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 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 2, 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 COPYING. If not, write to 22;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23;; Boston, MA 02110-1301, USA. */ 24;; 25;; The original PO technology requires these to be ordered by speed, 26;; so that assigner will pick the fastest. 27;; 28;; See file "rtl.def" for documentation on define_insn, match_*, et. al. 29;; 30;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register 31;; constraint letters. 32;; 33;; The special asm out single letter directives following a '%' are: 34;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of 35;; operands[1]. 36;; 'L' Print the opcode suffix for a 32-bit integer opcode. 37;; 'W' Print the opcode suffix for a 16-bit integer opcode. 38;; 'B' Print the opcode suffix for an 8-bit integer opcode. 39;; 'Q' Print the opcode suffix for a 64-bit float opcode. 40;; 'S' Print the opcode suffix for a 32-bit float opcode. 41;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode. 42;; 'J' Print the appropriate jump operand. 43;; 44;; 'b' Print the QImode name of the register for the indicated operand. 45;; %b0 would print %al if operands[0] is reg 0. 46;; 'w' Likewise, print the HImode name of the register. 47;; 'k' Likewise, print the SImode name of the register. 48;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh. 49;; 'y' Print "st(0)" instead of "st" as a register. 50 51;; UNSPEC usage: 52 53(define_constants 54 [; Relocation specifiers 55 (UNSPEC_GOT 0) 56 (UNSPEC_GOTOFF 1) 57 (UNSPEC_GOTPCREL 2) 58 (UNSPEC_GOTTPOFF 3) 59 (UNSPEC_TPOFF 4) 60 (UNSPEC_NTPOFF 5) 61 (UNSPEC_DTPOFF 6) 62 (UNSPEC_GOTNTPOFF 7) 63 (UNSPEC_INDNTPOFF 8) 64 65 ; Prologue support 66 (UNSPEC_STACK_ALLOC 11) 67 (UNSPEC_SET_GOT 12) 68 (UNSPEC_SSE_PROLOGUE_SAVE 13) 69 (UNSPEC_REG_SAVE 14) 70 (UNSPEC_DEF_CFA 15) 71 72 ; TLS support 73 (UNSPEC_TP 16) 74 (UNSPEC_TLS_GD 17) 75 (UNSPEC_TLS_LD_BASE 18) 76 77 ; Other random patterns 78 (UNSPEC_SCAS 20) 79 (UNSPEC_FNSTSW 21) 80 (UNSPEC_SAHF 22) 81 (UNSPEC_FSTCW 23) 82 (UNSPEC_ADD_CARRY 24) 83 (UNSPEC_FLDCW 25) 84 (UNSPEC_REP 26) 85 (UNSPEC_EH_RETURN 27) 86 87 ; For SSE/MMX support: 88 (UNSPEC_FIX_NOTRUNC 30) 89 (UNSPEC_MASKMOV 31) 90 (UNSPEC_MOVMSK 32) 91 (UNSPEC_MOVNT 33) 92 (UNSPEC_MOVU 34) 93 (UNSPEC_RCP 35) 94 (UNSPEC_RSQRT 36) 95 (UNSPEC_SFENCE 37) 96 (UNSPEC_NOP 38) ; prevents combiner cleverness 97 (UNSPEC_PFRCP 39) 98 (UNSPEC_PFRCPIT1 40) 99 (UNSPEC_PFRCPIT2 41) 100 (UNSPEC_PFRSQRT 42) 101 (UNSPEC_PFRSQIT1 43) 102 (UNSPEC_MFENCE 44) 103 (UNSPEC_LFENCE 45) 104 (UNSPEC_PSADBW 46) 105 (UNSPEC_LDQQU 47) 106 107 ; Generic math support 108 (UNSPEC_COPYSIGN 50) 109 (UNSPEC_IEEE_MIN 51) ; not commutative 110 (UNSPEC_IEEE_MAX 52) ; not commutative 111 112 ; x87 Floating point 113 (UNSPEC_SIN 60) 114 (UNSPEC_COS 61) 115 (UNSPEC_FPATAN 62) 116 (UNSPEC_FYL2X 63) 117 (UNSPEC_FYL2XP1 64) 118 (UNSPEC_FRNDINT 65) 119 (UNSPEC_FIST 66) 120 (UNSPEC_F2XM1 67) 121 122 ; x87 Rounding 123 (UNSPEC_FRNDINT_FLOOR 70) 124 (UNSPEC_FRNDINT_CEIL 71) 125 (UNSPEC_FRNDINT_TRUNC 72) 126 (UNSPEC_FRNDINT_MASK_PM 73) 127 (UNSPEC_FIST_FLOOR 74) 128 (UNSPEC_FIST_CEIL 75) 129 130 ; x87 Double output FP 131 (UNSPEC_SINCOS_COS 80) 132 (UNSPEC_SINCOS_SIN 81) 133 (UNSPEC_TAN_ONE 82) 134 (UNSPEC_TAN_TAN 83) 135 (UNSPEC_XTRACT_FRACT 84) 136 (UNSPEC_XTRACT_EXP 85) 137 (UNSPEC_FSCALE_FRACT 86) 138 (UNSPEC_FSCALE_EXP 87) 139 (UNSPEC_FPREM_F 88) 140 (UNSPEC_FPREM_U 89) 141 (UNSPEC_FPREM1_F 90) 142 (UNSPEC_FPREM1_U 91) 143 144 ; SSP patterns 145 (UNSPEC_SP_SET 100) 146 (UNSPEC_SP_TEST 101) 147 (UNSPEC_SP_TLS_SET 102) 148 (UNSPEC_SP_TLS_TEST 103) 149 ]) 150 151(define_constants 152 [(UNSPECV_BLOCKAGE 0) 153 (UNSPECV_STACK_PROBE 1) 154 (UNSPECV_EMMS 2) 155 (UNSPECV_LDMXCSR 3) 156 (UNSPECV_STMXCSR 4) 157 (UNSPECV_FEMMS 5) 158 (UNSPECV_CLFLUSH 6) 159 (UNSPECV_ALIGN 7) 160 (UNSPECV_MONITOR 8) 161 (UNSPECV_MWAIT 9) 162 (UNSPECV_CMPXCHG_1 10) 163 (UNSPECV_CMPXCHG_2 11) 164 (UNSPECV_XCHG 12) 165 (UNSPECV_LOCK 13) 166 ]) 167 168;; Registers by name. 169(define_constants 170 [(BP_REG 6) 171 (SP_REG 7) 172 (FLAGS_REG 17) 173 (FPSR_REG 18) 174 (DIRFLAG_REG 19) 175 ]) 176 177;; Insns whose names begin with "x86_" are emitted by gen_FOO calls 178;; from i386.c. 179 180;; In C guard expressions, put expressions which may be compile-time 181;; constants first. This allows for better optimization. For 182;; example, write "TARGET_64BIT && reload_completed", not 183;; "reload_completed && TARGET_64BIT". 184 185 186;; Processor type. This attribute must exactly match the processor_type 187;; enumeration in i386.h. 188(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona" 189 (const (symbol_ref "ix86_tune"))) 190 191;; A basic instruction type. Refinements due to arguments to be 192;; provided in other attributes. 193(define_attr "type" 194 "other,multi, 195 alu,alu1,negnot,imov,imovx,lea, 196 incdec,ishift,ishift1,rotate,rotate1,imul,idiv, 197 icmp,test,ibr,setcc,icmov, 198 push,pop,call,callv,leave, 199 str,cld, 200 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint, 201 sselog,sselog1,sseiadd,sseishft,sseimul, 202 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv, 203 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft" 204 (const_string "other")) 205 206;; Main data type used by the insn 207(define_attr "mode" 208 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF" 209 (const_string "unknown")) 210 211;; The CPU unit operations uses. 212(define_attr "unit" "integer,i387,sse,mmx,unknown" 213 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint") 214 (const_string "i387") 215 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul, 216 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv") 217 (const_string "sse") 218 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft") 219 (const_string "mmx") 220 (eq_attr "type" "other") 221 (const_string "unknown")] 222 (const_string "integer"))) 223 224;; The (bounding maximum) length of an instruction immediate. 225(define_attr "length_immediate" "" 226 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave") 227 (const_int 0) 228 (eq_attr "unit" "i387,sse,mmx") 229 (const_int 0) 230 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1, 231 imul,icmp,push,pop") 232 (symbol_ref "ix86_attr_length_immediate_default(insn,1)") 233 (eq_attr "type" "imov,test") 234 (symbol_ref "ix86_attr_length_immediate_default(insn,0)") 235 (eq_attr "type" "call") 236 (if_then_else (match_operand 0 "constant_call_address_operand" "") 237 (const_int 4) 238 (const_int 0)) 239 (eq_attr "type" "callv") 240 (if_then_else (match_operand 1 "constant_call_address_operand" "") 241 (const_int 4) 242 (const_int 0)) 243 ;; We don't know the size before shorten_branches. Expect 244 ;; the instruction to fit for better scheduling. 245 (eq_attr "type" "ibr") 246 (const_int 1) 247 ] 248 (symbol_ref "/* Update immediate_length and other attributes! */ 249 gcc_unreachable (),1"))) 250 251;; The (bounding maximum) length of an instruction address. 252(define_attr "length_address" "" 253 (cond [(eq_attr "type" "str,cld,other,multi,fxch") 254 (const_int 0) 255 (and (eq_attr "type" "call") 256 (match_operand 0 "constant_call_address_operand" "")) 257 (const_int 0) 258 (and (eq_attr "type" "callv") 259 (match_operand 1 "constant_call_address_operand" "")) 260 (const_int 0) 261 ] 262 (symbol_ref "ix86_attr_length_address_default (insn)"))) 263 264;; Set when length prefix is used. 265(define_attr "prefix_data16" "" 266 (if_then_else (ior (eq_attr "mode" "HI") 267 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF"))) 268 (const_int 1) 269 (const_int 0))) 270 271;; Set when string REP prefix is used. 272(define_attr "prefix_rep" "" 273 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF")) 274 (const_int 1) 275 (const_int 0))) 276 277;; Set when 0f opcode prefix is used. 278(define_attr "prefix_0f" "" 279 (if_then_else 280 (ior (eq_attr "type" "imovx,setcc,icmov") 281 (eq_attr "unit" "sse,mmx")) 282 (const_int 1) 283 (const_int 0))) 284 285;; Set when REX opcode prefix is used. 286(define_attr "prefix_rex" "" 287 (cond [(and (eq_attr "mode" "DI") 288 (eq_attr "type" "!push,pop,call,callv,leave,ibr")) 289 (const_int 1) 290 (and (eq_attr "mode" "QI") 291 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)") 292 (const_int 0))) 293 (const_int 1) 294 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)") 295 (const_int 0)) 296 (const_int 1) 297 ] 298 (const_int 0))) 299 300;; Set when modrm byte is used. 301(define_attr "modrm" "" 302 (cond [(eq_attr "type" "str,cld,leave") 303 (const_int 0) 304 (eq_attr "unit" "i387") 305 (const_int 0) 306 (and (eq_attr "type" "incdec") 307 (ior (match_operand:SI 1 "register_operand" "") 308 (match_operand:HI 1 "register_operand" ""))) 309 (const_int 0) 310 (and (eq_attr "type" "push") 311 (not (match_operand 1 "memory_operand" ""))) 312 (const_int 0) 313 (and (eq_attr "type" "pop") 314 (not (match_operand 0 "memory_operand" ""))) 315 (const_int 0) 316 (and (eq_attr "type" "imov") 317 (and (match_operand 0 "register_operand" "") 318 (match_operand 1 "immediate_operand" ""))) 319 (const_int 0) 320 (and (eq_attr "type" "call") 321 (match_operand 0 "constant_call_address_operand" "")) 322 (const_int 0) 323 (and (eq_attr "type" "callv") 324 (match_operand 1 "constant_call_address_operand" "")) 325 (const_int 0) 326 ] 327 (const_int 1))) 328 329;; The (bounding maximum) length of an instruction in bytes. 330;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences. 331;; Later we may want to split them and compute proper length as for 332;; other insns. 333(define_attr "length" "" 334 (cond [(eq_attr "type" "other,multi,fistp,frndint") 335 (const_int 16) 336 (eq_attr "type" "fcmp") 337 (const_int 4) 338 (eq_attr "unit" "i387") 339 (plus (const_int 2) 340 (plus (attr "prefix_data16") 341 (attr "length_address")))] 342 (plus (plus (attr "modrm") 343 (plus (attr "prefix_0f") 344 (plus (attr "prefix_rex") 345 (const_int 1)))) 346 (plus (attr "prefix_rep") 347 (plus (attr "prefix_data16") 348 (plus (attr "length_immediate") 349 (attr "length_address"))))))) 350 351;; The `memory' attribute is `none' if no memory is referenced, `load' or 352;; `store' if there is a simple memory reference therein, or `unknown' 353;; if the instruction is complex. 354 355(define_attr "memory" "none,load,store,both,unknown" 356 (cond [(eq_attr "type" "other,multi,str") 357 (const_string "unknown") 358 (eq_attr "type" "lea,fcmov,fpspc,cld") 359 (const_string "none") 360 (eq_attr "type" "fistp,leave") 361 (const_string "both") 362 (eq_attr "type" "frndint") 363 (const_string "load") 364 (eq_attr "type" "push") 365 (if_then_else (match_operand 1 "memory_operand" "") 366 (const_string "both") 367 (const_string "store")) 368 (eq_attr "type" "pop") 369 (if_then_else (match_operand 0 "memory_operand" "") 370 (const_string "both") 371 (const_string "load")) 372 (eq_attr "type" "setcc") 373 (if_then_else (match_operand 0 "memory_operand" "") 374 (const_string "store") 375 (const_string "none")) 376 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp") 377 (if_then_else (ior (match_operand 0 "memory_operand" "") 378 (match_operand 1 "memory_operand" "")) 379 (const_string "load") 380 (const_string "none")) 381 (eq_attr "type" "ibr") 382 (if_then_else (match_operand 0 "memory_operand" "") 383 (const_string "load") 384 (const_string "none")) 385 (eq_attr "type" "call") 386 (if_then_else (match_operand 0 "constant_call_address_operand" "") 387 (const_string "none") 388 (const_string "load")) 389 (eq_attr "type" "callv") 390 (if_then_else (match_operand 1 "constant_call_address_operand" "") 391 (const_string "none") 392 (const_string "load")) 393 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1") 394 (match_operand 1 "memory_operand" "")) 395 (const_string "both") 396 (and (match_operand 0 "memory_operand" "") 397 (match_operand 1 "memory_operand" "")) 398 (const_string "both") 399 (match_operand 0 "memory_operand" "") 400 (const_string "store") 401 (match_operand 1 "memory_operand" "") 402 (const_string "load") 403 (and (eq_attr "type" 404 "!alu1,negnot,ishift1, 405 imov,imovx,icmp,test, 406 fmov,fcmp,fsgn, 407 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1, 408 mmx,mmxmov,mmxcmp,mmxcvt") 409 (match_operand 2 "memory_operand" "")) 410 (const_string "load") 411 (and (eq_attr "type" "icmov") 412 (match_operand 3 "memory_operand" "")) 413 (const_string "load") 414 ] 415 (const_string "none"))) 416 417;; Indicates if an instruction has both an immediate and a displacement. 418 419(define_attr "imm_disp" "false,true,unknown" 420 (cond [(eq_attr "type" "other,multi") 421 (const_string "unknown") 422 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1") 423 (and (match_operand 0 "memory_displacement_operand" "") 424 (match_operand 1 "immediate_operand" ""))) 425 (const_string "true") 426 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv") 427 (and (match_operand 0 "memory_displacement_operand" "") 428 (match_operand 2 "immediate_operand" ""))) 429 (const_string "true") 430 ] 431 (const_string "false"))) 432 433;; Indicates if an FP operation has an integer source. 434 435(define_attr "fp_int_src" "false,true" 436 (const_string "false")) 437 438;; Defines rounding mode of an FP operation. 439 440(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any" 441 (const_string "any")) 442 443;; Describe a user's asm statement. 444(define_asm_attributes 445 [(set_attr "length" "128") 446 (set_attr "type" "multi")]) 447 448;; All x87 floating point modes 449(define_mode_macro X87MODEF [SF DF XF]) 450 451;; All integer modes handled by x87 fisttp operator. 452(define_mode_macro X87MODEI [HI SI DI]) 453 454;; All integer modes handled by integer x87 operators. 455(define_mode_macro X87MODEI12 [HI SI]) 456 457;; All SSE floating point modes 458(define_mode_macro SSEMODEF [SF DF]) 459 460;; All integer modes handled by SSE cvtts?2si* operators. 461(define_mode_macro SSEMODEI24 [SI DI]) 462 463 464;; Scheduling descriptions 465 466(include "pentium.md") 467(include "ppro.md") 468(include "k6.md") 469(include "athlon.md") 470 471 472;; Operand and operator predicates 473 474(include "predicates.md") 475 476 477;; Compare instructions. 478 479;; All compare insns have expanders that save the operands away without 480;; actually generating RTL. The bCOND or sCOND (emitted immediately 481;; after the cmp) will actually emit the cmpM. 482 483(define_expand "cmpti" 484 [(set (reg:CC FLAGS_REG) 485 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "") 486 (match_operand:TI 1 "x86_64_general_operand" "")))] 487 "TARGET_64BIT" 488{ 489 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 490 operands[0] = force_reg (TImode, operands[0]); 491 ix86_compare_op0 = operands[0]; 492 ix86_compare_op1 = operands[1]; 493 DONE; 494}) 495 496(define_expand "cmpdi" 497 [(set (reg:CC FLAGS_REG) 498 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "") 499 (match_operand:DI 1 "x86_64_general_operand" "")))] 500 "" 501{ 502 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 503 operands[0] = force_reg (DImode, operands[0]); 504 ix86_compare_op0 = operands[0]; 505 ix86_compare_op1 = operands[1]; 506 DONE; 507}) 508 509(define_expand "cmpsi" 510 [(set (reg:CC FLAGS_REG) 511 (compare:CC (match_operand:SI 0 "cmpsi_operand" "") 512 (match_operand:SI 1 "general_operand" "")))] 513 "" 514{ 515 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 516 operands[0] = force_reg (SImode, operands[0]); 517 ix86_compare_op0 = operands[0]; 518 ix86_compare_op1 = operands[1]; 519 DONE; 520}) 521 522(define_expand "cmphi" 523 [(set (reg:CC FLAGS_REG) 524 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "") 525 (match_operand:HI 1 "general_operand" "")))] 526 "" 527{ 528 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 529 operands[0] = force_reg (HImode, operands[0]); 530 ix86_compare_op0 = operands[0]; 531 ix86_compare_op1 = operands[1]; 532 DONE; 533}) 534 535(define_expand "cmpqi" 536 [(set (reg:CC FLAGS_REG) 537 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "") 538 (match_operand:QI 1 "general_operand" "")))] 539 "TARGET_QIMODE_MATH" 540{ 541 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 542 operands[0] = force_reg (QImode, operands[0]); 543 ix86_compare_op0 = operands[0]; 544 ix86_compare_op1 = operands[1]; 545 DONE; 546}) 547 548(define_insn "cmpdi_ccno_1_rex64" 549 [(set (reg FLAGS_REG) 550 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr") 551 (match_operand:DI 1 "const0_operand" "n,n")))] 552 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 553 "@ 554 test{q}\t{%0, %0|%0, %0} 555 cmp{q}\t{%1, %0|%0, %1}" 556 [(set_attr "type" "test,icmp") 557 (set_attr "length_immediate" "0,1") 558 (set_attr "mode" "DI")]) 559 560(define_insn "*cmpdi_minus_1_rex64" 561 [(set (reg FLAGS_REG) 562 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r") 563 (match_operand:DI 1 "x86_64_general_operand" "re,mr")) 564 (const_int 0)))] 565 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)" 566 "cmp{q}\t{%1, %0|%0, %1}" 567 [(set_attr "type" "icmp") 568 (set_attr "mode" "DI")]) 569 570(define_expand "cmpdi_1_rex64" 571 [(set (reg:CC FLAGS_REG) 572 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "") 573 (match_operand:DI 1 "general_operand" "")))] 574 "TARGET_64BIT" 575 "") 576 577(define_insn "cmpdi_1_insn_rex64" 578 [(set (reg FLAGS_REG) 579 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r") 580 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))] 581 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 582 "cmp{q}\t{%1, %0|%0, %1}" 583 [(set_attr "type" "icmp") 584 (set_attr "mode" "DI")]) 585 586 587(define_insn "*cmpsi_ccno_1" 588 [(set (reg FLAGS_REG) 589 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr") 590 (match_operand:SI 1 "const0_operand" "n,n")))] 591 "ix86_match_ccmode (insn, CCNOmode)" 592 "@ 593 test{l}\t{%0, %0|%0, %0} 594 cmp{l}\t{%1, %0|%0, %1}" 595 [(set_attr "type" "test,icmp") 596 (set_attr "length_immediate" "0,1") 597 (set_attr "mode" "SI")]) 598 599(define_insn "*cmpsi_minus_1" 600 [(set (reg FLAGS_REG) 601 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r") 602 (match_operand:SI 1 "general_operand" "ri,mr")) 603 (const_int 0)))] 604 "ix86_match_ccmode (insn, CCGOCmode)" 605 "cmp{l}\t{%1, %0|%0, %1}" 606 [(set_attr "type" "icmp") 607 (set_attr "mode" "SI")]) 608 609(define_expand "cmpsi_1" 610 [(set (reg:CC FLAGS_REG) 611 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r") 612 (match_operand:SI 1 "general_operand" "ri,mr")))] 613 "" 614 "") 615 616(define_insn "*cmpsi_1_insn" 617 [(set (reg FLAGS_REG) 618 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r") 619 (match_operand:SI 1 "general_operand" "ri,mr")))] 620 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 621 && ix86_match_ccmode (insn, CCmode)" 622 "cmp{l}\t{%1, %0|%0, %1}" 623 [(set_attr "type" "icmp") 624 (set_attr "mode" "SI")]) 625 626(define_insn "*cmphi_ccno_1" 627 [(set (reg FLAGS_REG) 628 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr") 629 (match_operand:HI 1 "const0_operand" "n,n")))] 630 "ix86_match_ccmode (insn, CCNOmode)" 631 "@ 632 test{w}\t{%0, %0|%0, %0} 633 cmp{w}\t{%1, %0|%0, %1}" 634 [(set_attr "type" "test,icmp") 635 (set_attr "length_immediate" "0,1") 636 (set_attr "mode" "HI")]) 637 638(define_insn "*cmphi_minus_1" 639 [(set (reg FLAGS_REG) 640 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r") 641 (match_operand:HI 1 "general_operand" "ri,mr")) 642 (const_int 0)))] 643 "ix86_match_ccmode (insn, CCGOCmode)" 644 "cmp{w}\t{%1, %0|%0, %1}" 645 [(set_attr "type" "icmp") 646 (set_attr "mode" "HI")]) 647 648(define_insn "*cmphi_1" 649 [(set (reg FLAGS_REG) 650 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r") 651 (match_operand:HI 1 "general_operand" "ri,mr")))] 652 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 653 && ix86_match_ccmode (insn, CCmode)" 654 "cmp{w}\t{%1, %0|%0, %1}" 655 [(set_attr "type" "icmp") 656 (set_attr "mode" "HI")]) 657 658(define_insn "*cmpqi_ccno_1" 659 [(set (reg FLAGS_REG) 660 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq") 661 (match_operand:QI 1 "const0_operand" "n,n")))] 662 "ix86_match_ccmode (insn, CCNOmode)" 663 "@ 664 test{b}\t{%0, %0|%0, %0} 665 cmp{b}\t{$0, %0|%0, 0}" 666 [(set_attr "type" "test,icmp") 667 (set_attr "length_immediate" "0,1") 668 (set_attr "mode" "QI")]) 669 670(define_insn "*cmpqi_1" 671 [(set (reg FLAGS_REG) 672 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q") 673 (match_operand:QI 1 "general_operand" "qi,mq")))] 674 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 675 && ix86_match_ccmode (insn, CCmode)" 676 "cmp{b}\t{%1, %0|%0, %1}" 677 [(set_attr "type" "icmp") 678 (set_attr "mode" "QI")]) 679 680(define_insn "*cmpqi_minus_1" 681 [(set (reg FLAGS_REG) 682 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q") 683 (match_operand:QI 1 "general_operand" "qi,mq")) 684 (const_int 0)))] 685 "ix86_match_ccmode (insn, CCGOCmode)" 686 "cmp{b}\t{%1, %0|%0, %1}" 687 [(set_attr "type" "icmp") 688 (set_attr "mode" "QI")]) 689 690(define_insn "*cmpqi_ext_1" 691 [(set (reg FLAGS_REG) 692 (compare 693 (match_operand:QI 0 "general_operand" "Qm") 694 (subreg:QI 695 (zero_extract:SI 696 (match_operand 1 "ext_register_operand" "Q") 697 (const_int 8) 698 (const_int 8)) 0)))] 699 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 700 "cmp{b}\t{%h1, %0|%0, %h1}" 701 [(set_attr "type" "icmp") 702 (set_attr "mode" "QI")]) 703 704(define_insn "*cmpqi_ext_1_rex64" 705 [(set (reg FLAGS_REG) 706 (compare 707 (match_operand:QI 0 "register_operand" "Q") 708 (subreg:QI 709 (zero_extract:SI 710 (match_operand 1 "ext_register_operand" "Q") 711 (const_int 8) 712 (const_int 8)) 0)))] 713 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 714 "cmp{b}\t{%h1, %0|%0, %h1}" 715 [(set_attr "type" "icmp") 716 (set_attr "mode" "QI")]) 717 718(define_insn "*cmpqi_ext_2" 719 [(set (reg FLAGS_REG) 720 (compare 721 (subreg:QI 722 (zero_extract:SI 723 (match_operand 0 "ext_register_operand" "Q") 724 (const_int 8) 725 (const_int 8)) 0) 726 (match_operand:QI 1 "const0_operand" "n")))] 727 "ix86_match_ccmode (insn, CCNOmode)" 728 "test{b}\t%h0, %h0" 729 [(set_attr "type" "test") 730 (set_attr "length_immediate" "0") 731 (set_attr "mode" "QI")]) 732 733(define_expand "cmpqi_ext_3" 734 [(set (reg:CC FLAGS_REG) 735 (compare:CC 736 (subreg:QI 737 (zero_extract:SI 738 (match_operand 0 "ext_register_operand" "") 739 (const_int 8) 740 (const_int 8)) 0) 741 (match_operand:QI 1 "general_operand" "")))] 742 "" 743 "") 744 745(define_insn "cmpqi_ext_3_insn" 746 [(set (reg FLAGS_REG) 747 (compare 748 (subreg:QI 749 (zero_extract:SI 750 (match_operand 0 "ext_register_operand" "Q") 751 (const_int 8) 752 (const_int 8)) 0) 753 (match_operand:QI 1 "general_operand" "Qmn")))] 754 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 755 "cmp{b}\t{%1, %h0|%h0, %1}" 756 [(set_attr "type" "icmp") 757 (set_attr "mode" "QI")]) 758 759(define_insn "cmpqi_ext_3_insn_rex64" 760 [(set (reg FLAGS_REG) 761 (compare 762 (subreg:QI 763 (zero_extract:SI 764 (match_operand 0 "ext_register_operand" "Q") 765 (const_int 8) 766 (const_int 8)) 0) 767 (match_operand:QI 1 "nonmemory_operand" "Qn")))] 768 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 769 "cmp{b}\t{%1, %h0|%h0, %1}" 770 [(set_attr "type" "icmp") 771 (set_attr "mode" "QI")]) 772 773(define_insn "*cmpqi_ext_4" 774 [(set (reg FLAGS_REG) 775 (compare 776 (subreg:QI 777 (zero_extract:SI 778 (match_operand 0 "ext_register_operand" "Q") 779 (const_int 8) 780 (const_int 8)) 0) 781 (subreg:QI 782 (zero_extract:SI 783 (match_operand 1 "ext_register_operand" "Q") 784 (const_int 8) 785 (const_int 8)) 0)))] 786 "ix86_match_ccmode (insn, CCmode)" 787 "cmp{b}\t{%h1, %h0|%h0, %h1}" 788 [(set_attr "type" "icmp") 789 (set_attr "mode" "QI")]) 790 791;; These implement float point compares. 792;; %%% See if we can get away with VOIDmode operands on the actual insns, 793;; which would allow mix and match FP modes on the compares. Which is what 794;; the old patterns did, but with many more of them. 795 796(define_expand "cmpxf" 797 [(set (reg:CC FLAGS_REG) 798 (compare:CC (match_operand:XF 0 "nonmemory_operand" "") 799 (match_operand:XF 1 "nonmemory_operand" "")))] 800 "TARGET_80387" 801{ 802 ix86_compare_op0 = operands[0]; 803 ix86_compare_op1 = operands[1]; 804 DONE; 805}) 806 807(define_expand "cmpdf" 808 [(set (reg:CC FLAGS_REG) 809 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "") 810 (match_operand:DF 1 "cmp_fp_expander_operand" "")))] 811 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 812{ 813 ix86_compare_op0 = operands[0]; 814 ix86_compare_op1 = operands[1]; 815 DONE; 816}) 817 818(define_expand "cmpsf" 819 [(set (reg:CC FLAGS_REG) 820 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "") 821 (match_operand:SF 1 "cmp_fp_expander_operand" "")))] 822 "TARGET_80387 || TARGET_SSE_MATH" 823{ 824 ix86_compare_op0 = operands[0]; 825 ix86_compare_op1 = operands[1]; 826 DONE; 827}) 828 829;; FP compares, step 1: 830;; Set the FP condition codes. 831;; 832;; CCFPmode compare with exceptions 833;; CCFPUmode compare with no exceptions 834 835;; We may not use "#" to split and emit these, since the REG_DEAD notes 836;; used to manage the reg stack popping would not be preserved. 837 838(define_insn "*cmpfp_0" 839 [(set (match_operand:HI 0 "register_operand" "=a") 840 (unspec:HI 841 [(compare:CCFP 842 (match_operand 1 "register_operand" "f") 843 (match_operand 2 "const0_operand" "X"))] 844 UNSPEC_FNSTSW))] 845 "TARGET_80387 846 && FLOAT_MODE_P (GET_MODE (operands[1])) 847 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 848 "* return output_fp_compare (insn, operands, 0, 0);" 849 [(set_attr "type" "multi") 850 (set_attr "unit" "i387") 851 (set (attr "mode") 852 (cond [(match_operand:SF 1 "" "") 853 (const_string "SF") 854 (match_operand:DF 1 "" "") 855 (const_string "DF") 856 ] 857 (const_string "XF")))]) 858 859(define_insn "*cmpfp_sf" 860 [(set (match_operand:HI 0 "register_operand" "=a") 861 (unspec:HI 862 [(compare:CCFP 863 (match_operand:SF 1 "register_operand" "f") 864 (match_operand:SF 2 "nonimmediate_operand" "fm"))] 865 UNSPEC_FNSTSW))] 866 "TARGET_80387" 867 "* return output_fp_compare (insn, operands, 0, 0);" 868 [(set_attr "type" "multi") 869 (set_attr "unit" "i387") 870 (set_attr "mode" "SF")]) 871 872(define_insn "*cmpfp_df" 873 [(set (match_operand:HI 0 "register_operand" "=a") 874 (unspec:HI 875 [(compare:CCFP 876 (match_operand:DF 1 "register_operand" "f") 877 (match_operand:DF 2 "nonimmediate_operand" "fm"))] 878 UNSPEC_FNSTSW))] 879 "TARGET_80387" 880 "* return output_fp_compare (insn, operands, 0, 0);" 881 [(set_attr "type" "multi") 882 (set_attr "unit" "i387") 883 (set_attr "mode" "DF")]) 884 885(define_insn "*cmpfp_xf" 886 [(set (match_operand:HI 0 "register_operand" "=a") 887 (unspec:HI 888 [(compare:CCFP 889 (match_operand:XF 1 "register_operand" "f") 890 (match_operand:XF 2 "register_operand" "f"))] 891 UNSPEC_FNSTSW))] 892 "TARGET_80387" 893 "* return output_fp_compare (insn, operands, 0, 0);" 894 [(set_attr "type" "multi") 895 (set_attr "unit" "i387") 896 (set_attr "mode" "XF")]) 897 898(define_insn "*cmpfp_u" 899 [(set (match_operand:HI 0 "register_operand" "=a") 900 (unspec:HI 901 [(compare:CCFPU 902 (match_operand 1 "register_operand" "f") 903 (match_operand 2 "register_operand" "f"))] 904 UNSPEC_FNSTSW))] 905 "TARGET_80387 906 && FLOAT_MODE_P (GET_MODE (operands[1])) 907 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 908 "* return output_fp_compare (insn, operands, 0, 1);" 909 [(set_attr "type" "multi") 910 (set_attr "unit" "i387") 911 (set (attr "mode") 912 (cond [(match_operand:SF 1 "" "") 913 (const_string "SF") 914 (match_operand:DF 1 "" "") 915 (const_string "DF") 916 ] 917 (const_string "XF")))]) 918 919(define_insn "*cmpfp_<mode>" 920 [(set (match_operand:HI 0 "register_operand" "=a") 921 (unspec:HI 922 [(compare:CCFP 923 (match_operand 1 "register_operand" "f") 924 (match_operator 3 "float_operator" 925 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))] 926 UNSPEC_FNSTSW))] 927 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 928 && FLOAT_MODE_P (GET_MODE (operands[1])) 929 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))" 930 "* return output_fp_compare (insn, operands, 0, 0);" 931 [(set_attr "type" "multi") 932 (set_attr "unit" "i387") 933 (set_attr "fp_int_src" "true") 934 (set_attr "mode" "<MODE>")]) 935 936;; FP compares, step 2 937;; Move the fpsw to ax. 938 939(define_insn "x86_fnstsw_1" 940 [(set (match_operand:HI 0 "register_operand" "=a") 941 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))] 942 "TARGET_80387" 943 "fnstsw\t%0" 944 [(set_attr "length" "2") 945 (set_attr "mode" "SI") 946 (set_attr "unit" "i387")]) 947 948;; FP compares, step 3 949;; Get ax into flags, general case. 950 951(define_insn "x86_sahf_1" 952 [(set (reg:CC FLAGS_REG) 953 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))] 954 "!TARGET_64BIT" 955 "sahf" 956 [(set_attr "length" "1") 957 (set_attr "athlon_decode" "vector") 958 (set_attr "mode" "SI")]) 959 960;; Pentium Pro can do steps 1 through 3 in one go. 961 962(define_insn "*cmpfp_i_mixed" 963 [(set (reg:CCFP FLAGS_REG) 964 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f") 965 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))] 966 "TARGET_MIX_SSE_I387 967 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 968 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 969 "* return output_fp_compare (insn, operands, 1, 0);" 970 [(set_attr "type" "fcmp,ssecomi") 971 (set (attr "mode") 972 (if_then_else (match_operand:SF 1 "" "") 973 (const_string "SF") 974 (const_string "DF"))) 975 (set_attr "athlon_decode" "vector")]) 976 977(define_insn "*cmpfp_i_sse" 978 [(set (reg:CCFP FLAGS_REG) 979 (compare:CCFP (match_operand 0 "register_operand" "x") 980 (match_operand 1 "nonimmediate_operand" "xm")))] 981 "TARGET_SSE_MATH 982 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 983 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 984 "* return output_fp_compare (insn, operands, 1, 0);" 985 [(set_attr "type" "ssecomi") 986 (set (attr "mode") 987 (if_then_else (match_operand:SF 1 "" "") 988 (const_string "SF") 989 (const_string "DF"))) 990 (set_attr "athlon_decode" "vector")]) 991 992(define_insn "*cmpfp_i_i387" 993 [(set (reg:CCFP FLAGS_REG) 994 (compare:CCFP (match_operand 0 "register_operand" "f") 995 (match_operand 1 "register_operand" "f")))] 996 "TARGET_80387 && TARGET_CMOVE 997 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))) 998 && FLOAT_MODE_P (GET_MODE (operands[0])) 999 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1000 "* return output_fp_compare (insn, operands, 1, 0);" 1001 [(set_attr "type" "fcmp") 1002 (set (attr "mode") 1003 (cond [(match_operand:SF 1 "" "") 1004 (const_string "SF") 1005 (match_operand:DF 1 "" "") 1006 (const_string "DF") 1007 ] 1008 (const_string "XF"))) 1009 (set_attr "athlon_decode" "vector")]) 1010 1011(define_insn "*cmpfp_iu_mixed" 1012 [(set (reg:CCFPU FLAGS_REG) 1013 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f") 1014 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))] 1015 "TARGET_MIX_SSE_I387 1016 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1017 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1018 "* return output_fp_compare (insn, operands, 1, 1);" 1019 [(set_attr "type" "fcmp,ssecomi") 1020 (set (attr "mode") 1021 (if_then_else (match_operand:SF 1 "" "") 1022 (const_string "SF") 1023 (const_string "DF"))) 1024 (set_attr "athlon_decode" "vector")]) 1025 1026(define_insn "*cmpfp_iu_sse" 1027 [(set (reg:CCFPU FLAGS_REG) 1028 (compare:CCFPU (match_operand 0 "register_operand" "x") 1029 (match_operand 1 "nonimmediate_operand" "xm")))] 1030 "TARGET_SSE_MATH 1031 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1032 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1033 "* return output_fp_compare (insn, operands, 1, 1);" 1034 [(set_attr "type" "ssecomi") 1035 (set (attr "mode") 1036 (if_then_else (match_operand:SF 1 "" "") 1037 (const_string "SF") 1038 (const_string "DF"))) 1039 (set_attr "athlon_decode" "vector")]) 1040 1041(define_insn "*cmpfp_iu_387" 1042 [(set (reg:CCFPU FLAGS_REG) 1043 (compare:CCFPU (match_operand 0 "register_operand" "f") 1044 (match_operand 1 "register_operand" "f")))] 1045 "TARGET_80387 && TARGET_CMOVE 1046 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))) 1047 && FLOAT_MODE_P (GET_MODE (operands[0])) 1048 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1049 "* return output_fp_compare (insn, operands, 1, 1);" 1050 [(set_attr "type" "fcmp") 1051 (set (attr "mode") 1052 (cond [(match_operand:SF 1 "" "") 1053 (const_string "SF") 1054 (match_operand:DF 1 "" "") 1055 (const_string "DF") 1056 ] 1057 (const_string "XF"))) 1058 (set_attr "athlon_decode" "vector")]) 1059 1060;; Move instructions. 1061 1062;; General case of fullword move. 1063 1064(define_expand "movsi" 1065 [(set (match_operand:SI 0 "nonimmediate_operand" "") 1066 (match_operand:SI 1 "general_operand" ""))] 1067 "" 1068 "ix86_expand_move (SImode, operands); DONE;") 1069 1070;; Push/pop instructions. They are separate since autoinc/dec is not a 1071;; general_operand. 1072;; 1073;; %%% We don't use a post-inc memory reference because x86 is not a 1074;; general AUTO_INC_DEC host, which impacts how it is treated in flow. 1075;; Changing this impacts compiler performance on other non-AUTO_INC_DEC 1076;; targets without our curiosities, and it is just as easy to represent 1077;; this differently. 1078 1079(define_insn "*pushsi2" 1080 [(set (match_operand:SI 0 "push_operand" "=<") 1081 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))] 1082 "!TARGET_64BIT" 1083 "push{l}\t%1" 1084 [(set_attr "type" "push") 1085 (set_attr "mode" "SI")]) 1086 1087;; For 64BIT abi we always round up to 8 bytes. 1088(define_insn "*pushsi2_rex64" 1089 [(set (match_operand:SI 0 "push_operand" "=X") 1090 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))] 1091 "TARGET_64BIT" 1092 "push{q}\t%q1" 1093 [(set_attr "type" "push") 1094 (set_attr "mode" "SI")]) 1095 1096(define_insn "*pushsi2_prologue" 1097 [(set (match_operand:SI 0 "push_operand" "=<") 1098 (match_operand:SI 1 "general_no_elim_operand" "ri*m")) 1099 (clobber (mem:BLK (scratch)))] 1100 "!TARGET_64BIT" 1101 "push{l}\t%1" 1102 [(set_attr "type" "push") 1103 (set_attr "mode" "SI")]) 1104 1105(define_insn "*popsi1_epilogue" 1106 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m") 1107 (mem:SI (reg:SI SP_REG))) 1108 (set (reg:SI SP_REG) 1109 (plus:SI (reg:SI SP_REG) (const_int 4))) 1110 (clobber (mem:BLK (scratch)))] 1111 "!TARGET_64BIT" 1112 "pop{l}\t%0" 1113 [(set_attr "type" "pop") 1114 (set_attr "mode" "SI")]) 1115 1116(define_insn "popsi1" 1117 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m") 1118 (mem:SI (reg:SI SP_REG))) 1119 (set (reg:SI SP_REG) 1120 (plus:SI (reg:SI SP_REG) (const_int 4)))] 1121 "!TARGET_64BIT" 1122 "pop{l}\t%0" 1123 [(set_attr "type" "pop") 1124 (set_attr "mode" "SI")]) 1125 1126(define_insn "*movsi_xor" 1127 [(set (match_operand:SI 0 "register_operand" "=r") 1128 (match_operand:SI 1 "const0_operand" "i")) 1129 (clobber (reg:CC FLAGS_REG))] 1130 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)" 1131 "xor{l}\t{%0, %0|%0, %0}" 1132 [(set_attr "type" "alu1") 1133 (set_attr "mode" "SI") 1134 (set_attr "length_immediate" "0")]) 1135 1136(define_insn "*movsi_or" 1137 [(set (match_operand:SI 0 "register_operand" "=r") 1138 (match_operand:SI 1 "immediate_operand" "i")) 1139 (clobber (reg:CC FLAGS_REG))] 1140 "reload_completed 1141 && operands[1] == constm1_rtx 1142 && (TARGET_PENTIUM || optimize_size)" 1143{ 1144 operands[1] = constm1_rtx; 1145 return "or{l}\t{%1, %0|%0, %1}"; 1146} 1147 [(set_attr "type" "alu1") 1148 (set_attr "mode" "SI") 1149 (set_attr "length_immediate" "1")]) 1150 1151(define_insn "*movsi_1" 1152 [(set (match_operand:SI 0 "nonimmediate_operand" 1153 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x") 1154 (match_operand:SI 1 "general_operand" 1155 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))] 1156 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 1157{ 1158 switch (get_attr_type (insn)) 1159 { 1160 case TYPE_SSELOG1: 1161 if (get_attr_mode (insn) == MODE_TI) 1162 return "pxor\t%0, %0"; 1163 return "xorps\t%0, %0"; 1164 1165 case TYPE_SSEMOV: 1166 switch (get_attr_mode (insn)) 1167 { 1168 case MODE_TI: 1169 return "movdqa\t{%1, %0|%0, %1}"; 1170 case MODE_V4SF: 1171 return "movaps\t{%1, %0|%0, %1}"; 1172 case MODE_SI: 1173 return "movd\t{%1, %0|%0, %1}"; 1174 case MODE_SF: 1175 return "movss\t{%1, %0|%0, %1}"; 1176 default: 1177 gcc_unreachable (); 1178 } 1179 1180 case TYPE_MMXADD: 1181 return "pxor\t%0, %0"; 1182 1183 case TYPE_MMXMOV: 1184 if (get_attr_mode (insn) == MODE_DI) 1185 return "movq\t{%1, %0|%0, %1}"; 1186 return "movd\t{%1, %0|%0, %1}"; 1187 1188 case TYPE_LEA: 1189 return "lea{l}\t{%1, %0|%0, %1}"; 1190 1191 default: 1192 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 1193 return "mov{l}\t{%1, %0|%0, %1}"; 1194 } 1195} 1196 [(set (attr "type") 1197 (cond [(eq_attr "alternative" "2") 1198 (const_string "mmxadd") 1199 (eq_attr "alternative" "3,4,5") 1200 (const_string "mmxmov") 1201 (eq_attr "alternative" "6") 1202 (const_string "sselog1") 1203 (eq_attr "alternative" "7,8,9,10,11") 1204 (const_string "ssemov") 1205 (match_operand:DI 1 "pic_32bit_operand" "") 1206 (const_string "lea") 1207 ] 1208 (const_string "imov"))) 1209 (set (attr "mode") 1210 (cond [(eq_attr "alternative" "2,3") 1211 (const_string "DI") 1212 (eq_attr "alternative" "6,7") 1213 (if_then_else 1214 (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 1215 (const_string "V4SF") 1216 (const_string "TI")) 1217 (and (eq_attr "alternative" "8,9,10,11") 1218 (eq (symbol_ref "TARGET_SSE2") (const_int 0))) 1219 (const_string "SF") 1220 ] 1221 (const_string "SI")))]) 1222 1223;; Stores and loads of ax to arbitrary constant address. 1224;; We fake an second form of instruction to force reload to load address 1225;; into register when rax is not available 1226(define_insn "*movabssi_1_rex64" 1227 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 1228 (match_operand:SI 1 "nonmemory_operand" "a,er"))] 1229 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 1230 "@ 1231 movabs{l}\t{%1, %P0|%P0, %1} 1232 mov{l}\t{%1, %a0|%a0, %1}" 1233 [(set_attr "type" "imov") 1234 (set_attr "modrm" "0,*") 1235 (set_attr "length_address" "8,0") 1236 (set_attr "length_immediate" "0,*") 1237 (set_attr "memory" "store") 1238 (set_attr "mode" "SI")]) 1239 1240(define_insn "*movabssi_2_rex64" 1241 [(set (match_operand:SI 0 "register_operand" "=a,r") 1242 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 1243 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 1244 "@ 1245 movabs{l}\t{%P1, %0|%0, %P1} 1246 mov{l}\t{%a1, %0|%0, %a1}" 1247 [(set_attr "type" "imov") 1248 (set_attr "modrm" "0,*") 1249 (set_attr "length_address" "8,0") 1250 (set_attr "length_immediate" "0") 1251 (set_attr "memory" "load") 1252 (set_attr "mode" "SI")]) 1253 1254(define_insn "*swapsi" 1255 [(set (match_operand:SI 0 "register_operand" "+r") 1256 (match_operand:SI 1 "register_operand" "+r")) 1257 (set (match_dup 1) 1258 (match_dup 0))] 1259 "" 1260 "xchg{l}\t%1, %0" 1261 [(set_attr "type" "imov") 1262 (set_attr "mode" "SI") 1263 (set_attr "pent_pair" "np") 1264 (set_attr "athlon_decode" "vector")]) 1265 1266(define_expand "movhi" 1267 [(set (match_operand:HI 0 "nonimmediate_operand" "") 1268 (match_operand:HI 1 "general_operand" ""))] 1269 "" 1270 "ix86_expand_move (HImode, operands); DONE;") 1271 1272(define_insn "*pushhi2" 1273 [(set (match_operand:HI 0 "push_operand" "=X") 1274 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))] 1275 "!TARGET_64BIT" 1276 "push{l}\t%k1" 1277 [(set_attr "type" "push") 1278 (set_attr "mode" "SI")]) 1279 1280;; For 64BIT abi we always round up to 8 bytes. 1281(define_insn "*pushhi2_rex64" 1282 [(set (match_operand:HI 0 "push_operand" "=X") 1283 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))] 1284 "TARGET_64BIT" 1285 "push{q}\t%q1" 1286 [(set_attr "type" "push") 1287 (set_attr "mode" "DI")]) 1288 1289(define_insn "*movhi_1" 1290 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") 1291 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))] 1292 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 1293{ 1294 switch (get_attr_type (insn)) 1295 { 1296 case TYPE_IMOVX: 1297 /* movzwl is faster than movw on p2 due to partial word stalls, 1298 though not as fast as an aligned movl. */ 1299 return "movz{wl|x}\t{%1, %k0|%k0, %1}"; 1300 default: 1301 if (get_attr_mode (insn) == MODE_SI) 1302 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 1303 else 1304 return "mov{w}\t{%1, %0|%0, %1}"; 1305 } 1306} 1307 [(set (attr "type") 1308 (cond [(ne (symbol_ref "optimize_size") (const_int 0)) 1309 (const_string "imov") 1310 (and (eq_attr "alternative" "0") 1311 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1312 (const_int 0)) 1313 (eq (symbol_ref "TARGET_HIMODE_MATH") 1314 (const_int 0)))) 1315 (const_string "imov") 1316 (and (eq_attr "alternative" "1,2") 1317 (match_operand:HI 1 "aligned_operand" "")) 1318 (const_string "imov") 1319 (and (ne (symbol_ref "TARGET_MOVX") 1320 (const_int 0)) 1321 (eq_attr "alternative" "0,2")) 1322 (const_string "imovx") 1323 ] 1324 (const_string "imov"))) 1325 (set (attr "mode") 1326 (cond [(eq_attr "type" "imovx") 1327 (const_string "SI") 1328 (and (eq_attr "alternative" "1,2") 1329 (match_operand:HI 1 "aligned_operand" "")) 1330 (const_string "SI") 1331 (and (eq_attr "alternative" "0") 1332 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1333 (const_int 0)) 1334 (eq (symbol_ref "TARGET_HIMODE_MATH") 1335 (const_int 0)))) 1336 (const_string "SI") 1337 ] 1338 (const_string "HI")))]) 1339 1340;; Stores and loads of ax to arbitrary constant address. 1341;; We fake an second form of instruction to force reload to load address 1342;; into register when rax is not available 1343(define_insn "*movabshi_1_rex64" 1344 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 1345 (match_operand:HI 1 "nonmemory_operand" "a,er"))] 1346 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 1347 "@ 1348 movabs{w}\t{%1, %P0|%P0, %1} 1349 mov{w}\t{%1, %a0|%a0, %1}" 1350 [(set_attr "type" "imov") 1351 (set_attr "modrm" "0,*") 1352 (set_attr "length_address" "8,0") 1353 (set_attr "length_immediate" "0,*") 1354 (set_attr "memory" "store") 1355 (set_attr "mode" "HI")]) 1356 1357(define_insn "*movabshi_2_rex64" 1358 [(set (match_operand:HI 0 "register_operand" "=a,r") 1359 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 1360 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 1361 "@ 1362 movabs{w}\t{%P1, %0|%0, %P1} 1363 mov{w}\t{%a1, %0|%0, %a1}" 1364 [(set_attr "type" "imov") 1365 (set_attr "modrm" "0,*") 1366 (set_attr "length_address" "8,0") 1367 (set_attr "length_immediate" "0") 1368 (set_attr "memory" "load") 1369 (set_attr "mode" "HI")]) 1370 1371(define_insn "*swaphi_1" 1372 [(set (match_operand:HI 0 "register_operand" "+r") 1373 (match_operand:HI 1 "register_operand" "+r")) 1374 (set (match_dup 1) 1375 (match_dup 0))] 1376 "!TARGET_PARTIAL_REG_STALL || optimize_size" 1377 "xchg{l}\t%k1, %k0" 1378 [(set_attr "type" "imov") 1379 (set_attr "mode" "SI") 1380 (set_attr "pent_pair" "np") 1381 (set_attr "athlon_decode" "vector")]) 1382 1383(define_insn "*swaphi_2" 1384 [(set (match_operand:HI 0 "register_operand" "+r") 1385 (match_operand:HI 1 "register_operand" "+r")) 1386 (set (match_dup 1) 1387 (match_dup 0))] 1388 "TARGET_PARTIAL_REG_STALL" 1389 "xchg{w}\t%1, %0" 1390 [(set_attr "type" "imov") 1391 (set_attr "mode" "HI") 1392 (set_attr "pent_pair" "np") 1393 (set_attr "athlon_decode" "vector")]) 1394 1395(define_expand "movstricthi" 1396 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "")) 1397 (match_operand:HI 1 "general_operand" ""))] 1398 "! TARGET_PARTIAL_REG_STALL || optimize_size" 1399{ 1400 /* Don't generate memory->memory moves, go through a register */ 1401 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 1402 operands[1] = force_reg (HImode, operands[1]); 1403}) 1404 1405(define_insn "*movstricthi_1" 1406 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r")) 1407 (match_operand:HI 1 "general_operand" "rn,m"))] 1408 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 1409 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 1410 "mov{w}\t{%1, %0|%0, %1}" 1411 [(set_attr "type" "imov") 1412 (set_attr "mode" "HI")]) 1413 1414(define_insn "*movstricthi_xor" 1415 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) 1416 (match_operand:HI 1 "const0_operand" "i")) 1417 (clobber (reg:CC FLAGS_REG))] 1418 "reload_completed 1419 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)" 1420 "xor{w}\t{%0, %0|%0, %0}" 1421 [(set_attr "type" "alu1") 1422 (set_attr "mode" "HI") 1423 (set_attr "length_immediate" "0")]) 1424 1425(define_expand "movqi" 1426 [(set (match_operand:QI 0 "nonimmediate_operand" "") 1427 (match_operand:QI 1 "general_operand" ""))] 1428 "" 1429 "ix86_expand_move (QImode, operands); DONE;") 1430 1431;; emit_push_insn when it calls move_by_pieces requires an insn to 1432;; "push a byte". But actually we use pushl, which has the effect 1433;; of rounding the amount pushed up to a word. 1434 1435(define_insn "*pushqi2" 1436 [(set (match_operand:QI 0 "push_operand" "=X") 1437 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))] 1438 "!TARGET_64BIT" 1439 "push{l}\t%k1" 1440 [(set_attr "type" "push") 1441 (set_attr "mode" "SI")]) 1442 1443;; For 64BIT abi we always round up to 8 bytes. 1444(define_insn "*pushqi2_rex64" 1445 [(set (match_operand:QI 0 "push_operand" "=X") 1446 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))] 1447 "TARGET_64BIT" 1448 "push{q}\t%q1" 1449 [(set_attr "type" "push") 1450 (set_attr "mode" "DI")]) 1451 1452;; Situation is quite tricky about when to choose full sized (SImode) move 1453;; over QImode moves. For Q_REG -> Q_REG move we use full size only for 1454;; partial register dependency machines (such as AMD Athlon), where QImode 1455;; moves issue extra dependency and for partial register stalls machines 1456;; that don't use QImode patterns (and QImode move cause stall on the next 1457;; instruction). 1458;; 1459;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial 1460;; register stall machines with, where we use QImode instructions, since 1461;; partial register stall can be caused there. Then we use movzx. 1462(define_insn "*movqi_1" 1463 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m") 1464 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))] 1465 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 1466{ 1467 switch (get_attr_type (insn)) 1468 { 1469 case TYPE_IMOVX: 1470 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM); 1471 return "movz{bl|x}\t{%1, %k0|%k0, %1}"; 1472 default: 1473 if (get_attr_mode (insn) == MODE_SI) 1474 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 1475 else 1476 return "mov{b}\t{%1, %0|%0, %1}"; 1477 } 1478} 1479 [(set (attr "type") 1480 (cond [(and (eq_attr "alternative" "5") 1481 (not (match_operand:QI 1 "aligned_operand" ""))) 1482 (const_string "imovx") 1483 (ne (symbol_ref "optimize_size") (const_int 0)) 1484 (const_string "imov") 1485 (and (eq_attr "alternative" "3") 1486 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1487 (const_int 0)) 1488 (eq (symbol_ref "TARGET_QIMODE_MATH") 1489 (const_int 0)))) 1490 (const_string "imov") 1491 (eq_attr "alternative" "3,5") 1492 (const_string "imovx") 1493 (and (ne (symbol_ref "TARGET_MOVX") 1494 (const_int 0)) 1495 (eq_attr "alternative" "2")) 1496 (const_string "imovx") 1497 ] 1498 (const_string "imov"))) 1499 (set (attr "mode") 1500 (cond [(eq_attr "alternative" "3,4,5") 1501 (const_string "SI") 1502 (eq_attr "alternative" "6") 1503 (const_string "QI") 1504 (eq_attr "type" "imovx") 1505 (const_string "SI") 1506 (and (eq_attr "type" "imov") 1507 (and (eq_attr "alternative" "0,1") 1508 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY") 1509 (const_int 0)))) 1510 (const_string "SI") 1511 ;; Avoid partial register stalls when not using QImode arithmetic 1512 (and (eq_attr "type" "imov") 1513 (and (eq_attr "alternative" "0,1") 1514 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL") 1515 (const_int 0)) 1516 (eq (symbol_ref "TARGET_QIMODE_MATH") 1517 (const_int 0))))) 1518 (const_string "SI") 1519 ] 1520 (const_string "QI")))]) 1521 1522(define_expand "reload_outqi" 1523 [(parallel [(match_operand:QI 0 "" "=m") 1524 (match_operand:QI 1 "register_operand" "r") 1525 (match_operand:QI 2 "register_operand" "=&q")])] 1526 "" 1527{ 1528 rtx op0, op1, op2; 1529 op0 = operands[0]; op1 = operands[1]; op2 = operands[2]; 1530 1531 gcc_assert (!reg_overlap_mentioned_p (op2, op0)); 1532 if (! q_regs_operand (op1, QImode)) 1533 { 1534 emit_insn (gen_movqi (op2, op1)); 1535 op1 = op2; 1536 } 1537 emit_insn (gen_movqi (op0, op1)); 1538 DONE; 1539}) 1540 1541(define_insn "*swapqi_1" 1542 [(set (match_operand:QI 0 "register_operand" "+r") 1543 (match_operand:QI 1 "register_operand" "+r")) 1544 (set (match_dup 1) 1545 (match_dup 0))] 1546 "!TARGET_PARTIAL_REG_STALL || optimize_size" 1547 "xchg{l}\t%k1, %k0" 1548 [(set_attr "type" "imov") 1549 (set_attr "mode" "SI") 1550 (set_attr "pent_pair" "np") 1551 (set_attr "athlon_decode" "vector")]) 1552 1553(define_insn "*swapqi_2" 1554 [(set (match_operand:QI 0 "register_operand" "+q") 1555 (match_operand:QI 1 "register_operand" "+q")) 1556 (set (match_dup 1) 1557 (match_dup 0))] 1558 "TARGET_PARTIAL_REG_STALL" 1559 "xchg{b}\t%1, %0" 1560 [(set_attr "type" "imov") 1561 (set_attr "mode" "QI") 1562 (set_attr "pent_pair" "np") 1563 (set_attr "athlon_decode" "vector")]) 1564 1565(define_expand "movstrictqi" 1566 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 1567 (match_operand:QI 1 "general_operand" ""))] 1568 "! TARGET_PARTIAL_REG_STALL || optimize_size" 1569{ 1570 /* Don't generate memory->memory moves, go through a register. */ 1571 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 1572 operands[1] = force_reg (QImode, operands[1]); 1573}) 1574 1575(define_insn "*movstrictqi_1" 1576 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 1577 (match_operand:QI 1 "general_operand" "*qn,m"))] 1578 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 1579 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 1580 "mov{b}\t{%1, %0|%0, %1}" 1581 [(set_attr "type" "imov") 1582 (set_attr "mode" "QI")]) 1583 1584(define_insn "*movstrictqi_xor" 1585 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q")) 1586 (match_operand:QI 1 "const0_operand" "i")) 1587 (clobber (reg:CC FLAGS_REG))] 1588 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)" 1589 "xor{b}\t{%0, %0|%0, %0}" 1590 [(set_attr "type" "alu1") 1591 (set_attr "mode" "QI") 1592 (set_attr "length_immediate" "0")]) 1593 1594(define_insn "*movsi_extv_1" 1595 [(set (match_operand:SI 0 "register_operand" "=R") 1596 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q") 1597 (const_int 8) 1598 (const_int 8)))] 1599 "" 1600 "movs{bl|x}\t{%h1, %0|%0, %h1}" 1601 [(set_attr "type" "imovx") 1602 (set_attr "mode" "SI")]) 1603 1604(define_insn "*movhi_extv_1" 1605 [(set (match_operand:HI 0 "register_operand" "=R") 1606 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q") 1607 (const_int 8) 1608 (const_int 8)))] 1609 "" 1610 "movs{bl|x}\t{%h1, %k0|%k0, %h1}" 1611 [(set_attr "type" "imovx") 1612 (set_attr "mode" "SI")]) 1613 1614(define_insn "*movqi_extv_1" 1615 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r") 1616 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") 1617 (const_int 8) 1618 (const_int 8)))] 1619 "!TARGET_64BIT" 1620{ 1621 switch (get_attr_type (insn)) 1622 { 1623 case TYPE_IMOVX: 1624 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; 1625 default: 1626 return "mov{b}\t{%h1, %0|%0, %h1}"; 1627 } 1628} 1629 [(set (attr "type") 1630 (if_then_else (and (match_operand:QI 0 "register_operand" "") 1631 (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1632 (ne (symbol_ref "TARGET_MOVX") 1633 (const_int 0)))) 1634 (const_string "imovx") 1635 (const_string "imov"))) 1636 (set (attr "mode") 1637 (if_then_else (eq_attr "type" "imovx") 1638 (const_string "SI") 1639 (const_string "QI")))]) 1640 1641(define_insn "*movqi_extv_1_rex64" 1642 [(set (match_operand:QI 0 "register_operand" "=Q,?R") 1643 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") 1644 (const_int 8) 1645 (const_int 8)))] 1646 "TARGET_64BIT" 1647{ 1648 switch (get_attr_type (insn)) 1649 { 1650 case TYPE_IMOVX: 1651 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; 1652 default: 1653 return "mov{b}\t{%h1, %0|%0, %h1}"; 1654 } 1655} 1656 [(set (attr "type") 1657 (if_then_else (and (match_operand:QI 0 "register_operand" "") 1658 (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1659 (ne (symbol_ref "TARGET_MOVX") 1660 (const_int 0)))) 1661 (const_string "imovx") 1662 (const_string "imov"))) 1663 (set (attr "mode") 1664 (if_then_else (eq_attr "type" "imovx") 1665 (const_string "SI") 1666 (const_string "QI")))]) 1667 1668;; Stores and loads of ax to arbitrary constant address. 1669;; We fake an second form of instruction to force reload to load address 1670;; into register when rax is not available 1671(define_insn "*movabsqi_1_rex64" 1672 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 1673 (match_operand:QI 1 "nonmemory_operand" "a,er"))] 1674 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 1675 "@ 1676 movabs{b}\t{%1, %P0|%P0, %1} 1677 mov{b}\t{%1, %a0|%a0, %1}" 1678 [(set_attr "type" "imov") 1679 (set_attr "modrm" "0,*") 1680 (set_attr "length_address" "8,0") 1681 (set_attr "length_immediate" "0,*") 1682 (set_attr "memory" "store") 1683 (set_attr "mode" "QI")]) 1684 1685(define_insn "*movabsqi_2_rex64" 1686 [(set (match_operand:QI 0 "register_operand" "=a,r") 1687 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 1688 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 1689 "@ 1690 movabs{b}\t{%P1, %0|%0, %P1} 1691 mov{b}\t{%a1, %0|%0, %a1}" 1692 [(set_attr "type" "imov") 1693 (set_attr "modrm" "0,*") 1694 (set_attr "length_address" "8,0") 1695 (set_attr "length_immediate" "0") 1696 (set_attr "memory" "load") 1697 (set_attr "mode" "QI")]) 1698 1699(define_insn "*movdi_extzv_1" 1700 [(set (match_operand:DI 0 "register_operand" "=R") 1701 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q") 1702 (const_int 8) 1703 (const_int 8)))] 1704 "TARGET_64BIT" 1705 "movz{bl|x}\t{%h1, %k0|%k0, %h1}" 1706 [(set_attr "type" "imovx") 1707 (set_attr "mode" "DI")]) 1708 1709(define_insn "*movsi_extzv_1" 1710 [(set (match_operand:SI 0 "register_operand" "=R") 1711 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q") 1712 (const_int 8) 1713 (const_int 8)))] 1714 "" 1715 "movz{bl|x}\t{%h1, %0|%0, %h1}" 1716 [(set_attr "type" "imovx") 1717 (set_attr "mode" "SI")]) 1718 1719(define_insn "*movqi_extzv_2" 1720 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R") 1721 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") 1722 (const_int 8) 1723 (const_int 8)) 0))] 1724 "!TARGET_64BIT" 1725{ 1726 switch (get_attr_type (insn)) 1727 { 1728 case TYPE_IMOVX: 1729 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 1730 default: 1731 return "mov{b}\t{%h1, %0|%0, %h1}"; 1732 } 1733} 1734 [(set (attr "type") 1735 (if_then_else (and (match_operand:QI 0 "register_operand" "") 1736 (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1737 (ne (symbol_ref "TARGET_MOVX") 1738 (const_int 0)))) 1739 (const_string "imovx") 1740 (const_string "imov"))) 1741 (set (attr "mode") 1742 (if_then_else (eq_attr "type" "imovx") 1743 (const_string "SI") 1744 (const_string "QI")))]) 1745 1746(define_insn "*movqi_extzv_2_rex64" 1747 [(set (match_operand:QI 0 "register_operand" "=Q,?R") 1748 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") 1749 (const_int 8) 1750 (const_int 8)) 0))] 1751 "TARGET_64BIT" 1752{ 1753 switch (get_attr_type (insn)) 1754 { 1755 case TYPE_IMOVX: 1756 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 1757 default: 1758 return "mov{b}\t{%h1, %0|%0, %h1}"; 1759 } 1760} 1761 [(set (attr "type") 1762 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1763 (ne (symbol_ref "TARGET_MOVX") 1764 (const_int 0))) 1765 (const_string "imovx") 1766 (const_string "imov"))) 1767 (set (attr "mode") 1768 (if_then_else (eq_attr "type" "imovx") 1769 (const_string "SI") 1770 (const_string "QI")))]) 1771 1772(define_insn "movsi_insv_1" 1773 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 1774 (const_int 8) 1775 (const_int 8)) 1776 (match_operand:SI 1 "general_operand" "Qmn"))] 1777 "!TARGET_64BIT" 1778 "mov{b}\t{%b1, %h0|%h0, %b1}" 1779 [(set_attr "type" "imov") 1780 (set_attr "mode" "QI")]) 1781 1782(define_insn "movdi_insv_1_rex64" 1783 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q") 1784 (const_int 8) 1785 (const_int 8)) 1786 (match_operand:DI 1 "nonmemory_operand" "Qn"))] 1787 "TARGET_64BIT" 1788 "mov{b}\t{%b1, %h0|%h0, %b1}" 1789 [(set_attr "type" "imov") 1790 (set_attr "mode" "QI")]) 1791 1792(define_insn "*movqi_insv_2" 1793 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 1794 (const_int 8) 1795 (const_int 8)) 1796 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q") 1797 (const_int 8)))] 1798 "" 1799 "mov{b}\t{%h1, %h0|%h0, %h1}" 1800 [(set_attr "type" "imov") 1801 (set_attr "mode" "QI")]) 1802 1803(define_expand "movdi" 1804 [(set (match_operand:DI 0 "nonimmediate_operand" "") 1805 (match_operand:DI 1 "general_operand" ""))] 1806 "" 1807 "ix86_expand_move (DImode, operands); DONE;") 1808 1809(define_insn "*pushdi" 1810 [(set (match_operand:DI 0 "push_operand" "=<") 1811 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))] 1812 "!TARGET_64BIT" 1813 "#") 1814 1815(define_insn "*pushdi2_rex64" 1816 [(set (match_operand:DI 0 "push_operand" "=<,!<") 1817 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))] 1818 "TARGET_64BIT" 1819 "@ 1820 push{q}\t%1 1821 #" 1822 [(set_attr "type" "push,multi") 1823 (set_attr "mode" "DI")]) 1824 1825;; Convert impossible pushes of immediate to existing instructions. 1826;; First try to get scratch register and go through it. In case this 1827;; fails, push sign extended lower part first and then overwrite 1828;; upper part by 32bit move. 1829(define_peephole2 1830 [(match_scratch:DI 2 "r") 1831 (set (match_operand:DI 0 "push_operand" "") 1832 (match_operand:DI 1 "immediate_operand" ""))] 1833 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1834 && !x86_64_immediate_operand (operands[1], DImode)" 1835 [(set (match_dup 2) (match_dup 1)) 1836 (set (match_dup 0) (match_dup 2))] 1837 "") 1838 1839;; We need to define this as both peepholer and splitter for case 1840;; peephole2 pass is not run. 1841;; "&& 1" is needed to keep it from matching the previous pattern. 1842(define_peephole2 1843 [(set (match_operand:DI 0 "push_operand" "") 1844 (match_operand:DI 1 "immediate_operand" ""))] 1845 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1846 && !x86_64_immediate_operand (operands[1], DImode) && 1" 1847 [(set (match_dup 0) (match_dup 1)) 1848 (set (match_dup 2) (match_dup 3))] 1849 "split_di (operands + 1, 1, operands + 2, operands + 3); 1850 operands[1] = gen_lowpart (DImode, operands[2]); 1851 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, 1852 GEN_INT (4))); 1853 ") 1854 1855(define_split 1856 [(set (match_operand:DI 0 "push_operand" "") 1857 (match_operand:DI 1 "immediate_operand" ""))] 1858 "TARGET_64BIT && ((optimize > 0 && flag_peephole2) 1859 ? flow2_completed : reload_completed) 1860 && !symbolic_operand (operands[1], DImode) 1861 && !x86_64_immediate_operand (operands[1], DImode)" 1862 [(set (match_dup 0) (match_dup 1)) 1863 (set (match_dup 2) (match_dup 3))] 1864 "split_di (operands + 1, 1, operands + 2, operands + 3); 1865 operands[1] = gen_lowpart (DImode, operands[2]); 1866 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, 1867 GEN_INT (4))); 1868 ") 1869 1870(define_insn "*pushdi2_prologue_rex64" 1871 [(set (match_operand:DI 0 "push_operand" "=<") 1872 (match_operand:DI 1 "general_no_elim_operand" "re*m")) 1873 (clobber (mem:BLK (scratch)))] 1874 "TARGET_64BIT" 1875 "push{q}\t%1" 1876 [(set_attr "type" "push") 1877 (set_attr "mode" "DI")]) 1878 1879(define_insn "*popdi1_epilogue_rex64" 1880 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m") 1881 (mem:DI (reg:DI SP_REG))) 1882 (set (reg:DI SP_REG) 1883 (plus:DI (reg:DI SP_REG) (const_int 8))) 1884 (clobber (mem:BLK (scratch)))] 1885 "TARGET_64BIT" 1886 "pop{q}\t%0" 1887 [(set_attr "type" "pop") 1888 (set_attr "mode" "DI")]) 1889 1890(define_insn "popdi1" 1891 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m") 1892 (mem:DI (reg:DI SP_REG))) 1893 (set (reg:DI SP_REG) 1894 (plus:DI (reg:DI SP_REG) (const_int 8)))] 1895 "TARGET_64BIT" 1896 "pop{q}\t%0" 1897 [(set_attr "type" "pop") 1898 (set_attr "mode" "DI")]) 1899 1900(define_insn "*movdi_xor_rex64" 1901 [(set (match_operand:DI 0 "register_operand" "=r") 1902 (match_operand:DI 1 "const0_operand" "i")) 1903 (clobber (reg:CC FLAGS_REG))] 1904 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size) 1905 && reload_completed" 1906 "xor{l}\t{%k0, %k0|%k0, %k0}" 1907 [(set_attr "type" "alu1") 1908 (set_attr "mode" "SI") 1909 (set_attr "length_immediate" "0")]) 1910 1911(define_insn "*movdi_or_rex64" 1912 [(set (match_operand:DI 0 "register_operand" "=r") 1913 (match_operand:DI 1 "const_int_operand" "i")) 1914 (clobber (reg:CC FLAGS_REG))] 1915 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size) 1916 && reload_completed 1917 && operands[1] == constm1_rtx" 1918{ 1919 operands[1] = constm1_rtx; 1920 return "or{q}\t{%1, %0|%0, %1}"; 1921} 1922 [(set_attr "type" "alu1") 1923 (set_attr "mode" "DI") 1924 (set_attr "length_immediate" "1")]) 1925 1926(define_insn "*movdi_2" 1927 [(set (match_operand:DI 0 "nonimmediate_operand" 1928 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x") 1929 (match_operand:DI 1 "general_operand" 1930 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))] 1931 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1932 "@ 1933 # 1934 # 1935 pxor\t%0, %0 1936 movq\t{%1, %0|%0, %1} 1937 movq\t{%1, %0|%0, %1} 1938 pxor\t%0, %0 1939 movq\t{%1, %0|%0, %1} 1940 movdqa\t{%1, %0|%0, %1} 1941 movq\t{%1, %0|%0, %1} 1942 xorps\t%0, %0 1943 movlps\t{%1, %0|%0, %1} 1944 movaps\t{%1, %0|%0, %1} 1945 movlps\t{%1, %0|%0, %1}" 1946 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov") 1947 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")]) 1948 1949(define_split 1950 [(set (match_operand:DI 0 "push_operand" "") 1951 (match_operand:DI 1 "general_operand" ""))] 1952 "!TARGET_64BIT && reload_completed 1953 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))" 1954 [(const_int 0)] 1955 "ix86_split_long_move (operands); DONE;") 1956 1957;; %%% This multiword shite has got to go. 1958(define_split 1959 [(set (match_operand:DI 0 "nonimmediate_operand" "") 1960 (match_operand:DI 1 "general_operand" ""))] 1961 "!TARGET_64BIT && reload_completed 1962 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0])) 1963 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))" 1964 [(const_int 0)] 1965 "ix86_split_long_move (operands); DONE;") 1966 1967(define_insn "*movdi_1_rex64" 1968 [(set (match_operand:DI 0 "nonimmediate_operand" 1969 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y") 1970 (match_operand:DI 1 "general_operand" 1971 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))] 1972 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1973{ 1974 switch (get_attr_type (insn)) 1975 { 1976 case TYPE_SSECVT: 1977 if (which_alternative == 13) 1978 return "movq2dq\t{%1, %0|%0, %1}"; 1979 else 1980 return "movdq2q\t{%1, %0|%0, %1}"; 1981 case TYPE_SSEMOV: 1982 if (get_attr_mode (insn) == MODE_TI) 1983 return "movdqa\t{%1, %0|%0, %1}"; 1984 /* FALLTHRU */ 1985 case TYPE_MMXMOV: 1986 /* Moves from and into integer register is done using movd opcode with 1987 REX prefix. */ 1988 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])) 1989 return "movd\t{%1, %0|%0, %1}"; 1990 return "movq\t{%1, %0|%0, %1}"; 1991 case TYPE_SSELOG1: 1992 case TYPE_MMXADD: 1993 return "pxor\t%0, %0"; 1994 case TYPE_MULTI: 1995 return "#"; 1996 case TYPE_LEA: 1997 return "lea{q}\t{%a1, %0|%0, %a1}"; 1998 default: 1999 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 2000 if (get_attr_mode (insn) == MODE_SI) 2001 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2002 else if (which_alternative == 2) 2003 return "movabs{q}\t{%1, %0|%0, %1}"; 2004 else 2005 return "mov{q}\t{%1, %0|%0, %1}"; 2006 } 2007} 2008 [(set (attr "type") 2009 (cond [(eq_attr "alternative" "5") 2010 (const_string "mmxadd") 2011 (eq_attr "alternative" "6,7,8") 2012 (const_string "mmxmov") 2013 (eq_attr "alternative" "9") 2014 (const_string "sselog1") 2015 (eq_attr "alternative" "10,11,12") 2016 (const_string "ssemov") 2017 (eq_attr "alternative" "13,14") 2018 (const_string "ssecvt") 2019 (eq_attr "alternative" "4") 2020 (const_string "multi") 2021 (match_operand:DI 1 "pic_32bit_operand" "") 2022 (const_string "lea") 2023 ] 2024 (const_string "imov"))) 2025 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*") 2026 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*") 2027 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")]) 2028 2029;; Stores and loads of ax to arbitrary constant address. 2030;; We fake an second form of instruction to force reload to load address 2031;; into register when rax is not available 2032(define_insn "*movabsdi_1_rex64" 2033 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 2034 (match_operand:DI 1 "nonmemory_operand" "a,er"))] 2035 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 2036 "@ 2037 movabs{q}\t{%1, %P0|%P0, %1} 2038 mov{q}\t{%1, %a0|%a0, %1}" 2039 [(set_attr "type" "imov") 2040 (set_attr "modrm" "0,*") 2041 (set_attr "length_address" "8,0") 2042 (set_attr "length_immediate" "0,*") 2043 (set_attr "memory" "store") 2044 (set_attr "mode" "DI")]) 2045 2046(define_insn "*movabsdi_2_rex64" 2047 [(set (match_operand:DI 0 "register_operand" "=a,r") 2048 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 2049 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 2050 "@ 2051 movabs{q}\t{%P1, %0|%0, %P1} 2052 mov{q}\t{%a1, %0|%0, %a1}" 2053 [(set_attr "type" "imov") 2054 (set_attr "modrm" "0,*") 2055 (set_attr "length_address" "8,0") 2056 (set_attr "length_immediate" "0") 2057 (set_attr "memory" "load") 2058 (set_attr "mode" "DI")]) 2059 2060;; Convert impossible stores of immediate to existing instructions. 2061;; First try to get scratch register and go through it. In case this 2062;; fails, move by 32bit parts. 2063(define_peephole2 2064 [(match_scratch:DI 2 "r") 2065 (set (match_operand:DI 0 "memory_operand" "") 2066 (match_operand:DI 1 "immediate_operand" ""))] 2067 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 2068 && !x86_64_immediate_operand (operands[1], DImode)" 2069 [(set (match_dup 2) (match_dup 1)) 2070 (set (match_dup 0) (match_dup 2))] 2071 "") 2072 2073;; We need to define this as both peepholer and splitter for case 2074;; peephole2 pass is not run. 2075;; "&& 1" is needed to keep it from matching the previous pattern. 2076(define_peephole2 2077 [(set (match_operand:DI 0 "memory_operand" "") 2078 (match_operand:DI 1 "immediate_operand" ""))] 2079 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 2080 && !x86_64_immediate_operand (operands[1], DImode) && 1" 2081 [(set (match_dup 2) (match_dup 3)) 2082 (set (match_dup 4) (match_dup 5))] 2083 "split_di (operands, 2, operands + 2, operands + 4);") 2084 2085(define_split 2086 [(set (match_operand:DI 0 "memory_operand" "") 2087 (match_operand:DI 1 "immediate_operand" ""))] 2088 "TARGET_64BIT && ((optimize > 0 && flag_peephole2) 2089 ? flow2_completed : reload_completed) 2090 && !symbolic_operand (operands[1], DImode) 2091 && !x86_64_immediate_operand (operands[1], DImode)" 2092 [(set (match_dup 2) (match_dup 3)) 2093 (set (match_dup 4) (match_dup 5))] 2094 "split_di (operands, 2, operands + 2, operands + 4);") 2095 2096(define_insn "*swapdi_rex64" 2097 [(set (match_operand:DI 0 "register_operand" "+r") 2098 (match_operand:DI 1 "register_operand" "+r")) 2099 (set (match_dup 1) 2100 (match_dup 0))] 2101 "TARGET_64BIT" 2102 "xchg{q}\t%1, %0" 2103 [(set_attr "type" "imov") 2104 (set_attr "mode" "DI") 2105 (set_attr "pent_pair" "np") 2106 (set_attr "athlon_decode" "vector")]) 2107 2108(define_expand "movti" 2109 [(set (match_operand:TI 0 "nonimmediate_operand" "") 2110 (match_operand:TI 1 "nonimmediate_operand" ""))] 2111 "TARGET_SSE || TARGET_64BIT" 2112{ 2113 if (TARGET_64BIT) 2114 ix86_expand_move (TImode, operands); 2115 else 2116 ix86_expand_vector_move (TImode, operands); 2117 DONE; 2118}) 2119 2120(define_insn "*movti_internal" 2121 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m") 2122 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))] 2123 "TARGET_SSE && !TARGET_64BIT 2124 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 2125{ 2126 switch (which_alternative) 2127 { 2128 case 0: 2129 if (get_attr_mode (insn) == MODE_V4SF) 2130 return "xorps\t%0, %0"; 2131 else 2132 return "pxor\t%0, %0"; 2133 case 1: 2134 case 2: 2135 if (get_attr_mode (insn) == MODE_V4SF) 2136 return "movaps\t{%1, %0|%0, %1}"; 2137 else 2138 return "movdqa\t{%1, %0|%0, %1}"; 2139 default: 2140 gcc_unreachable (); 2141 } 2142} 2143 [(set_attr "type" "ssemov,ssemov,ssemov") 2144 (set (attr "mode") 2145 (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0)) 2146 (const_string "V4SF") 2147 2148 (eq_attr "alternative" "0,1") 2149 (if_then_else 2150 (ne (symbol_ref "optimize_size") 2151 (const_int 0)) 2152 (const_string "V4SF") 2153 (const_string "TI")) 2154 (eq_attr "alternative" "2") 2155 (if_then_else 2156 (ne (symbol_ref "optimize_size") 2157 (const_int 0)) 2158 (const_string "V4SF") 2159 (const_string "TI"))] 2160 (const_string "TI")))]) 2161 2162(define_insn "*movti_rex64" 2163 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm") 2164 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))] 2165 "TARGET_64BIT 2166 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 2167{ 2168 switch (which_alternative) 2169 { 2170 case 0: 2171 case 1: 2172 return "#"; 2173 case 2: 2174 if (get_attr_mode (insn) == MODE_V4SF) 2175 return "xorps\t%0, %0"; 2176 else 2177 return "pxor\t%0, %0"; 2178 case 3: 2179 case 4: 2180 if (get_attr_mode (insn) == MODE_V4SF) 2181 return "movaps\t{%1, %0|%0, %1}"; 2182 else 2183 return "movdqa\t{%1, %0|%0, %1}"; 2184 default: 2185 gcc_unreachable (); 2186 } 2187} 2188 [(set_attr "type" "*,*,ssemov,ssemov,ssemov") 2189 (set (attr "mode") 2190 (cond [(eq_attr "alternative" "2,3") 2191 (if_then_else 2192 (ne (symbol_ref "optimize_size") 2193 (const_int 0)) 2194 (const_string "V4SF") 2195 (const_string "TI")) 2196 (eq_attr "alternative" "4") 2197 (if_then_else 2198 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") 2199 (const_int 0)) 2200 (ne (symbol_ref "optimize_size") 2201 (const_int 0))) 2202 (const_string "V4SF") 2203 (const_string "TI"))] 2204 (const_string "DI")))]) 2205 2206(define_split 2207 [(set (match_operand:TI 0 "nonimmediate_operand" "") 2208 (match_operand:TI 1 "general_operand" ""))] 2209 "reload_completed && !SSE_REG_P (operands[0]) 2210 && !SSE_REG_P (operands[1])" 2211 [(const_int 0)] 2212 "ix86_split_long_move (operands); DONE;") 2213 2214(define_expand "movsf" 2215 [(set (match_operand:SF 0 "nonimmediate_operand" "") 2216 (match_operand:SF 1 "general_operand" ""))] 2217 "" 2218 "ix86_expand_move (SFmode, operands); DONE;") 2219 2220(define_insn "*pushsf" 2221 [(set (match_operand:SF 0 "push_operand" "=<,<,<") 2222 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))] 2223 "!TARGET_64BIT" 2224{ 2225 /* Anything else should be already split before reg-stack. */ 2226 gcc_assert (which_alternative == 1); 2227 return "push{l}\t%1"; 2228} 2229 [(set_attr "type" "multi,push,multi") 2230 (set_attr "unit" "i387,*,*") 2231 (set_attr "mode" "SF,SI,SF")]) 2232 2233(define_insn "*pushsf_rex64" 2234 [(set (match_operand:SF 0 "push_operand" "=X,X,X") 2235 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))] 2236 "TARGET_64BIT" 2237{ 2238 /* Anything else should be already split before reg-stack. */ 2239 gcc_assert (which_alternative == 1); 2240 return "push{q}\t%q1"; 2241} 2242 [(set_attr "type" "multi,push,multi") 2243 (set_attr "unit" "i387,*,*") 2244 (set_attr "mode" "SF,DI,SF")]) 2245 2246(define_split 2247 [(set (match_operand:SF 0 "push_operand" "") 2248 (match_operand:SF 1 "memory_operand" ""))] 2249 "reload_completed 2250 && GET_CODE (operands[1]) == MEM 2251 && constant_pool_reference_p (operands[1])" 2252 [(set (match_dup 0) 2253 (match_dup 1))] 2254 "operands[1] = avoid_constant_pool_reference (operands[1]);") 2255 2256 2257;; %%% Kill this when call knows how to work this out. 2258(define_split 2259 [(set (match_operand:SF 0 "push_operand" "") 2260 (match_operand:SF 1 "any_fp_register_operand" ""))] 2261 "!TARGET_64BIT" 2262 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) 2263 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))]) 2264 2265(define_split 2266 [(set (match_operand:SF 0 "push_operand" "") 2267 (match_operand:SF 1 "any_fp_register_operand" ""))] 2268 "TARGET_64BIT" 2269 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 2270 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))]) 2271 2272(define_insn "*movsf_1" 2273 [(set (match_operand:SF 0 "nonimmediate_operand" 2274 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y") 2275 (match_operand:SF 1 "general_operand" 2276 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))] 2277 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 2278 && (reload_in_progress || reload_completed 2279 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2280 || GET_CODE (operands[1]) != CONST_DOUBLE 2281 || memory_operand (operands[0], SFmode))" 2282{ 2283 switch (which_alternative) 2284 { 2285 case 0: 2286 return output_387_reg_move (insn, operands); 2287 2288 case 1: 2289 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2290 return "fstp%z0\t%y0"; 2291 else 2292 return "fst%z0\t%y0"; 2293 2294 case 2: 2295 return standard_80387_constant_opcode (operands[1]); 2296 2297 case 3: 2298 case 4: 2299 return "mov{l}\t{%1, %0|%0, %1}"; 2300 case 5: 2301 if (get_attr_mode (insn) == MODE_TI) 2302 return "pxor\t%0, %0"; 2303 else 2304 return "xorps\t%0, %0"; 2305 case 6: 2306 if (get_attr_mode (insn) == MODE_V4SF) 2307 return "movaps\t{%1, %0|%0, %1}"; 2308 else 2309 return "movss\t{%1, %0|%0, %1}"; 2310 case 7: 2311 case 8: 2312 return "movss\t{%1, %0|%0, %1}"; 2313 2314 case 9: 2315 case 10: 2316 return "movd\t{%1, %0|%0, %1}"; 2317 2318 case 11: 2319 return "movq\t{%1, %0|%0, %1}"; 2320 2321 default: 2322 gcc_unreachable (); 2323 } 2324} 2325 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov") 2326 (set (attr "mode") 2327 (cond [(eq_attr "alternative" "3,4,9,10") 2328 (const_string "SI") 2329 (eq_attr "alternative" "5") 2330 (if_then_else 2331 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") 2332 (const_int 0)) 2333 (ne (symbol_ref "TARGET_SSE2") 2334 (const_int 0))) 2335 (eq (symbol_ref "optimize_size") 2336 (const_int 0))) 2337 (const_string "TI") 2338 (const_string "V4SF")) 2339 /* For architectures resolving dependencies on 2340 whole SSE registers use APS move to break dependency 2341 chains, otherwise use short move to avoid extra work. 2342 2343 Do the same for architectures resolving dependencies on 2344 the parts. While in DF mode it is better to always handle 2345 just register parts, the SF mode is different due to lack 2346 of instructions to load just part of the register. It is 2347 better to maintain the whole registers in single format 2348 to avoid problems on using packed logical operations. */ 2349 (eq_attr "alternative" "6") 2350 (if_then_else 2351 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 2352 (const_int 0)) 2353 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") 2354 (const_int 0))) 2355 (const_string "V4SF") 2356 (const_string "SF")) 2357 (eq_attr "alternative" "11") 2358 (const_string "DI")] 2359 (const_string "SF")))]) 2360 2361(define_insn "*swapsf" 2362 [(set (match_operand:SF 0 "fp_register_operand" "+f") 2363 (match_operand:SF 1 "fp_register_operand" "+f")) 2364 (set (match_dup 1) 2365 (match_dup 0))] 2366 "reload_completed || TARGET_80387" 2367{ 2368 if (STACK_TOP_P (operands[0])) 2369 return "fxch\t%1"; 2370 else 2371 return "fxch\t%0"; 2372} 2373 [(set_attr "type" "fxch") 2374 (set_attr "mode" "SF")]) 2375 2376(define_expand "movdf" 2377 [(set (match_operand:DF 0 "nonimmediate_operand" "") 2378 (match_operand:DF 1 "general_operand" ""))] 2379 "" 2380 "ix86_expand_move (DFmode, operands); DONE;") 2381 2382;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. 2383;; Size of pushdf using integer instructions is 2+2*memory operand size 2384;; On the average, pushdf using integers can be still shorter. Allow this 2385;; pattern for optimize_size too. 2386 2387(define_insn "*pushdf_nointeger" 2388 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<") 2389 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))] 2390 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES" 2391{ 2392 /* This insn should be already split before reg-stack. */ 2393 gcc_unreachable (); 2394} 2395 [(set_attr "type" "multi") 2396 (set_attr "unit" "i387,*,*,*") 2397 (set_attr "mode" "DF,SI,SI,DF")]) 2398 2399(define_insn "*pushdf_integer" 2400 [(set (match_operand:DF 0 "push_operand" "=<,<,<") 2401 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))] 2402 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES" 2403{ 2404 /* This insn should be already split before reg-stack. */ 2405 gcc_unreachable (); 2406} 2407 [(set_attr "type" "multi") 2408 (set_attr "unit" "i387,*,*") 2409 (set_attr "mode" "DF,SI,DF")]) 2410 2411;; %%% Kill this when call knows how to work this out. 2412(define_split 2413 [(set (match_operand:DF 0 "push_operand" "") 2414 (match_operand:DF 1 "any_fp_register_operand" ""))] 2415 "!TARGET_64BIT && reload_completed" 2416 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 2417 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))] 2418 "") 2419 2420(define_split 2421 [(set (match_operand:DF 0 "push_operand" "") 2422 (match_operand:DF 1 "any_fp_register_operand" ""))] 2423 "TARGET_64BIT && reload_completed" 2424 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 2425 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))] 2426 "") 2427 2428(define_split 2429 [(set (match_operand:DF 0 "push_operand" "") 2430 (match_operand:DF 1 "general_operand" ""))] 2431 "reload_completed" 2432 [(const_int 0)] 2433 "ix86_split_long_move (operands); DONE;") 2434 2435;; Moving is usually shorter when only FP registers are used. This separate 2436;; movdf pattern avoids the use of integer registers for FP operations 2437;; when optimizing for size. 2438 2439(define_insn "*movdf_nointeger" 2440 [(set (match_operand:DF 0 "nonimmediate_operand" 2441 "=f#Y,m ,f#Y,*r ,o ,Y*x#f,Y*x#f,Y*x#f ,m ") 2442 (match_operand:DF 1 "general_operand" 2443 "fm#Y,f#Y,G ,*roF,F*r,C ,Y*x#f,HmY*x#f,Y*x#f"))] 2444 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2445 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT) 2446 && (reload_in_progress || reload_completed 2447 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2448 || GET_CODE (operands[1]) != CONST_DOUBLE 2449 || memory_operand (operands[0], DFmode))" 2450{ 2451 switch (which_alternative) 2452 { 2453 case 0: 2454 return output_387_reg_move (insn, operands); 2455 2456 case 1: 2457 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2458 return "fstp%z0\t%y0"; 2459 else 2460 return "fst%z0\t%y0"; 2461 2462 case 2: 2463 return standard_80387_constant_opcode (operands[1]); 2464 2465 case 3: 2466 case 4: 2467 return "#"; 2468 case 5: 2469 switch (get_attr_mode (insn)) 2470 { 2471 case MODE_V4SF: 2472 return "xorps\t%0, %0"; 2473 case MODE_V2DF: 2474 return "xorpd\t%0, %0"; 2475 case MODE_TI: 2476 return "pxor\t%0, %0"; 2477 default: 2478 gcc_unreachable (); 2479 } 2480 case 6: 2481 case 7: 2482 case 8: 2483 switch (get_attr_mode (insn)) 2484 { 2485 case MODE_V4SF: 2486 return "movaps\t{%1, %0|%0, %1}"; 2487 case MODE_V2DF: 2488 return "movapd\t{%1, %0|%0, %1}"; 2489 case MODE_TI: 2490 return "movdqa\t{%1, %0|%0, %1}"; 2491 case MODE_DI: 2492 return "movq\t{%1, %0|%0, %1}"; 2493 case MODE_DF: 2494 return "movsd\t{%1, %0|%0, %1}"; 2495 case MODE_V1DF: 2496 return "movlpd\t{%1, %0|%0, %1}"; 2497 case MODE_V2SF: 2498 return "movlps\t{%1, %0|%0, %1}"; 2499 default: 2500 gcc_unreachable (); 2501 } 2502 2503 default: 2504 gcc_unreachable (); 2505 } 2506} 2507 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov") 2508 (set (attr "mode") 2509 (cond [(eq_attr "alternative" "0,1,2") 2510 (const_string "DF") 2511 (eq_attr "alternative" "3,4") 2512 (const_string "SI") 2513 2514 /* For SSE1, we have many fewer alternatives. */ 2515 (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 2516 (cond [(eq_attr "alternative" "5,6") 2517 (const_string "V4SF") 2518 ] 2519 (const_string "V2SF")) 2520 2521 /* xorps is one byte shorter. */ 2522 (eq_attr "alternative" "5") 2523 (cond [(ne (symbol_ref "optimize_size") 2524 (const_int 0)) 2525 (const_string "V4SF") 2526 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") 2527 (const_int 0)) 2528 (const_string "TI") 2529 ] 2530 (const_string "V2DF")) 2531 2532 /* For architectures resolving dependencies on 2533 whole SSE registers use APD move to break dependency 2534 chains, otherwise use short move to avoid extra work. 2535 2536 movaps encodes one byte shorter. */ 2537 (eq_attr "alternative" "6") 2538 (cond 2539 [(ne (symbol_ref "optimize_size") 2540 (const_int 0)) 2541 (const_string "V4SF") 2542 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 2543 (const_int 0)) 2544 (const_string "V2DF") 2545 ] 2546 (const_string "DF")) 2547 /* For architectures resolving dependencies on register 2548 parts we may avoid extra work to zero out upper part 2549 of register. */ 2550 (eq_attr "alternative" "7") 2551 (if_then_else 2552 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") 2553 (const_int 0)) 2554 (const_string "V1DF") 2555 (const_string "DF")) 2556 ] 2557 (const_string "DF")))]) 2558 2559(define_insn "*movdf_integer" 2560 [(set (match_operand:DF 0 "nonimmediate_operand" 2561 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y*x#rf,Y*x#rf,Y*x#rf,m") 2562 (match_operand:DF 1 "general_operand" 2563 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y*x#rf,m ,Y*x#rf"))] 2564 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2565 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT) 2566 && (reload_in_progress || reload_completed 2567 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2568 || GET_CODE (operands[1]) != CONST_DOUBLE 2569 || memory_operand (operands[0], DFmode))" 2570{ 2571 switch (which_alternative) 2572 { 2573 case 0: 2574 return output_387_reg_move (insn, operands); 2575 2576 case 1: 2577 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2578 return "fstp%z0\t%y0"; 2579 else 2580 return "fst%z0\t%y0"; 2581 2582 case 2: 2583 return standard_80387_constant_opcode (operands[1]); 2584 2585 case 3: 2586 case 4: 2587 return "#"; 2588 2589 case 5: 2590 switch (get_attr_mode (insn)) 2591 { 2592 case MODE_V4SF: 2593 return "xorps\t%0, %0"; 2594 case MODE_V2DF: 2595 return "xorpd\t%0, %0"; 2596 case MODE_TI: 2597 return "pxor\t%0, %0"; 2598 default: 2599 gcc_unreachable (); 2600 } 2601 case 6: 2602 case 7: 2603 case 8: 2604 switch (get_attr_mode (insn)) 2605 { 2606 case MODE_V4SF: 2607 return "movaps\t{%1, %0|%0, %1}"; 2608 case MODE_V2DF: 2609 return "movapd\t{%1, %0|%0, %1}"; 2610 case MODE_TI: 2611 return "movdqa\t{%1, %0|%0, %1}"; 2612 case MODE_DI: 2613 return "movq\t{%1, %0|%0, %1}"; 2614 case MODE_DF: 2615 return "movsd\t{%1, %0|%0, %1}"; 2616 case MODE_V1DF: 2617 return "movlpd\t{%1, %0|%0, %1}"; 2618 case MODE_V2SF: 2619 return "movlps\t{%1, %0|%0, %1}"; 2620 default: 2621 gcc_unreachable (); 2622 } 2623 2624 default: 2625 gcc_unreachable(); 2626 } 2627} 2628 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov") 2629 (set (attr "mode") 2630 (cond [(eq_attr "alternative" "0,1,2") 2631 (const_string "DF") 2632 (eq_attr "alternative" "3,4") 2633 (const_string "SI") 2634 2635 /* For SSE1, we have many fewer alternatives. */ 2636 (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 2637 (cond [(eq_attr "alternative" "5,6") 2638 (const_string "V4SF") 2639 ] 2640 (const_string "V2SF")) 2641 2642 /* xorps is one byte shorter. */ 2643 (eq_attr "alternative" "5") 2644 (cond [(ne (symbol_ref "optimize_size") 2645 (const_int 0)) 2646 (const_string "V4SF") 2647 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") 2648 (const_int 0)) 2649 (const_string "TI") 2650 ] 2651 (const_string "V2DF")) 2652 2653 /* For architectures resolving dependencies on 2654 whole SSE registers use APD move to break dependency 2655 chains, otherwise use short move to avoid extra work. 2656 2657 movaps encodes one byte shorter. */ 2658 (eq_attr "alternative" "6") 2659 (cond 2660 [(ne (symbol_ref "optimize_size") 2661 (const_int 0)) 2662 (const_string "V4SF") 2663 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 2664 (const_int 0)) 2665 (const_string "V2DF") 2666 ] 2667 (const_string "DF")) 2668 /* For architectures resolving dependencies on register 2669 parts we may avoid extra work to zero out upper part 2670 of register. */ 2671 (eq_attr "alternative" "7") 2672 (if_then_else 2673 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") 2674 (const_int 0)) 2675 (const_string "V1DF") 2676 (const_string "DF")) 2677 ] 2678 (const_string "DF")))]) 2679 2680(define_split 2681 [(set (match_operand:DF 0 "nonimmediate_operand" "") 2682 (match_operand:DF 1 "general_operand" ""))] 2683 "reload_completed 2684 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2685 && ! (ANY_FP_REG_P (operands[0]) || 2686 (GET_CODE (operands[0]) == SUBREG 2687 && ANY_FP_REG_P (SUBREG_REG (operands[0])))) 2688 && ! (ANY_FP_REG_P (operands[1]) || 2689 (GET_CODE (operands[1]) == SUBREG 2690 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))" 2691 [(const_int 0)] 2692 "ix86_split_long_move (operands); DONE;") 2693 2694(define_insn "*swapdf" 2695 [(set (match_operand:DF 0 "fp_register_operand" "+f") 2696 (match_operand:DF 1 "fp_register_operand" "+f")) 2697 (set (match_dup 1) 2698 (match_dup 0))] 2699 "reload_completed || TARGET_80387" 2700{ 2701 if (STACK_TOP_P (operands[0])) 2702 return "fxch\t%1"; 2703 else 2704 return "fxch\t%0"; 2705} 2706 [(set_attr "type" "fxch") 2707 (set_attr "mode" "DF")]) 2708 2709(define_expand "movxf" 2710 [(set (match_operand:XF 0 "nonimmediate_operand" "") 2711 (match_operand:XF 1 "general_operand" ""))] 2712 "" 2713 "ix86_expand_move (XFmode, operands); DONE;") 2714 2715;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. 2716;; Size of pushdf using integer instructions is 3+3*memory operand size 2717;; Pushing using integer instructions is longer except for constants 2718;; and direct memory references. 2719;; (assuming that any given constant is pushed only once, but this ought to be 2720;; handled elsewhere). 2721 2722(define_insn "*pushxf_nointeger" 2723 [(set (match_operand:XF 0 "push_operand" "=X,X,X") 2724 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))] 2725 "optimize_size" 2726{ 2727 /* This insn should be already split before reg-stack. */ 2728 gcc_unreachable (); 2729} 2730 [(set_attr "type" "multi") 2731 (set_attr "unit" "i387,*,*") 2732 (set_attr "mode" "XF,SI,SI")]) 2733 2734(define_insn "*pushxf_integer" 2735 [(set (match_operand:XF 0 "push_operand" "=<,<") 2736 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))] 2737 "!optimize_size" 2738{ 2739 /* This insn should be already split before reg-stack. */ 2740 gcc_unreachable (); 2741} 2742 [(set_attr "type" "multi") 2743 (set_attr "unit" "i387,*") 2744 (set_attr "mode" "XF,SI")]) 2745 2746(define_split 2747 [(set (match_operand 0 "push_operand" "") 2748 (match_operand 1 "general_operand" ""))] 2749 "reload_completed 2750 && (GET_MODE (operands[0]) == XFmode 2751 || GET_MODE (operands[0]) == DFmode) 2752 && !ANY_FP_REG_P (operands[1])" 2753 [(const_int 0)] 2754 "ix86_split_long_move (operands); DONE;") 2755 2756(define_split 2757 [(set (match_operand:XF 0 "push_operand" "") 2758 (match_operand:XF 1 "any_fp_register_operand" ""))] 2759 "!TARGET_64BIT" 2760 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2))) 2761 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))] 2762 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 2763 2764(define_split 2765 [(set (match_operand:XF 0 "push_operand" "") 2766 (match_operand:XF 1 "any_fp_register_operand" ""))] 2767 "TARGET_64BIT" 2768 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2))) 2769 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))] 2770 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 2771 2772;; Do not use integer registers when optimizing for size 2773(define_insn "*movxf_nointeger" 2774 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o") 2775 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))] 2776 "optimize_size 2777 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2778 && (reload_in_progress || reload_completed 2779 || GET_CODE (operands[1]) != CONST_DOUBLE 2780 || memory_operand (operands[0], XFmode))" 2781{ 2782 switch (which_alternative) 2783 { 2784 case 0: 2785 return output_387_reg_move (insn, operands); 2786 2787 case 1: 2788 /* There is no non-popping store to memory for XFmode. So if 2789 we need one, follow the store with a load. */ 2790 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2791 return "fstp%z0\t%y0\;fld%z0\t%y0"; 2792 else 2793 return "fstp%z0\t%y0"; 2794 2795 case 2: 2796 return standard_80387_constant_opcode (operands[1]); 2797 2798 case 3: case 4: 2799 return "#"; 2800 default: 2801 gcc_unreachable (); 2802 } 2803} 2804 [(set_attr "type" "fmov,fmov,fmov,multi,multi") 2805 (set_attr "mode" "XF,XF,XF,SI,SI")]) 2806 2807(define_insn "*movxf_integer" 2808 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o") 2809 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))] 2810 "!optimize_size 2811 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2812 && (reload_in_progress || reload_completed 2813 || GET_CODE (operands[1]) != CONST_DOUBLE 2814 || memory_operand (operands[0], XFmode))" 2815{ 2816 switch (which_alternative) 2817 { 2818 case 0: 2819 return output_387_reg_move (insn, operands); 2820 2821 case 1: 2822 /* There is no non-popping store to memory for XFmode. So if 2823 we need one, follow the store with a load. */ 2824 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2825 return "fstp%z0\t%y0\;fld%z0\t%y0"; 2826 else 2827 return "fstp%z0\t%y0"; 2828 2829 case 2: 2830 return standard_80387_constant_opcode (operands[1]); 2831 2832 case 3: case 4: 2833 return "#"; 2834 2835 default: 2836 gcc_unreachable (); 2837 } 2838} 2839 [(set_attr "type" "fmov,fmov,fmov,multi,multi") 2840 (set_attr "mode" "XF,XF,XF,SI,SI")]) 2841 2842(define_split 2843 [(set (match_operand 0 "nonimmediate_operand" "") 2844 (match_operand 1 "general_operand" ""))] 2845 "reload_completed 2846 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2847 && GET_MODE (operands[0]) == XFmode 2848 && ! (ANY_FP_REG_P (operands[0]) || 2849 (GET_CODE (operands[0]) == SUBREG 2850 && ANY_FP_REG_P (SUBREG_REG (operands[0])))) 2851 && ! (ANY_FP_REG_P (operands[1]) || 2852 (GET_CODE (operands[1]) == SUBREG 2853 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))" 2854 [(const_int 0)] 2855 "ix86_split_long_move (operands); DONE;") 2856 2857(define_split 2858 [(set (match_operand 0 "register_operand" "") 2859 (match_operand 1 "memory_operand" ""))] 2860 "reload_completed 2861 && GET_CODE (operands[1]) == MEM 2862 && (GET_MODE (operands[0]) == XFmode 2863 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode) 2864 && constant_pool_reference_p (operands[1])" 2865 [(set (match_dup 0) (match_dup 1))] 2866{ 2867 rtx c = avoid_constant_pool_reference (operands[1]); 2868 rtx r = operands[0]; 2869 2870 if (GET_CODE (r) == SUBREG) 2871 r = SUBREG_REG (r); 2872 2873 if (SSE_REG_P (r)) 2874 { 2875 if (!standard_sse_constant_p (c)) 2876 FAIL; 2877 } 2878 else if (FP_REG_P (r)) 2879 { 2880 if (!standard_80387_constant_p (c)) 2881 FAIL; 2882 } 2883 else if (MMX_REG_P (r)) 2884 FAIL; 2885 2886 operands[1] = c; 2887}) 2888 2889(define_insn "swapxf" 2890 [(set (match_operand:XF 0 "register_operand" "+f") 2891 (match_operand:XF 1 "register_operand" "+f")) 2892 (set (match_dup 1) 2893 (match_dup 0))] 2894 "TARGET_80387" 2895{ 2896 if (STACK_TOP_P (operands[0])) 2897 return "fxch\t%1"; 2898 else 2899 return "fxch\t%0"; 2900} 2901 [(set_attr "type" "fxch") 2902 (set_attr "mode" "XF")]) 2903 2904(define_expand "movtf" 2905 [(set (match_operand:TF 0 "nonimmediate_operand" "") 2906 (match_operand:TF 1 "nonimmediate_operand" ""))] 2907 "TARGET_64BIT" 2908{ 2909 ix86_expand_move (TFmode, operands); 2910 DONE; 2911}) 2912 2913(define_insn "*movtf_internal" 2914 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm") 2915 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))] 2916 "TARGET_64BIT 2917 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 2918{ 2919 switch (which_alternative) 2920 { 2921 case 0: 2922 case 1: 2923 return "#"; 2924 case 2: 2925 if (get_attr_mode (insn) == MODE_V4SF) 2926 return "xorps\t%0, %0"; 2927 else 2928 return "pxor\t%0, %0"; 2929 case 3: 2930 case 4: 2931 if (get_attr_mode (insn) == MODE_V4SF) 2932 return "movaps\t{%1, %0|%0, %1}"; 2933 else 2934 return "movdqa\t{%1, %0|%0, %1}"; 2935 default: 2936 gcc_unreachable (); 2937 } 2938} 2939 [(set_attr "type" "*,*,ssemov,ssemov,ssemov") 2940 (set (attr "mode") 2941 (cond [(eq_attr "alternative" "2,3") 2942 (if_then_else 2943 (ne (symbol_ref "optimize_size") 2944 (const_int 0)) 2945 (const_string "V4SF") 2946 (const_string "TI")) 2947 (eq_attr "alternative" "4") 2948 (if_then_else 2949 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") 2950 (const_int 0)) 2951 (ne (symbol_ref "optimize_size") 2952 (const_int 0))) 2953 (const_string "V4SF") 2954 (const_string "TI"))] 2955 (const_string "DI")))]) 2956 2957(define_split 2958 [(set (match_operand:TF 0 "nonimmediate_operand" "") 2959 (match_operand:TF 1 "general_operand" ""))] 2960 "reload_completed && !SSE_REG_P (operands[0]) 2961 && !SSE_REG_P (operands[1])" 2962 [(const_int 0)] 2963 "ix86_split_long_move (operands); DONE;") 2964 2965;; Zero extension instructions 2966 2967(define_expand "zero_extendhisi2" 2968 [(set (match_operand:SI 0 "register_operand" "") 2969 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 2970 "" 2971{ 2972 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) 2973 { 2974 operands[1] = force_reg (HImode, operands[1]); 2975 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1])); 2976 DONE; 2977 } 2978}) 2979 2980(define_insn "zero_extendhisi2_and" 2981 [(set (match_operand:SI 0 "register_operand" "=r") 2982 (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))) 2983 (clobber (reg:CC FLAGS_REG))] 2984 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 2985 "#" 2986 [(set_attr "type" "alu1") 2987 (set_attr "mode" "SI")]) 2988 2989(define_split 2990 [(set (match_operand:SI 0 "register_operand" "") 2991 (zero_extend:SI (match_operand:HI 1 "register_operand" ""))) 2992 (clobber (reg:CC FLAGS_REG))] 2993 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 2994 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535))) 2995 (clobber (reg:CC FLAGS_REG))])] 2996 "") 2997 2998(define_insn "*zero_extendhisi2_movzwl" 2999 [(set (match_operand:SI 0 "register_operand" "=r") 3000 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3001 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" 3002 "movz{wl|x}\t{%1, %0|%0, %1}" 3003 [(set_attr "type" "imovx") 3004 (set_attr "mode" "SI")]) 3005 3006(define_expand "zero_extendqihi2" 3007 [(parallel 3008 [(set (match_operand:HI 0 "register_operand" "") 3009 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) 3010 (clobber (reg:CC FLAGS_REG))])] 3011 "" 3012 "") 3013 3014(define_insn "*zero_extendqihi2_and" 3015 [(set (match_operand:HI 0 "register_operand" "=r,?&q") 3016 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) 3017 (clobber (reg:CC FLAGS_REG))] 3018 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 3019 "#" 3020 [(set_attr "type" "alu1") 3021 (set_attr "mode" "HI")]) 3022 3023(define_insn "*zero_extendqihi2_movzbw_and" 3024 [(set (match_operand:HI 0 "register_operand" "=r,r") 3025 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) 3026 (clobber (reg:CC FLAGS_REG))] 3027 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" 3028 "#" 3029 [(set_attr "type" "imovx,alu1") 3030 (set_attr "mode" "HI")]) 3031 3032(define_insn "*zero_extendqihi2_movzbw" 3033 [(set (match_operand:HI 0 "register_operand" "=r") 3034 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3035 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed" 3036 "movz{bw|x}\t{%1, %0|%0, %1}" 3037 [(set_attr "type" "imovx") 3038 (set_attr "mode" "HI")]) 3039 3040;; For the movzbw case strip only the clobber 3041(define_split 3042 [(set (match_operand:HI 0 "register_operand" "") 3043 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) 3044 (clobber (reg:CC FLAGS_REG))] 3045 "reload_completed 3046 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) 3047 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" 3048 [(set (match_operand:HI 0 "register_operand" "") 3049 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]) 3050 3051;; When source and destination does not overlap, clear destination 3052;; first and then do the movb 3053(define_split 3054 [(set (match_operand:HI 0 "register_operand" "") 3055 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) 3056 (clobber (reg:CC FLAGS_REG))] 3057 "reload_completed 3058 && ANY_QI_REG_P (operands[0]) 3059 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) 3060 && !reg_overlap_mentioned_p (operands[0], operands[1])" 3061 [(set (match_dup 0) (const_int 0)) 3062 (set (strict_low_part (match_dup 2)) (match_dup 1))] 3063 "operands[2] = gen_lowpart (QImode, operands[0]);") 3064 3065;; Rest is handled by single and. 3066(define_split 3067 [(set (match_operand:HI 0 "register_operand" "") 3068 (zero_extend:HI (match_operand:QI 1 "register_operand" ""))) 3069 (clobber (reg:CC FLAGS_REG))] 3070 "reload_completed 3071 && true_regnum (operands[0]) == true_regnum (operands[1])" 3072 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255))) 3073 (clobber (reg:CC FLAGS_REG))])] 3074 "") 3075 3076(define_expand "zero_extendqisi2" 3077 [(parallel 3078 [(set (match_operand:SI 0 "register_operand" "") 3079 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) 3080 (clobber (reg:CC FLAGS_REG))])] 3081 "" 3082 "") 3083 3084(define_insn "*zero_extendqisi2_and" 3085 [(set (match_operand:SI 0 "register_operand" "=r,?&q") 3086 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) 3087 (clobber (reg:CC FLAGS_REG))] 3088 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 3089 "#" 3090 [(set_attr "type" "alu1") 3091 (set_attr "mode" "SI")]) 3092 3093(define_insn "*zero_extendqisi2_movzbw_and" 3094 [(set (match_operand:SI 0 "register_operand" "=r,r") 3095 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) 3096 (clobber (reg:CC FLAGS_REG))] 3097 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" 3098 "#" 3099 [(set_attr "type" "imovx,alu1") 3100 (set_attr "mode" "SI")]) 3101 3102(define_insn "*zero_extendqisi2_movzbw" 3103 [(set (match_operand:SI 0 "register_operand" "=r") 3104 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3105 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed" 3106 "movz{bl|x}\t{%1, %0|%0, %1}" 3107 [(set_attr "type" "imovx") 3108 (set_attr "mode" "SI")]) 3109 3110;; For the movzbl case strip only the clobber 3111(define_split 3112 [(set (match_operand:SI 0 "register_operand" "") 3113 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) 3114 (clobber (reg:CC FLAGS_REG))] 3115 "reload_completed 3116 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) 3117 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" 3118 [(set (match_dup 0) 3119 (zero_extend:SI (match_dup 1)))]) 3120 3121;; When source and destination does not overlap, clear destination 3122;; first and then do the movb 3123(define_split 3124 [(set (match_operand:SI 0 "register_operand" "") 3125 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) 3126 (clobber (reg:CC FLAGS_REG))] 3127 "reload_completed 3128 && ANY_QI_REG_P (operands[0]) 3129 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM) 3130 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) 3131 && !reg_overlap_mentioned_p (operands[0], operands[1])" 3132 [(set (match_dup 0) (const_int 0)) 3133 (set (strict_low_part (match_dup 2)) (match_dup 1))] 3134 "operands[2] = gen_lowpart (QImode, operands[0]);") 3135 3136;; Rest is handled by single and. 3137(define_split 3138 [(set (match_operand:SI 0 "register_operand" "") 3139 (zero_extend:SI (match_operand:QI 1 "register_operand" ""))) 3140 (clobber (reg:CC FLAGS_REG))] 3141 "reload_completed 3142 && true_regnum (operands[0]) == true_regnum (operands[1])" 3143 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255))) 3144 (clobber (reg:CC FLAGS_REG))])] 3145 "") 3146 3147;; %%% Kill me once multi-word ops are sane. 3148(define_expand "zero_extendsidi2" 3149 [(set (match_operand:DI 0 "register_operand" "=r") 3150 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))] 3151 "" 3152 "if (!TARGET_64BIT) 3153 { 3154 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1])); 3155 DONE; 3156 } 3157 ") 3158 3159(define_insn "zero_extendsidi2_32" 3160 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y") 3161 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm"))) 3162 (clobber (reg:CC FLAGS_REG))] 3163 "!TARGET_64BIT" 3164 "@ 3165 # 3166 # 3167 # 3168 movd\t{%1, %0|%0, %1} 3169 movd\t{%1, %0|%0, %1}" 3170 [(set_attr "mode" "SI,SI,SI,DI,TI") 3171 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")]) 3172 3173(define_insn "zero_extendsidi2_rex64" 3174 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y") 3175 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))] 3176 "TARGET_64BIT" 3177 "@ 3178 mov\t{%k1, %k0|%k0, %k1} 3179 # 3180 movd\t{%1, %0|%0, %1} 3181 movd\t{%1, %0|%0, %1}" 3182 [(set_attr "type" "imovx,imov,mmxmov,ssemov") 3183 (set_attr "mode" "SI,DI,SI,SI")]) 3184 3185(define_split 3186 [(set (match_operand:DI 0 "memory_operand" "") 3187 (zero_extend:DI (match_dup 0)))] 3188 "TARGET_64BIT" 3189 [(set (match_dup 4) (const_int 0))] 3190 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3191 3192(define_split 3193 [(set (match_operand:DI 0 "register_operand" "") 3194 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) 3195 (clobber (reg:CC FLAGS_REG))] 3196 "!TARGET_64BIT && reload_completed 3197 && true_regnum (operands[0]) == true_regnum (operands[1])" 3198 [(set (match_dup 4) (const_int 0))] 3199 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3200 3201(define_split 3202 [(set (match_operand:DI 0 "nonimmediate_operand" "") 3203 (zero_extend:DI (match_operand:SI 1 "general_operand" ""))) 3204 (clobber (reg:CC FLAGS_REG))] 3205 "!TARGET_64BIT && reload_completed 3206 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])" 3207 [(set (match_dup 3) (match_dup 1)) 3208 (set (match_dup 4) (const_int 0))] 3209 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3210 3211(define_insn "zero_extendhidi2" 3212 [(set (match_operand:DI 0 "register_operand" "=r") 3213 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3214 "TARGET_64BIT" 3215 "movz{wl|x}\t{%1, %k0|%k0, %1}" 3216 [(set_attr "type" "imovx") 3217 (set_attr "mode" "DI")]) 3218 3219(define_insn "zero_extendqidi2" 3220 [(set (match_operand:DI 0 "register_operand" "=r") 3221 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))] 3222 "TARGET_64BIT" 3223 "movz{bl|x}\t{%1, %k0|%k0, %1}" 3224 [(set_attr "type" "imovx") 3225 (set_attr "mode" "DI")]) 3226 3227;; Sign extension instructions 3228 3229(define_expand "extendsidi2" 3230 [(parallel [(set (match_operand:DI 0 "register_operand" "") 3231 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3232 (clobber (reg:CC FLAGS_REG)) 3233 (clobber (match_scratch:SI 2 ""))])] 3234 "" 3235{ 3236 if (TARGET_64BIT) 3237 { 3238 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1])); 3239 DONE; 3240 } 3241}) 3242 3243(define_insn "*extendsidi2_1" 3244 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o") 3245 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r"))) 3246 (clobber (reg:CC FLAGS_REG)) 3247 (clobber (match_scratch:SI 2 "=X,X,X,&r"))] 3248 "!TARGET_64BIT" 3249 "#") 3250 3251(define_insn "extendsidi2_rex64" 3252 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3253 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))] 3254 "TARGET_64BIT" 3255 "@ 3256 {cltq|cdqe} 3257 movs{lq|x}\t{%1,%0|%0, %1}" 3258 [(set_attr "type" "imovx") 3259 (set_attr "mode" "DI") 3260 (set_attr "prefix_0f" "0") 3261 (set_attr "modrm" "0,1")]) 3262 3263(define_insn "extendhidi2" 3264 [(set (match_operand:DI 0 "register_operand" "=r") 3265 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3266 "TARGET_64BIT" 3267 "movs{wq|x}\t{%1,%0|%0, %1}" 3268 [(set_attr "type" "imovx") 3269 (set_attr "mode" "DI")]) 3270 3271(define_insn "extendqidi2" 3272 [(set (match_operand:DI 0 "register_operand" "=r") 3273 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3274 "TARGET_64BIT" 3275 "movs{bq|x}\t{%1,%0|%0, %1}" 3276 [(set_attr "type" "imovx") 3277 (set_attr "mode" "DI")]) 3278 3279;; Extend to memory case when source register does die. 3280(define_split 3281 [(set (match_operand:DI 0 "memory_operand" "") 3282 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3283 (clobber (reg:CC FLAGS_REG)) 3284 (clobber (match_operand:SI 2 "register_operand" ""))] 3285 "(reload_completed 3286 && dead_or_set_p (insn, operands[1]) 3287 && !reg_mentioned_p (operands[1], operands[0]))" 3288 [(set (match_dup 3) (match_dup 1)) 3289 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) 3290 (clobber (reg:CC FLAGS_REG))]) 3291 (set (match_dup 4) (match_dup 1))] 3292 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3293 3294;; Extend to memory case when source register does not die. 3295(define_split 3296 [(set (match_operand:DI 0 "memory_operand" "") 3297 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3298 (clobber (reg:CC FLAGS_REG)) 3299 (clobber (match_operand:SI 2 "register_operand" ""))] 3300 "reload_completed" 3301 [(const_int 0)] 3302{ 3303 split_di (&operands[0], 1, &operands[3], &operands[4]); 3304 3305 emit_move_insn (operands[3], operands[1]); 3306 3307 /* Generate a cltd if possible and doing so it profitable. */ 3308 if (true_regnum (operands[1]) == 0 3309 && true_regnum (operands[2]) == 1 3310 && (optimize_size || TARGET_USE_CLTD)) 3311 { 3312 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31))); 3313 } 3314 else 3315 { 3316 emit_move_insn (operands[2], operands[1]); 3317 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31))); 3318 } 3319 emit_move_insn (operands[4], operands[2]); 3320 DONE; 3321}) 3322 3323;; Extend to register case. Optimize case where source and destination 3324;; registers match and cases where we can use cltd. 3325(define_split 3326 [(set (match_operand:DI 0 "register_operand" "") 3327 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3328 (clobber (reg:CC FLAGS_REG)) 3329 (clobber (match_scratch:SI 2 ""))] 3330 "reload_completed" 3331 [(const_int 0)] 3332{ 3333 split_di (&operands[0], 1, &operands[3], &operands[4]); 3334 3335 if (true_regnum (operands[3]) != true_regnum (operands[1])) 3336 emit_move_insn (operands[3], operands[1]); 3337 3338 /* Generate a cltd if possible and doing so it profitable. */ 3339 if (true_regnum (operands[3]) == 0 3340 && (optimize_size || TARGET_USE_CLTD)) 3341 { 3342 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31))); 3343 DONE; 3344 } 3345 3346 if (true_regnum (operands[4]) != true_regnum (operands[1])) 3347 emit_move_insn (operands[4], operands[1]); 3348 3349 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31))); 3350 DONE; 3351}) 3352 3353(define_insn "extendhisi2" 3354 [(set (match_operand:SI 0 "register_operand" "=*a,r") 3355 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))] 3356 "" 3357{ 3358 switch (get_attr_prefix_0f (insn)) 3359 { 3360 case 0: 3361 return "{cwtl|cwde}"; 3362 default: 3363 return "movs{wl|x}\t{%1,%0|%0, %1}"; 3364 } 3365} 3366 [(set_attr "type" "imovx") 3367 (set_attr "mode" "SI") 3368 (set (attr "prefix_0f") 3369 ;; movsx is short decodable while cwtl is vector decoded. 3370 (if_then_else (and (eq_attr "cpu" "!k6") 3371 (eq_attr "alternative" "0")) 3372 (const_string "0") 3373 (const_string "1"))) 3374 (set (attr "modrm") 3375 (if_then_else (eq_attr "prefix_0f" "0") 3376 (const_string "0") 3377 (const_string "1")))]) 3378 3379(define_insn "*extendhisi2_zext" 3380 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3381 (zero_extend:DI 3382 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))] 3383 "TARGET_64BIT" 3384{ 3385 switch (get_attr_prefix_0f (insn)) 3386 { 3387 case 0: 3388 return "{cwtl|cwde}"; 3389 default: 3390 return "movs{wl|x}\t{%1,%k0|%k0, %1}"; 3391 } 3392} 3393 [(set_attr "type" "imovx") 3394 (set_attr "mode" "SI") 3395 (set (attr "prefix_0f") 3396 ;; movsx is short decodable while cwtl is vector decoded. 3397 (if_then_else (and (eq_attr "cpu" "!k6") 3398 (eq_attr "alternative" "0")) 3399 (const_string "0") 3400 (const_string "1"))) 3401 (set (attr "modrm") 3402 (if_then_else (eq_attr "prefix_0f" "0") 3403 (const_string "0") 3404 (const_string "1")))]) 3405 3406(define_insn "extendqihi2" 3407 [(set (match_operand:HI 0 "register_operand" "=*a,r") 3408 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))] 3409 "" 3410{ 3411 switch (get_attr_prefix_0f (insn)) 3412 { 3413 case 0: 3414 return "{cbtw|cbw}"; 3415 default: 3416 return "movs{bw|x}\t{%1,%0|%0, %1}"; 3417 } 3418} 3419 [(set_attr "type" "imovx") 3420 (set_attr "mode" "HI") 3421 (set (attr "prefix_0f") 3422 ;; movsx is short decodable while cwtl is vector decoded. 3423 (if_then_else (and (eq_attr "cpu" "!k6") 3424 (eq_attr "alternative" "0")) 3425 (const_string "0") 3426 (const_string "1"))) 3427 (set (attr "modrm") 3428 (if_then_else (eq_attr "prefix_0f" "0") 3429 (const_string "0") 3430 (const_string "1")))]) 3431 3432(define_insn "extendqisi2" 3433 [(set (match_operand:SI 0 "register_operand" "=r") 3434 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3435 "" 3436 "movs{bl|x}\t{%1,%0|%0, %1}" 3437 [(set_attr "type" "imovx") 3438 (set_attr "mode" "SI")]) 3439 3440(define_insn "*extendqisi2_zext" 3441 [(set (match_operand:DI 0 "register_operand" "=r") 3442 (zero_extend:DI 3443 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))] 3444 "TARGET_64BIT" 3445 "movs{bl|x}\t{%1,%k0|%k0, %1}" 3446 [(set_attr "type" "imovx") 3447 (set_attr "mode" "SI")]) 3448 3449;; Conversions between float and double. 3450 3451;; These are all no-ops in the model used for the 80387. So just 3452;; emit moves. 3453 3454;; %%% Kill these when call knows how to work out a DFmode push earlier. 3455(define_insn "*dummy_extendsfdf2" 3456 [(set (match_operand:DF 0 "push_operand" "=<") 3457 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))] 3458 "0" 3459 "#") 3460 3461(define_split 3462 [(set (match_operand:DF 0 "push_operand" "") 3463 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))] 3464 "!TARGET_64BIT" 3465 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 3466 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))]) 3467 3468(define_split 3469 [(set (match_operand:DF 0 "push_operand" "") 3470 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))] 3471 "TARGET_64BIT" 3472 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 3473 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))]) 3474 3475(define_insn "*dummy_extendsfxf2" 3476 [(set (match_operand:XF 0 "push_operand" "=<") 3477 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))] 3478 "0" 3479 "#") 3480 3481(define_split 3482 [(set (match_operand:XF 0 "push_operand" "") 3483 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))] 3484 "" 3485 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2))) 3486 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))] 3487 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3488 3489(define_split 3490 [(set (match_operand:XF 0 "push_operand" "") 3491 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))] 3492 "TARGET_64BIT" 3493 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2))) 3494 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))] 3495 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3496 3497(define_split 3498 [(set (match_operand:XF 0 "push_operand" "") 3499 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))] 3500 "" 3501 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2))) 3502 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))] 3503 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3504 3505(define_split 3506 [(set (match_operand:XF 0 "push_operand" "") 3507 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))] 3508 "TARGET_64BIT" 3509 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2))) 3510 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))] 3511 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3512 3513(define_expand "extendsfdf2" 3514 [(set (match_operand:DF 0 "nonimmediate_operand" "") 3515 (float_extend:DF (match_operand:SF 1 "general_operand" "")))] 3516 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 3517{ 3518 /* ??? Needed for compress_float_constant since all fp constants 3519 are LEGITIMATE_CONSTANT_P. */ 3520 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3521 operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 3522 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 3523 operands[1] = force_reg (SFmode, operands[1]); 3524}) 3525 3526(define_insn "*extendsfdf2_mixed" 3527 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f") 3528 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))] 3529 "TARGET_SSE2 && TARGET_MIX_SSE_I387 3530 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3531{ 3532 switch (which_alternative) 3533 { 3534 case 0: 3535 return output_387_reg_move (insn, operands); 3536 3537 case 1: 3538 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3539 return "fstp%z0\t%y0"; 3540 else 3541 return "fst%z0\t%y0"; 3542 3543 case 2: 3544 return "cvtss2sd\t{%1, %0|%0, %1}"; 3545 3546 default: 3547 gcc_unreachable (); 3548 } 3549} 3550 [(set_attr "type" "fmov,fmov,ssecvt") 3551 (set_attr "mode" "SF,XF,DF")]) 3552 3553(define_insn "*extendsfdf2_sse" 3554 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y") 3555 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))] 3556 "TARGET_SSE2 && TARGET_SSE_MATH 3557 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3558 "cvtss2sd\t{%1, %0|%0, %1}" 3559 [(set_attr "type" "ssecvt") 3560 (set_attr "mode" "DF")]) 3561 3562(define_insn "*extendsfdf2_i387" 3563 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m") 3564 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 3565 "TARGET_80387 3566 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3567{ 3568 switch (which_alternative) 3569 { 3570 case 0: 3571 return output_387_reg_move (insn, operands); 3572 3573 case 1: 3574 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3575 return "fstp%z0\t%y0"; 3576 else 3577 return "fst%z0\t%y0"; 3578 3579 default: 3580 gcc_unreachable (); 3581 } 3582} 3583 [(set_attr "type" "fmov") 3584 (set_attr "mode" "SF,XF")]) 3585 3586(define_expand "extendsfxf2" 3587 [(set (match_operand:XF 0 "nonimmediate_operand" "") 3588 (float_extend:XF (match_operand:SF 1 "general_operand" "")))] 3589 "TARGET_80387" 3590{ 3591 /* ??? Needed for compress_float_constant since all fp constants 3592 are LEGITIMATE_CONSTANT_P. */ 3593 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3594 operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 3595 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 3596 operands[1] = force_reg (SFmode, operands[1]); 3597}) 3598 3599(define_insn "*extendsfxf2_i387" 3600 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 3601 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 3602 "TARGET_80387 3603 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3604{ 3605 switch (which_alternative) 3606 { 3607 case 0: 3608 return output_387_reg_move (insn, operands); 3609 3610 case 1: 3611 /* There is no non-popping store to memory for XFmode. So if 3612 we need one, follow the store with a load. */ 3613 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3614 return "fstp%z0\t%y0"; 3615 else 3616 return "fstp%z0\t%y0\n\tfld%z0\t%y0"; 3617 3618 default: 3619 gcc_unreachable (); 3620 } 3621} 3622 [(set_attr "type" "fmov") 3623 (set_attr "mode" "SF,XF")]) 3624 3625(define_expand "extenddfxf2" 3626 [(set (match_operand:XF 0 "nonimmediate_operand" "") 3627 (float_extend:XF (match_operand:DF 1 "general_operand" "")))] 3628 "TARGET_80387" 3629{ 3630 /* ??? Needed for compress_float_constant since all fp constants 3631 are LEGITIMATE_CONSTANT_P. */ 3632 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3633 operands[1] = validize_mem (force_const_mem (DFmode, operands[1])); 3634 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 3635 operands[1] = force_reg (DFmode, operands[1]); 3636}) 3637 3638(define_insn "*extenddfxf2_i387" 3639 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 3640 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))] 3641 "TARGET_80387 3642 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3643{ 3644 switch (which_alternative) 3645 { 3646 case 0: 3647 return output_387_reg_move (insn, operands); 3648 3649 case 1: 3650 /* There is no non-popping store to memory for XFmode. So if 3651 we need one, follow the store with a load. */ 3652 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3653 return "fstp%z0\t%y0\n\tfld%z0\t%y0"; 3654 else 3655 return "fstp%z0\t%y0"; 3656 3657 default: 3658 gcc_unreachable (); 3659 } 3660} 3661 [(set_attr "type" "fmov") 3662 (set_attr "mode" "DF,XF")]) 3663 3664;; %%% This seems bad bad news. 3665;; This cannot output into an f-reg because there is no way to be sure 3666;; of truncating in that case. Otherwise this is just like a simple move 3667;; insn. So we pretend we can output to a reg in order to get better 3668;; register preferencing, but we really use a stack slot. 3669 3670;; Conversion from DFmode to SFmode. 3671 3672(define_expand "truncdfsf2" 3673 [(set (match_operand:SF 0 "nonimmediate_operand" "") 3674 (float_truncate:SF 3675 (match_operand:DF 1 "nonimmediate_operand" "")))] 3676 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 3677{ 3678 if (MEM_P (operands[0]) && MEM_P (operands[1])) 3679 operands[1] = force_reg (DFmode, operands[1]); 3680 3681 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387) 3682 ; 3683 else if (flag_unsafe_math_optimizations) 3684 ; 3685 else 3686 { 3687 rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL); 3688 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp)); 3689 DONE; 3690 } 3691}) 3692 3693(define_expand "truncdfsf2_with_temp" 3694 [(parallel [(set (match_operand:SF 0 "" "") 3695 (float_truncate:SF (match_operand:DF 1 "" ""))) 3696 (clobber (match_operand:SF 2 "" ""))])] 3697 "") 3698 3699(define_insn "*truncdfsf_fast_mixed" 3700 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y") 3701 (float_truncate:SF 3702 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))] 3703 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations" 3704{ 3705 switch (which_alternative) 3706 { 3707 case 0: 3708 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3709 return "fstp%z0\t%y0"; 3710 else 3711 return "fst%z0\t%y0"; 3712 case 1: 3713 return output_387_reg_move (insn, operands); 3714 case 2: 3715 return "cvtsd2ss\t{%1, %0|%0, %1}"; 3716 default: 3717 gcc_unreachable (); 3718 } 3719} 3720 [(set_attr "type" "fmov,fmov,ssecvt") 3721 (set_attr "mode" "SF")]) 3722 3723;; Yes, this one doesn't depend on flag_unsafe_math_optimizations, 3724;; because nothing we do here is unsafe. 3725(define_insn "*truncdfsf_fast_sse" 3726 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y") 3727 (float_truncate:SF 3728 (match_operand:DF 1 "nonimmediate_operand" "Ym")))] 3729 "TARGET_SSE2 && TARGET_SSE_MATH" 3730 "cvtsd2ss\t{%1, %0|%0, %1}" 3731 [(set_attr "type" "ssecvt") 3732 (set_attr "mode" "SF")]) 3733 3734(define_insn "*truncdfsf_fast_i387" 3735 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm") 3736 (float_truncate:SF 3737 (match_operand:DF 1 "nonimmediate_operand" "f")))] 3738 "TARGET_80387 && flag_unsafe_math_optimizations" 3739 "* return output_387_reg_move (insn, operands);" 3740 [(set_attr "type" "fmov") 3741 (set_attr "mode" "SF")]) 3742 3743(define_insn "*truncdfsf_mixed" 3744 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y") 3745 (float_truncate:SF 3746 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym"))) 3747 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))] 3748 "TARGET_MIX_SSE_I387" 3749{ 3750 switch (which_alternative) 3751 { 3752 case 0: 3753 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3754 return "fstp%z0\t%y0"; 3755 else 3756 return "fst%z0\t%y0"; 3757 case 1: 3758 return "#"; 3759 case 2: 3760 return "cvtsd2ss\t{%1, %0|%0, %1}"; 3761 default: 3762 gcc_unreachable (); 3763 } 3764} 3765 [(set_attr "type" "fmov,multi,ssecvt") 3766 (set_attr "unit" "*,i387,*") 3767 (set_attr "mode" "SF")]) 3768 3769(define_insn "*truncdfsf_i387" 3770 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r") 3771 (float_truncate:SF 3772 (match_operand:DF 1 "nonimmediate_operand" "f,f"))) 3773 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))] 3774 "TARGET_80387" 3775{ 3776 switch (which_alternative) 3777 { 3778 case 0: 3779 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3780 return "fstp%z0\t%y0"; 3781 else 3782 return "fst%z0\t%y0"; 3783 case 1: 3784 return "#"; 3785 default: 3786 gcc_unreachable (); 3787 } 3788} 3789 [(set_attr "type" "fmov,multi") 3790 (set_attr "unit" "*,i387") 3791 (set_attr "mode" "SF")]) 3792 3793(define_insn "*truncdfsf2_i387_1" 3794 [(set (match_operand:SF 0 "memory_operand" "=m") 3795 (float_truncate:SF 3796 (match_operand:DF 1 "register_operand" "f")))] 3797 "TARGET_80387 3798 && !(TARGET_SSE2 && TARGET_SSE_MATH) 3799 && !TARGET_MIX_SSE_I387" 3800{ 3801 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3802 return "fstp%z0\t%y0"; 3803 else 3804 return "fst%z0\t%y0"; 3805} 3806 [(set_attr "type" "fmov") 3807 (set_attr "mode" "SF")]) 3808 3809(define_split 3810 [(set (match_operand:SF 0 "register_operand" "") 3811 (float_truncate:SF 3812 (match_operand:DF 1 "fp_register_operand" ""))) 3813 (clobber (match_operand 2 "" ""))] 3814 "reload_completed" 3815 [(set (match_dup 2) (match_dup 1)) 3816 (set (match_dup 0) (match_dup 2))] 3817{ 3818 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1])); 3819}) 3820 3821;; Conversion from XFmode to SFmode. 3822 3823(define_expand "truncxfsf2" 3824 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") 3825 (float_truncate:SF 3826 (match_operand:XF 1 "register_operand" ""))) 3827 (clobber (match_dup 2))])] 3828 "TARGET_80387" 3829{ 3830 if (flag_unsafe_math_optimizations) 3831 { 3832 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode); 3833 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1])); 3834 if (reg != operands[0]) 3835 emit_move_insn (operands[0], reg); 3836 DONE; 3837 } 3838 else 3839 operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL); 3840}) 3841 3842(define_insn "*truncxfsf2_mixed" 3843 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf") 3844 (float_truncate:SF 3845 (match_operand:XF 1 "register_operand" "f,f,f,f"))) 3846 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))] 3847 "TARGET_MIX_SSE_I387" 3848{ 3849 gcc_assert (!which_alternative); 3850 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3851 return "fstp%z0\t%y0"; 3852 else 3853 return "fst%z0\t%y0"; 3854} 3855 [(set_attr "type" "fmov,multi,multi,multi") 3856 (set_attr "unit" "*,i387,i387,i387") 3857 (set_attr "mode" "SF")]) 3858 3859(define_insn "truncxfsf2_i387_noop" 3860 [(set (match_operand:SF 0 "register_operand" "=f") 3861 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))] 3862 "TARGET_80387 && flag_unsafe_math_optimizations" 3863{ 3864 return output_387_reg_move (insn, operands); 3865} 3866 [(set_attr "type" "fmov") 3867 (set_attr "mode" "SF")]) 3868 3869(define_insn "*truncxfsf2_i387" 3870 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f") 3871 (float_truncate:SF 3872 (match_operand:XF 1 "register_operand" "f,f,f"))) 3873 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))] 3874 "TARGET_80387" 3875{ 3876 gcc_assert (!which_alternative); 3877 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3878 return "fstp%z0\t%y0"; 3879 else 3880 return "fst%z0\t%y0"; 3881} 3882 [(set_attr "type" "fmov,multi,multi") 3883 (set_attr "unit" "*,i387,i387") 3884 (set_attr "mode" "SF")]) 3885 3886(define_insn "*truncxfsf2_i387_1" 3887 [(set (match_operand:SF 0 "memory_operand" "=m") 3888 (float_truncate:SF 3889 (match_operand:XF 1 "register_operand" "f")))] 3890 "TARGET_80387" 3891{ 3892 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3893 return "fstp%z0\t%y0"; 3894 else 3895 return "fst%z0\t%y0"; 3896} 3897 [(set_attr "type" "fmov") 3898 (set_attr "mode" "SF")]) 3899 3900(define_split 3901 [(set (match_operand:SF 0 "register_operand" "") 3902 (float_truncate:SF 3903 (match_operand:XF 1 "register_operand" ""))) 3904 (clobber (match_operand:SF 2 "memory_operand" ""))] 3905 "TARGET_80387 && reload_completed" 3906 [(set (match_dup 2) (float_truncate:SF (match_dup 1))) 3907 (set (match_dup 0) (match_dup 2))] 3908 "") 3909 3910(define_split 3911 [(set (match_operand:SF 0 "memory_operand" "") 3912 (float_truncate:SF 3913 (match_operand:XF 1 "register_operand" ""))) 3914 (clobber (match_operand:SF 2 "memory_operand" ""))] 3915 "TARGET_80387" 3916 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))] 3917 "") 3918 3919;; Conversion from XFmode to DFmode. 3920 3921(define_expand "truncxfdf2" 3922 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "") 3923 (float_truncate:DF 3924 (match_operand:XF 1 "register_operand" ""))) 3925 (clobber (match_dup 2))])] 3926 "TARGET_80387" 3927{ 3928 if (flag_unsafe_math_optimizations) 3929 { 3930 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode); 3931 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1])); 3932 if (reg != operands[0]) 3933 emit_move_insn (operands[0], reg); 3934 DONE; 3935 } 3936 else 3937 operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL); 3938}) 3939 3940(define_insn "*truncxfdf2_mixed" 3941 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf") 3942 (float_truncate:DF 3943 (match_operand:XF 1 "register_operand" "f,f,f,f"))) 3944 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))] 3945 "TARGET_SSE2 && TARGET_MIX_SSE_I387" 3946{ 3947 gcc_assert (!which_alternative); 3948 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3949 return "fstp%z0\t%y0"; 3950 else 3951 return "fst%z0\t%y0"; 3952} 3953 [(set_attr "type" "fmov,multi,multi,multi") 3954 (set_attr "unit" "*,i387,i387,i387") 3955 (set_attr "mode" "DF")]) 3956 3957(define_insn "truncxfdf2_i387_noop" 3958 [(set (match_operand:DF 0 "register_operand" "=f") 3959 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))] 3960 "TARGET_80387 && flag_unsafe_math_optimizations" 3961{ 3962 return output_387_reg_move (insn, operands); 3963} 3964 [(set_attr "type" "fmov") 3965 (set_attr "mode" "DF")]) 3966 3967(define_insn "*truncxfdf2_i387" 3968 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f") 3969 (float_truncate:DF 3970 (match_operand:XF 1 "register_operand" "f,f,f"))) 3971 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))] 3972 "TARGET_80387" 3973{ 3974 gcc_assert (!which_alternative); 3975 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3976 return "fstp%z0\t%y0"; 3977 else 3978 return "fst%z0\t%y0"; 3979} 3980 [(set_attr "type" "fmov,multi,multi") 3981 (set_attr "unit" "*,i387,i387") 3982 (set_attr "mode" "DF")]) 3983 3984(define_insn "*truncxfdf2_i387_1" 3985 [(set (match_operand:DF 0 "memory_operand" "=m") 3986 (float_truncate:DF 3987 (match_operand:XF 1 "register_operand" "f")))] 3988 "TARGET_80387" 3989{ 3990 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3991 return "fstp%z0\t%y0"; 3992 else 3993 return "fst%z0\t%y0"; 3994} 3995 [(set_attr "type" "fmov") 3996 (set_attr "mode" "DF")]) 3997 3998(define_split 3999 [(set (match_operand:DF 0 "register_operand" "") 4000 (float_truncate:DF 4001 (match_operand:XF 1 "register_operand" ""))) 4002 (clobber (match_operand:DF 2 "memory_operand" ""))] 4003 "TARGET_80387 && reload_completed" 4004 [(set (match_dup 2) (float_truncate:DF (match_dup 1))) 4005 (set (match_dup 0) (match_dup 2))] 4006 "") 4007 4008(define_split 4009 [(set (match_operand:DF 0 "memory_operand" "") 4010 (float_truncate:DF 4011 (match_operand:XF 1 "register_operand" ""))) 4012 (clobber (match_operand:DF 2 "memory_operand" ""))] 4013 "TARGET_80387" 4014 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))] 4015 "") 4016 4017;; Signed conversion to DImode. 4018 4019(define_expand "fix_truncxfdi2" 4020 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 4021 (fix:DI (match_operand:XF 1 "register_operand" ""))) 4022 (clobber (reg:CC FLAGS_REG))])] 4023 "TARGET_80387" 4024{ 4025 if (TARGET_FISTTP) 4026 { 4027 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4028 DONE; 4029 } 4030}) 4031 4032(define_expand "fix_trunc<mode>di2" 4033 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 4034 (fix:DI (match_operand:SSEMODEF 1 "register_operand" ""))) 4035 (clobber (reg:CC FLAGS_REG))])] 4036 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))" 4037{ 4038 if (TARGET_FISTTP 4039 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4040 { 4041 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4042 DONE; 4043 } 4044 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)) 4045 { 4046 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode); 4047 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1])); 4048 if (out != operands[0]) 4049 emit_move_insn (operands[0], out); 4050 DONE; 4051 } 4052}) 4053 4054;; Signed conversion to SImode. 4055 4056(define_expand "fix_truncxfsi2" 4057 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4058 (fix:SI (match_operand:XF 1 "register_operand" ""))) 4059 (clobber (reg:CC FLAGS_REG))])] 4060 "TARGET_80387" 4061{ 4062 if (TARGET_FISTTP) 4063 { 4064 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4065 DONE; 4066 } 4067}) 4068 4069(define_expand "fix_trunc<mode>si2" 4070 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4071 (fix:SI (match_operand:SSEMODEF 1 "register_operand" ""))) 4072 (clobber (reg:CC FLAGS_REG))])] 4073 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)" 4074{ 4075 if (TARGET_FISTTP 4076 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4077 { 4078 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4079 DONE; 4080 } 4081 if (SSE_FLOAT_MODE_P (<MODE>mode)) 4082 { 4083 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode); 4084 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1])); 4085 if (out != operands[0]) 4086 emit_move_insn (operands[0], out); 4087 DONE; 4088 } 4089}) 4090 4091;; Signed conversion to HImode. 4092 4093(define_expand "fix_trunc<mode>hi2" 4094 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 4095 (fix:HI (match_operand:X87MODEF 1 "register_operand" ""))) 4096 (clobber (reg:CC FLAGS_REG))])] 4097 "TARGET_80387 4098 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))" 4099{ 4100 if (TARGET_FISTTP) 4101 { 4102 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1])); 4103 DONE; 4104 } 4105}) 4106 4107;; When SSE is available, it is always faster to use it! 4108(define_insn "fix_truncsfdi_sse" 4109 [(set (match_operand:DI 0 "register_operand" "=r,r") 4110 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))] 4111 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4112 "cvttss2si{q}\t{%1, %0|%0, %1}" 4113 [(set_attr "type" "sseicvt") 4114 (set_attr "mode" "SF") 4115 (set_attr "athlon_decode" "double,vector")]) 4116 4117(define_insn "fix_truncdfdi_sse" 4118 [(set (match_operand:DI 0 "register_operand" "=r,r") 4119 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))] 4120 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4121 "cvttsd2si{q}\t{%1, %0|%0, %1}" 4122 [(set_attr "type" "sseicvt") 4123 (set_attr "mode" "DF") 4124 (set_attr "athlon_decode" "double,vector")]) 4125 4126(define_insn "fix_truncsfsi_sse" 4127 [(set (match_operand:SI 0 "register_operand" "=r,r") 4128 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))] 4129 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4130 "cvttss2si\t{%1, %0|%0, %1}" 4131 [(set_attr "type" "sseicvt") 4132 (set_attr "mode" "DF") 4133 (set_attr "athlon_decode" "double,vector")]) 4134 4135(define_insn "fix_truncdfsi_sse" 4136 [(set (match_operand:SI 0 "register_operand" "=r,r") 4137 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))] 4138 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4139 "cvttsd2si\t{%1, %0|%0, %1}" 4140 [(set_attr "type" "sseicvt") 4141 (set_attr "mode" "DF") 4142 (set_attr "athlon_decode" "double,vector")]) 4143 4144;; Avoid vector decoded forms of the instruction. 4145(define_peephole2 4146 [(match_scratch:DF 2 "Y") 4147 (set (match_operand:SSEMODEI24 0 "register_operand" "") 4148 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))] 4149 "TARGET_K8 && !optimize_size" 4150 [(set (match_dup 2) (match_dup 1)) 4151 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))] 4152 "") 4153 4154(define_peephole2 4155 [(match_scratch:SF 2 "x") 4156 (set (match_operand:SSEMODEI24 0 "register_operand" "") 4157 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))] 4158 "TARGET_K8 && !optimize_size" 4159 [(set (match_dup 2) (match_dup 1)) 4160 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))] 4161 "") 4162 4163(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1" 4164 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 4165 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))] 4166 "TARGET_FISTTP 4167 && FLOAT_MODE_P (GET_MODE (operands[1])) 4168 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4169 && (TARGET_64BIT || <MODE>mode != DImode)) 4170 && TARGET_SSE_MATH) 4171 && !(reload_completed || reload_in_progress)" 4172 "#" 4173 "&& 1" 4174 [(const_int 0)] 4175{ 4176 if (memory_operand (operands[0], VOIDmode)) 4177 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1])); 4178 else 4179 { 4180 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4181 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0], 4182 operands[1], 4183 operands[2])); 4184 } 4185 DONE; 4186} 4187 [(set_attr "type" "fisttp") 4188 (set_attr "mode" "<MODE>")]) 4189 4190(define_insn "fix_trunc<mode>_i387_fisttp" 4191 [(set (match_operand:X87MODEI 0 "memory_operand" "=m") 4192 (fix:X87MODEI (match_operand 1 "register_operand" "f"))) 4193 (clobber (match_scratch:XF 2 "=&1f"))] 4194 "TARGET_FISTTP 4195 && FLOAT_MODE_P (GET_MODE (operands[1])) 4196 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4197 && (TARGET_64BIT || <MODE>mode != DImode)) 4198 && TARGET_SSE_MATH)" 4199 "* return output_fix_trunc (insn, operands, 1);" 4200 [(set_attr "type" "fisttp") 4201 (set_attr "mode" "<MODE>")]) 4202 4203(define_insn "fix_trunc<mode>_i387_fisttp_with_temp" 4204 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 4205 (fix:X87MODEI (match_operand 1 "register_operand" "f,f"))) 4206 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m")) 4207 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 4208 "TARGET_FISTTP 4209 && FLOAT_MODE_P (GET_MODE (operands[1])) 4210 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4211 && (TARGET_64BIT || <MODE>mode != DImode)) 4212 && TARGET_SSE_MATH)" 4213 "#" 4214 [(set_attr "type" "fisttp") 4215 (set_attr "mode" "<MODE>")]) 4216 4217(define_split 4218 [(set (match_operand:X87MODEI 0 "register_operand" "") 4219 (fix:X87MODEI (match_operand 1 "register_operand" ""))) 4220 (clobber (match_operand:X87MODEI 2 "memory_operand" "")) 4221 (clobber (match_scratch 3 ""))] 4222 "reload_completed" 4223 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1))) 4224 (clobber (match_dup 3))]) 4225 (set (match_dup 0) (match_dup 2))] 4226 "") 4227 4228(define_split 4229 [(set (match_operand:X87MODEI 0 "memory_operand" "") 4230 (fix:X87MODEI (match_operand 1 "register_operand" ""))) 4231 (clobber (match_operand:X87MODEI 2 "memory_operand" "")) 4232 (clobber (match_scratch 3 ""))] 4233 "reload_completed" 4234 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1))) 4235 (clobber (match_dup 3))])] 4236 "") 4237 4238;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description 4239;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control 4240;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG 4241;; clobbering insns can be used. Look at emit_i387_cw_initialization () 4242;; function in i386.c. 4243(define_insn_and_split "*fix_trunc<mode>_i387_1" 4244 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 4245 (fix:X87MODEI (match_operand 1 "register_operand" "f,f"))) 4246 (clobber (reg:CC FLAGS_REG))] 4247 "TARGET_80387 && !TARGET_FISTTP 4248 && FLOAT_MODE_P (GET_MODE (operands[1])) 4249 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4250 && (TARGET_64BIT || <MODE>mode != DImode)) 4251 && !(reload_completed || reload_in_progress)" 4252 "#" 4253 "&& 1" 4254 [(const_int 0)] 4255{ 4256 ix86_optimize_mode_switching[I387_TRUNC] = 1; 4257 4258 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 4259 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 4260 if (memory_operand (operands[0], VOIDmode)) 4261 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1], 4262 operands[2], operands[3])); 4263 else 4264 { 4265 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4266 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1], 4267 operands[2], operands[3], 4268 operands[4])); 4269 } 4270 DONE; 4271} 4272 [(set_attr "type" "fistp") 4273 (set_attr "i387_cw" "trunc") 4274 (set_attr "mode" "<MODE>")]) 4275 4276(define_insn "fix_truncdi_i387" 4277 [(set (match_operand:DI 0 "memory_operand" "=m") 4278 (fix:DI (match_operand 1 "register_operand" "f"))) 4279 (use (match_operand:HI 2 "memory_operand" "m")) 4280 (use (match_operand:HI 3 "memory_operand" "m")) 4281 (clobber (match_scratch:XF 4 "=&1f"))] 4282 "TARGET_80387 && !TARGET_FISTTP 4283 && FLOAT_MODE_P (GET_MODE (operands[1])) 4284 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4285 "* return output_fix_trunc (insn, operands, 0);" 4286 [(set_attr "type" "fistp") 4287 (set_attr "i387_cw" "trunc") 4288 (set_attr "mode" "DI")]) 4289 4290(define_insn "fix_truncdi_i387_with_temp" 4291 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 4292 (fix:DI (match_operand 1 "register_operand" "f,f"))) 4293 (use (match_operand:HI 2 "memory_operand" "m,m")) 4294 (use (match_operand:HI 3 "memory_operand" "m,m")) 4295 (clobber (match_operand:DI 4 "memory_operand" "=m,m")) 4296 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 4297 "TARGET_80387 && !TARGET_FISTTP 4298 && FLOAT_MODE_P (GET_MODE (operands[1])) 4299 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4300 "#" 4301 [(set_attr "type" "fistp") 4302 (set_attr "i387_cw" "trunc") 4303 (set_attr "mode" "DI")]) 4304 4305(define_split 4306 [(set (match_operand:DI 0 "register_operand" "") 4307 (fix:DI (match_operand 1 "register_operand" ""))) 4308 (use (match_operand:HI 2 "memory_operand" "")) 4309 (use (match_operand:HI 3 "memory_operand" "")) 4310 (clobber (match_operand:DI 4 "memory_operand" "")) 4311 (clobber (match_scratch 5 ""))] 4312 "reload_completed" 4313 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1))) 4314 (use (match_dup 2)) 4315 (use (match_dup 3)) 4316 (clobber (match_dup 5))]) 4317 (set (match_dup 0) (match_dup 4))] 4318 "") 4319 4320(define_split 4321 [(set (match_operand:DI 0 "memory_operand" "") 4322 (fix:DI (match_operand 1 "register_operand" ""))) 4323 (use (match_operand:HI 2 "memory_operand" "")) 4324 (use (match_operand:HI 3 "memory_operand" "")) 4325 (clobber (match_operand:DI 4 "memory_operand" "")) 4326 (clobber (match_scratch 5 ""))] 4327 "reload_completed" 4328 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1))) 4329 (use (match_dup 2)) 4330 (use (match_dup 3)) 4331 (clobber (match_dup 5))])] 4332 "") 4333 4334(define_insn "fix_trunc<mode>_i387" 4335 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 4336 (fix:X87MODEI12 (match_operand 1 "register_operand" "f"))) 4337 (use (match_operand:HI 2 "memory_operand" "m")) 4338 (use (match_operand:HI 3 "memory_operand" "m"))] 4339 "TARGET_80387 && !TARGET_FISTTP 4340 && FLOAT_MODE_P (GET_MODE (operands[1])) 4341 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4342 "* return output_fix_trunc (insn, operands, 0);" 4343 [(set_attr "type" "fistp") 4344 (set_attr "i387_cw" "trunc") 4345 (set_attr "mode" "<MODE>")]) 4346 4347(define_insn "fix_trunc<mode>_i387_with_temp" 4348 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") 4349 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f"))) 4350 (use (match_operand:HI 2 "memory_operand" "m,m")) 4351 (use (match_operand:HI 3 "memory_operand" "m,m")) 4352 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))] 4353 "TARGET_80387 && !TARGET_FISTTP 4354 && FLOAT_MODE_P (GET_MODE (operands[1])) 4355 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4356 "#" 4357 [(set_attr "type" "fistp") 4358 (set_attr "i387_cw" "trunc") 4359 (set_attr "mode" "<MODE>")]) 4360 4361(define_split 4362 [(set (match_operand:X87MODEI12 0 "register_operand" "") 4363 (fix:X87MODEI12 (match_operand 1 "register_operand" ""))) 4364 (use (match_operand:HI 2 "memory_operand" "")) 4365 (use (match_operand:HI 3 "memory_operand" "")) 4366 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 4367 "reload_completed" 4368 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1))) 4369 (use (match_dup 2)) 4370 (use (match_dup 3))]) 4371 (set (match_dup 0) (match_dup 4))] 4372 "") 4373 4374(define_split 4375 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 4376 (fix:X87MODEI12 (match_operand 1 "register_operand" ""))) 4377 (use (match_operand:HI 2 "memory_operand" "")) 4378 (use (match_operand:HI 3 "memory_operand" "")) 4379 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 4380 "reload_completed" 4381 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1))) 4382 (use (match_dup 2)) 4383 (use (match_dup 3))])] 4384 "") 4385 4386(define_insn "x86_fnstcw_1" 4387 [(set (match_operand:HI 0 "memory_operand" "=m") 4388 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))] 4389 "TARGET_80387" 4390 "fnstcw\t%0" 4391 [(set_attr "length" "2") 4392 (set_attr "mode" "HI") 4393 (set_attr "unit" "i387")]) 4394 4395(define_insn "x86_fldcw_1" 4396 [(set (reg:HI FPSR_REG) 4397 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))] 4398 "TARGET_80387" 4399 "fldcw\t%0" 4400 [(set_attr "length" "2") 4401 (set_attr "mode" "HI") 4402 (set_attr "unit" "i387") 4403 (set_attr "athlon_decode" "vector")]) 4404 4405;; Conversion between fixed point and floating point. 4406 4407;; Even though we only accept memory inputs, the backend _really_ 4408;; wants to be able to do this between registers. 4409 4410(define_expand "floathisf2" 4411 [(set (match_operand:SF 0 "register_operand" "") 4412 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))] 4413 "TARGET_80387 || TARGET_SSE_MATH" 4414{ 4415 if (TARGET_SSE_MATH) 4416 { 4417 emit_insn (gen_floatsisf2 (operands[0], 4418 convert_to_mode (SImode, operands[1], 0))); 4419 DONE; 4420 } 4421}) 4422 4423(define_insn "*floathisf2_i387" 4424 [(set (match_operand:SF 0 "register_operand" "=f,f") 4425 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))] 4426 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 4427 "@ 4428 fild%z1\t%1 4429 #" 4430 [(set_attr "type" "fmov,multi") 4431 (set_attr "mode" "SF") 4432 (set_attr "unit" "*,i387") 4433 (set_attr "fp_int_src" "true")]) 4434 4435(define_expand "floatsisf2" 4436 [(set (match_operand:SF 0 "register_operand" "") 4437 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))] 4438 "TARGET_80387 || TARGET_SSE_MATH" 4439 "") 4440 4441(define_insn "*floatsisf2_mixed" 4442 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f") 4443 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))] 4444 "TARGET_MIX_SSE_I387" 4445 "@ 4446 fild%z1\t%1 4447 # 4448 cvtsi2ss\t{%1, %0|%0, %1} 4449 cvtsi2ss\t{%1, %0|%0, %1}" 4450 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4451 (set_attr "mode" "SF") 4452 (set_attr "unit" "*,i387,*,*") 4453 (set_attr "athlon_decode" "*,*,vector,double") 4454 (set_attr "fp_int_src" "true")]) 4455 4456(define_insn "*floatsisf2_sse" 4457 [(set (match_operand:SF 0 "register_operand" "=x,x") 4458 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))] 4459 "TARGET_SSE_MATH" 4460 "cvtsi2ss\t{%1, %0|%0, %1}" 4461 [(set_attr "type" "sseicvt") 4462 (set_attr "mode" "SF") 4463 (set_attr "athlon_decode" "vector,double") 4464 (set_attr "fp_int_src" "true")]) 4465 4466(define_insn "*floatsisf2_i387" 4467 [(set (match_operand:SF 0 "register_operand" "=f,f") 4468 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))] 4469 "TARGET_80387" 4470 "@ 4471 fild%z1\t%1 4472 #" 4473 [(set_attr "type" "fmov,multi") 4474 (set_attr "mode" "SF") 4475 (set_attr "unit" "*,i387") 4476 (set_attr "fp_int_src" "true")]) 4477 4478(define_expand "floatdisf2" 4479 [(set (match_operand:SF 0 "register_operand" "") 4480 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))] 4481 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)" 4482 "") 4483 4484(define_insn "*floatdisf2_mixed" 4485 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f") 4486 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))] 4487 "TARGET_64BIT && TARGET_MIX_SSE_I387" 4488 "@ 4489 fild%z1\t%1 4490 # 4491 cvtsi2ss{q}\t{%1, %0|%0, %1} 4492 cvtsi2ss{q}\t{%1, %0|%0, %1}" 4493 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4494 (set_attr "mode" "SF") 4495 (set_attr "unit" "*,i387,*,*") 4496 (set_attr "athlon_decode" "*,*,vector,double") 4497 (set_attr "fp_int_src" "true")]) 4498 4499(define_insn "*floatdisf2_sse" 4500 [(set (match_operand:SF 0 "register_operand" "=x,x") 4501 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))] 4502 "TARGET_64BIT && TARGET_SSE_MATH" 4503 "cvtsi2ss{q}\t{%1, %0|%0, %1}" 4504 [(set_attr "type" "sseicvt") 4505 (set_attr "mode" "SF") 4506 (set_attr "athlon_decode" "vector,double") 4507 (set_attr "fp_int_src" "true")]) 4508 4509(define_insn "*floatdisf2_i387" 4510 [(set (match_operand:SF 0 "register_operand" "=f,f") 4511 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))] 4512 "TARGET_80387" 4513 "@ 4514 fild%z1\t%1 4515 #" 4516 [(set_attr "type" "fmov,multi") 4517 (set_attr "mode" "SF") 4518 (set_attr "unit" "*,i387") 4519 (set_attr "fp_int_src" "true")]) 4520 4521(define_expand "floathidf2" 4522 [(set (match_operand:DF 0 "register_operand" "") 4523 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))] 4524 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4525{ 4526 if (TARGET_SSE2 && TARGET_SSE_MATH) 4527 { 4528 emit_insn (gen_floatsidf2 (operands[0], 4529 convert_to_mode (SImode, operands[1], 0))); 4530 DONE; 4531 } 4532}) 4533 4534(define_insn "*floathidf2_i387" 4535 [(set (match_operand:DF 0 "register_operand" "=f,f") 4536 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))] 4537 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)" 4538 "@ 4539 fild%z1\t%1 4540 #" 4541 [(set_attr "type" "fmov,multi") 4542 (set_attr "mode" "DF") 4543 (set_attr "unit" "*,i387") 4544 (set_attr "fp_int_src" "true")]) 4545 4546(define_expand "floatsidf2" 4547 [(set (match_operand:DF 0 "register_operand" "") 4548 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))] 4549 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4550 "") 4551 4552(define_insn "*floatsidf2_mixed" 4553 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f") 4554 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))] 4555 "TARGET_SSE2 && TARGET_MIX_SSE_I387" 4556 "@ 4557 fild%z1\t%1 4558 # 4559 cvtsi2sd\t{%1, %0|%0, %1} 4560 cvtsi2sd\t{%1, %0|%0, %1}" 4561 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4562 (set_attr "mode" "DF") 4563 (set_attr "unit" "*,i387,*,*") 4564 (set_attr "athlon_decode" "*,*,double,direct") 4565 (set_attr "fp_int_src" "true")]) 4566 4567(define_insn "*floatsidf2_sse" 4568 [(set (match_operand:DF 0 "register_operand" "=Y,Y") 4569 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))] 4570 "TARGET_SSE2 && TARGET_SSE_MATH" 4571 "cvtsi2sd\t{%1, %0|%0, %1}" 4572 [(set_attr "type" "sseicvt") 4573 (set_attr "mode" "DF") 4574 (set_attr "athlon_decode" "double,direct") 4575 (set_attr "fp_int_src" "true")]) 4576 4577(define_insn "*floatsidf2_i387" 4578 [(set (match_operand:DF 0 "register_operand" "=f,f") 4579 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))] 4580 "TARGET_80387" 4581 "@ 4582 fild%z1\t%1 4583 #" 4584 [(set_attr "type" "fmov,multi") 4585 (set_attr "mode" "DF") 4586 (set_attr "unit" "*,i387") 4587 (set_attr "fp_int_src" "true")]) 4588 4589(define_expand "floatdidf2" 4590 [(set (match_operand:DF 0 "register_operand" "") 4591 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))] 4592 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)" 4593 "") 4594 4595(define_insn "*floatdidf2_mixed" 4596 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f") 4597 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))] 4598 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387" 4599 "@ 4600 fild%z1\t%1 4601 # 4602 cvtsi2sd{q}\t{%1, %0|%0, %1} 4603 cvtsi2sd{q}\t{%1, %0|%0, %1}" 4604 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4605 (set_attr "mode" "DF") 4606 (set_attr "unit" "*,i387,*,*") 4607 (set_attr "athlon_decode" "*,*,double,direct") 4608 (set_attr "fp_int_src" "true")]) 4609 4610(define_insn "*floatdidf2_sse" 4611 [(set (match_operand:DF 0 "register_operand" "=Y,Y") 4612 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))] 4613 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH" 4614 "cvtsi2sd{q}\t{%1, %0|%0, %1}" 4615 [(set_attr "type" "sseicvt") 4616 (set_attr "mode" "DF") 4617 (set_attr "athlon_decode" "double,direct") 4618 (set_attr "fp_int_src" "true")]) 4619 4620(define_insn "*floatdidf2_i387" 4621 [(set (match_operand:DF 0 "register_operand" "=f,f") 4622 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))] 4623 "TARGET_80387" 4624 "@ 4625 fild%z1\t%1 4626 #" 4627 [(set_attr "type" "fmov,multi") 4628 (set_attr "mode" "DF") 4629 (set_attr "unit" "*,i387") 4630 (set_attr "fp_int_src" "true")]) 4631 4632(define_insn "floathixf2" 4633 [(set (match_operand:XF 0 "register_operand" "=f,f") 4634 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))] 4635 "TARGET_80387" 4636 "@ 4637 fild%z1\t%1 4638 #" 4639 [(set_attr "type" "fmov,multi") 4640 (set_attr "mode" "XF") 4641 (set_attr "unit" "*,i387") 4642 (set_attr "fp_int_src" "true")]) 4643 4644(define_insn "floatsixf2" 4645 [(set (match_operand:XF 0 "register_operand" "=f,f") 4646 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))] 4647 "TARGET_80387" 4648 "@ 4649 fild%z1\t%1 4650 #" 4651 [(set_attr "type" "fmov,multi") 4652 (set_attr "mode" "XF") 4653 (set_attr "unit" "*,i387") 4654 (set_attr "fp_int_src" "true")]) 4655 4656(define_insn "floatdixf2" 4657 [(set (match_operand:XF 0 "register_operand" "=f,f") 4658 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))] 4659 "TARGET_80387" 4660 "@ 4661 fild%z1\t%1 4662 #" 4663 [(set_attr "type" "fmov,multi") 4664 (set_attr "mode" "XF") 4665 (set_attr "unit" "*,i387") 4666 (set_attr "fp_int_src" "true")]) 4667 4668;; %%% Kill these when reload knows how to do it. 4669(define_split 4670 [(set (match_operand 0 "fp_register_operand" "") 4671 (float (match_operand 1 "register_operand" "")))] 4672 "reload_completed 4673 && TARGET_80387 4674 && FLOAT_MODE_P (GET_MODE (operands[0]))" 4675 [(const_int 0)] 4676{ 4677 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]); 4678 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]); 4679 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2])); 4680 ix86_free_from_memory (GET_MODE (operands[1])); 4681 DONE; 4682}) 4683 4684(define_expand "floatunssisf2" 4685 [(use (match_operand:SF 0 "register_operand" "")) 4686 (use (match_operand:SI 1 "register_operand" ""))] 4687 "!TARGET_64BIT && TARGET_SSE_MATH" 4688 "x86_emit_floatuns (operands); DONE;") 4689 4690(define_expand "floatunsdisf2" 4691 [(use (match_operand:SF 0 "register_operand" "")) 4692 (use (match_operand:DI 1 "register_operand" ""))] 4693 "TARGET_64BIT && TARGET_SSE_MATH" 4694 "x86_emit_floatuns (operands); DONE;") 4695 4696(define_expand "floatunsdidf2" 4697 [(use (match_operand:DF 0 "register_operand" "")) 4698 (use (match_operand:DI 1 "register_operand" ""))] 4699 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH" 4700 "x86_emit_floatuns (operands); DONE;") 4701 4702;; SSE extract/set expanders 4703 4704 4705;; Add instructions 4706 4707;; %%% splits for addditi3 4708 4709(define_expand "addti3" 4710 [(set (match_operand:TI 0 "nonimmediate_operand" "") 4711 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "") 4712 (match_operand:TI 2 "x86_64_general_operand" ""))) 4713 (clobber (reg:CC FLAGS_REG))] 4714 "TARGET_64BIT" 4715 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;") 4716 4717(define_insn "*addti3_1" 4718 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o") 4719 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0") 4720 (match_operand:TI 2 "general_operand" "roiF,riF"))) 4721 (clobber (reg:CC FLAGS_REG))] 4722 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)" 4723 "#") 4724 4725(define_split 4726 [(set (match_operand:TI 0 "nonimmediate_operand" "") 4727 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "") 4728 (match_operand:TI 2 "general_operand" ""))) 4729 (clobber (reg:CC FLAGS_REG))] 4730 "TARGET_64BIT && reload_completed" 4731 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)] 4732 UNSPEC_ADD_CARRY)) 4733 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]) 4734 (parallel [(set (match_dup 3) 4735 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) 4736 (match_dup 4)) 4737 (match_dup 5))) 4738 (clobber (reg:CC FLAGS_REG))])] 4739 "split_ti (operands+0, 1, operands+0, operands+3); 4740 split_ti (operands+1, 1, operands+1, operands+4); 4741 split_ti (operands+2, 1, operands+2, operands+5);") 4742 4743;; %%% splits for addsidi3 4744; [(set (match_operand:DI 0 "nonimmediate_operand" "") 4745; (plus:DI (match_operand:DI 1 "general_operand" "") 4746; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))] 4747 4748(define_expand "adddi3" 4749 [(set (match_operand:DI 0 "nonimmediate_operand" "") 4750 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") 4751 (match_operand:DI 2 "x86_64_general_operand" ""))) 4752 (clobber (reg:CC FLAGS_REG))] 4753 "" 4754 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;") 4755 4756(define_insn "*adddi3_1" 4757 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") 4758 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 4759 (match_operand:DI 2 "general_operand" "roiF,riF"))) 4760 (clobber (reg:CC FLAGS_REG))] 4761 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 4762 "#") 4763 4764(define_split 4765 [(set (match_operand:DI 0 "nonimmediate_operand" "") 4766 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") 4767 (match_operand:DI 2 "general_operand" ""))) 4768 (clobber (reg:CC FLAGS_REG))] 4769 "!TARGET_64BIT && reload_completed" 4770 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)] 4771 UNSPEC_ADD_CARRY)) 4772 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) 4773 (parallel [(set (match_dup 3) 4774 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) 4775 (match_dup 4)) 4776 (match_dup 5))) 4777 (clobber (reg:CC FLAGS_REG))])] 4778 "split_di (operands+0, 1, operands+0, operands+3); 4779 split_di (operands+1, 1, operands+1, operands+4); 4780 split_di (operands+2, 1, operands+2, operands+5);") 4781 4782(define_insn "adddi3_carry_rex64" 4783 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 4784 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "") 4785 (match_operand:DI 1 "nonimmediate_operand" "%0,0")) 4786 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 4787 (clobber (reg:CC FLAGS_REG))] 4788 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 4789 "adc{q}\t{%2, %0|%0, %2}" 4790 [(set_attr "type" "alu") 4791 (set_attr "pent_pair" "pu") 4792 (set_attr "mode" "DI")]) 4793 4794(define_insn "*adddi3_cc_rex64" 4795 [(set (reg:CC FLAGS_REG) 4796 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0") 4797 (match_operand:DI 2 "x86_64_general_operand" "re,rm")] 4798 UNSPEC_ADD_CARRY)) 4799 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 4800 (plus:DI (match_dup 1) (match_dup 2)))] 4801 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 4802 "add{q}\t{%2, %0|%0, %2}" 4803 [(set_attr "type" "alu") 4804 (set_attr "mode" "DI")]) 4805 4806(define_insn "addqi3_carry" 4807 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 4808 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "") 4809 (match_operand:QI 1 "nonimmediate_operand" "%0,0")) 4810 (match_operand:QI 2 "general_operand" "qi,qm"))) 4811 (clobber (reg:CC FLAGS_REG))] 4812 "ix86_binary_operator_ok (PLUS, QImode, operands)" 4813 "adc{b}\t{%2, %0|%0, %2}" 4814 [(set_attr "type" "alu") 4815 (set_attr "pent_pair" "pu") 4816 (set_attr "mode" "QI")]) 4817 4818(define_insn "addhi3_carry" 4819 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 4820 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "") 4821 (match_operand:HI 1 "nonimmediate_operand" "%0,0")) 4822 (match_operand:HI 2 "general_operand" "ri,rm"))) 4823 (clobber (reg:CC FLAGS_REG))] 4824 "ix86_binary_operator_ok (PLUS, HImode, operands)" 4825 "adc{w}\t{%2, %0|%0, %2}" 4826 [(set_attr "type" "alu") 4827 (set_attr "pent_pair" "pu") 4828 (set_attr "mode" "HI")]) 4829 4830(define_insn "addsi3_carry" 4831 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 4832 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 4833 (match_operand:SI 1 "nonimmediate_operand" "%0,0")) 4834 (match_operand:SI 2 "general_operand" "ri,rm"))) 4835 (clobber (reg:CC FLAGS_REG))] 4836 "ix86_binary_operator_ok (PLUS, SImode, operands)" 4837 "adc{l}\t{%2, %0|%0, %2}" 4838 [(set_attr "type" "alu") 4839 (set_attr "pent_pair" "pu") 4840 (set_attr "mode" "SI")]) 4841 4842(define_insn "*addsi3_carry_zext" 4843 [(set (match_operand:DI 0 "register_operand" "=r") 4844 (zero_extend:DI 4845 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 4846 (match_operand:SI 1 "nonimmediate_operand" "%0")) 4847 (match_operand:SI 2 "general_operand" "rim")))) 4848 (clobber (reg:CC FLAGS_REG))] 4849 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 4850 "adc{l}\t{%2, %k0|%k0, %2}" 4851 [(set_attr "type" "alu") 4852 (set_attr "pent_pair" "pu") 4853 (set_attr "mode" "SI")]) 4854 4855(define_insn "*addsi3_cc" 4856 [(set (reg:CC FLAGS_REG) 4857 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0") 4858 (match_operand:SI 2 "general_operand" "ri,rm")] 4859 UNSPEC_ADD_CARRY)) 4860 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 4861 (plus:SI (match_dup 1) (match_dup 2)))] 4862 "ix86_binary_operator_ok (PLUS, SImode, operands)" 4863 "add{l}\t{%2, %0|%0, %2}" 4864 [(set_attr "type" "alu") 4865 (set_attr "mode" "SI")]) 4866 4867(define_insn "addqi3_cc" 4868 [(set (reg:CC FLAGS_REG) 4869 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0") 4870 (match_operand:QI 2 "general_operand" "qi,qm")] 4871 UNSPEC_ADD_CARRY)) 4872 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 4873 (plus:QI (match_dup 1) (match_dup 2)))] 4874 "ix86_binary_operator_ok (PLUS, QImode, operands)" 4875 "add{b}\t{%2, %0|%0, %2}" 4876 [(set_attr "type" "alu") 4877 (set_attr "mode" "QI")]) 4878 4879(define_expand "addsi3" 4880 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4881 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "") 4882 (match_operand:SI 2 "general_operand" ""))) 4883 (clobber (reg:CC FLAGS_REG))])] 4884 "" 4885 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;") 4886 4887(define_insn "*lea_1" 4888 [(set (match_operand:SI 0 "register_operand" "=r") 4889 (match_operand:SI 1 "no_seg_address_operand" "p"))] 4890 "!TARGET_64BIT" 4891 "lea{l}\t{%a1, %0|%0, %a1}" 4892 [(set_attr "type" "lea") 4893 (set_attr "mode" "SI")]) 4894 4895(define_insn "*lea_1_rex64" 4896 [(set (match_operand:SI 0 "register_operand" "=r") 4897 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))] 4898 "TARGET_64BIT" 4899 "lea{l}\t{%a1, %0|%0, %a1}" 4900 [(set_attr "type" "lea") 4901 (set_attr "mode" "SI")]) 4902 4903(define_insn "*lea_1_zext" 4904 [(set (match_operand:DI 0 "register_operand" "=r") 4905 (zero_extend:DI 4906 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))] 4907 "TARGET_64BIT" 4908 "lea{l}\t{%a1, %k0|%k0, %a1}" 4909 [(set_attr "type" "lea") 4910 (set_attr "mode" "SI")]) 4911 4912(define_insn "*lea_2_rex64" 4913 [(set (match_operand:DI 0 "register_operand" "=r") 4914 (match_operand:DI 1 "no_seg_address_operand" "p"))] 4915 "TARGET_64BIT" 4916 "lea{q}\t{%a1, %0|%0, %a1}" 4917 [(set_attr "type" "lea") 4918 (set_attr "mode" "DI")]) 4919 4920;; The lea patterns for non-Pmodes needs to be matched by several 4921;; insns converted to real lea by splitters. 4922 4923(define_insn_and_split "*lea_general_1" 4924 [(set (match_operand 0 "register_operand" "=r") 4925 (plus (plus (match_operand 1 "index_register_operand" "l") 4926 (match_operand 2 "register_operand" "r")) 4927 (match_operand 3 "immediate_operand" "i")))] 4928 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode 4929 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) 4930 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 4931 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 4932 && GET_MODE (operands[0]) == GET_MODE (operands[2]) 4933 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 4934 || GET_MODE (operands[3]) == VOIDmode)" 4935 "#" 4936 "&& reload_completed" 4937 [(const_int 0)] 4938{ 4939 rtx pat; 4940 operands[0] = gen_lowpart (SImode, operands[0]); 4941 operands[1] = gen_lowpart (Pmode, operands[1]); 4942 operands[2] = gen_lowpart (Pmode, operands[2]); 4943 operands[3] = gen_lowpart (Pmode, operands[3]); 4944 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]), 4945 operands[3]); 4946 if (Pmode != SImode) 4947 pat = gen_rtx_SUBREG (SImode, pat, 0); 4948 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 4949 DONE; 4950} 4951 [(set_attr "type" "lea") 4952 (set_attr "mode" "SI")]) 4953 4954(define_insn_and_split "*lea_general_1_zext" 4955 [(set (match_operand:DI 0 "register_operand" "=r") 4956 (zero_extend:DI 4957 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l") 4958 (match_operand:SI 2 "register_operand" "r")) 4959 (match_operand:SI 3 "immediate_operand" "i"))))] 4960 "TARGET_64BIT" 4961 "#" 4962 "&& reload_completed" 4963 [(set (match_dup 0) 4964 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1) 4965 (match_dup 2)) 4966 (match_dup 3)) 0)))] 4967{ 4968 operands[1] = gen_lowpart (Pmode, operands[1]); 4969 operands[2] = gen_lowpart (Pmode, operands[2]); 4970 operands[3] = gen_lowpart (Pmode, operands[3]); 4971} 4972 [(set_attr "type" "lea") 4973 (set_attr "mode" "SI")]) 4974 4975(define_insn_and_split "*lea_general_2" 4976 [(set (match_operand 0 "register_operand" "=r") 4977 (plus (mult (match_operand 1 "index_register_operand" "l") 4978 (match_operand 2 "const248_operand" "i")) 4979 (match_operand 3 "nonmemory_operand" "ri")))] 4980 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode 4981 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) 4982 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 4983 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 4984 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 4985 || GET_MODE (operands[3]) == VOIDmode)" 4986 "#" 4987 "&& reload_completed" 4988 [(const_int 0)] 4989{ 4990 rtx pat; 4991 operands[0] = gen_lowpart (SImode, operands[0]); 4992 operands[1] = gen_lowpart (Pmode, operands[1]); 4993 operands[3] = gen_lowpart (Pmode, operands[3]); 4994 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]), 4995 operands[3]); 4996 if (Pmode != SImode) 4997 pat = gen_rtx_SUBREG (SImode, pat, 0); 4998 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 4999 DONE; 5000} 5001 [(set_attr "type" "lea") 5002 (set_attr "mode" "SI")]) 5003 5004(define_insn_and_split "*lea_general_2_zext" 5005 [(set (match_operand:DI 0 "register_operand" "=r") 5006 (zero_extend:DI 5007 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l") 5008 (match_operand:SI 2 "const248_operand" "n")) 5009 (match_operand:SI 3 "nonmemory_operand" "ri"))))] 5010 "TARGET_64BIT" 5011 "#" 5012 "&& reload_completed" 5013 [(set (match_dup 0) 5014 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1) 5015 (match_dup 2)) 5016 (match_dup 3)) 0)))] 5017{ 5018 operands[1] = gen_lowpart (Pmode, operands[1]); 5019 operands[3] = gen_lowpart (Pmode, operands[3]); 5020} 5021 [(set_attr "type" "lea") 5022 (set_attr "mode" "SI")]) 5023 5024(define_insn_and_split "*lea_general_3" 5025 [(set (match_operand 0 "register_operand" "=r") 5026 (plus (plus (mult (match_operand 1 "index_register_operand" "l") 5027 (match_operand 2 "const248_operand" "i")) 5028 (match_operand 3 "register_operand" "r")) 5029 (match_operand 4 "immediate_operand" "i")))] 5030 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode 5031 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) 5032 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 5033 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 5034 && GET_MODE (operands[0]) == GET_MODE (operands[3])" 5035 "#" 5036 "&& reload_completed" 5037 [(const_int 0)] 5038{ 5039 rtx pat; 5040 operands[0] = gen_lowpart (SImode, operands[0]); 5041 operands[1] = gen_lowpart (Pmode, operands[1]); 5042 operands[3] = gen_lowpart (Pmode, operands[3]); 5043 operands[4] = gen_lowpart (Pmode, operands[4]); 5044 pat = gen_rtx_PLUS (Pmode, 5045 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], 5046 operands[2]), 5047 operands[3]), 5048 operands[4]); 5049 if (Pmode != SImode) 5050 pat = gen_rtx_SUBREG (SImode, pat, 0); 5051 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5052 DONE; 5053} 5054 [(set_attr "type" "lea") 5055 (set_attr "mode" "SI")]) 5056 5057(define_insn_and_split "*lea_general_3_zext" 5058 [(set (match_operand:DI 0 "register_operand" "=r") 5059 (zero_extend:DI 5060 (plus:SI (plus:SI (mult:SI 5061 (match_operand:SI 1 "index_register_operand" "l") 5062 (match_operand:SI 2 "const248_operand" "n")) 5063 (match_operand:SI 3 "register_operand" "r")) 5064 (match_operand:SI 4 "immediate_operand" "i"))))] 5065 "TARGET_64BIT" 5066 "#" 5067 "&& reload_completed" 5068 [(set (match_dup 0) 5069 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1) 5070 (match_dup 2)) 5071 (match_dup 3)) 5072 (match_dup 4)) 0)))] 5073{ 5074 operands[1] = gen_lowpart (Pmode, operands[1]); 5075 operands[3] = gen_lowpart (Pmode, operands[3]); 5076 operands[4] = gen_lowpart (Pmode, operands[4]); 5077} 5078 [(set_attr "type" "lea") 5079 (set_attr "mode" "SI")]) 5080 5081(define_insn "*adddi_1_rex64" 5082 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r") 5083 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r") 5084 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le"))) 5085 (clobber (reg:CC FLAGS_REG))] 5086 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 5087{ 5088 switch (get_attr_type (insn)) 5089 { 5090 case TYPE_LEA: 5091 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 5092 return "lea{q}\t{%a2, %0|%0, %a2}"; 5093 5094 case TYPE_INCDEC: 5095 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5096 if (operands[2] == const1_rtx) 5097 return "inc{q}\t%0"; 5098 else 5099 { 5100 gcc_assert (operands[2] == constm1_rtx); 5101 return "dec{q}\t%0"; 5102 } 5103 5104 default: 5105 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5106 5107 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5108 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5109 if (GET_CODE (operands[2]) == CONST_INT 5110 /* Avoid overflows. */ 5111 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5112 && (INTVAL (operands[2]) == 128 5113 || (INTVAL (operands[2]) < 0 5114 && INTVAL (operands[2]) != -128))) 5115 { 5116 operands[2] = GEN_INT (-INTVAL (operands[2])); 5117 return "sub{q}\t{%2, %0|%0, %2}"; 5118 } 5119 return "add{q}\t{%2, %0|%0, %2}"; 5120 } 5121} 5122 [(set (attr "type") 5123 (cond [(eq_attr "alternative" "2") 5124 (const_string "lea") 5125 ; Current assemblers are broken and do not allow @GOTOFF in 5126 ; ought but a memory context. 5127 (match_operand:DI 2 "pic_symbolic_operand" "") 5128 (const_string "lea") 5129 (match_operand:DI 2 "incdec_operand" "") 5130 (const_string "incdec") 5131 ] 5132 (const_string "alu"))) 5133 (set_attr "mode" "DI")]) 5134 5135;; Convert lea to the lea pattern to avoid flags dependency. 5136(define_split 5137 [(set (match_operand:DI 0 "register_operand" "") 5138 (plus:DI (match_operand:DI 1 "register_operand" "") 5139 (match_operand:DI 2 "x86_64_nonmemory_operand" ""))) 5140 (clobber (reg:CC FLAGS_REG))] 5141 "TARGET_64BIT && reload_completed 5142 && true_regnum (operands[0]) != true_regnum (operands[1])" 5143 [(set (match_dup 0) 5144 (plus:DI (match_dup 1) 5145 (match_dup 2)))] 5146 "") 5147 5148(define_insn "*adddi_2_rex64" 5149 [(set (reg FLAGS_REG) 5150 (compare 5151 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 5152 (match_operand:DI 2 "x86_64_general_operand" "rme,re")) 5153 (const_int 0))) 5154 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") 5155 (plus:DI (match_dup 1) (match_dup 2)))] 5156 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 5157 && ix86_binary_operator_ok (PLUS, DImode, operands) 5158 /* Current assemblers are broken and do not allow @GOTOFF in 5159 ought but a memory context. */ 5160 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5161{ 5162 switch (get_attr_type (insn)) 5163 { 5164 case TYPE_INCDEC: 5165 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5166 if (operands[2] == const1_rtx) 5167 return "inc{q}\t%0"; 5168 else 5169 { 5170 gcc_assert (operands[2] == constm1_rtx); 5171 return "dec{q}\t%0"; 5172 } 5173 5174 default: 5175 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5176 /* ???? We ought to handle there the 32bit case too 5177 - do we need new constraint? */ 5178 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5179 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5180 if (GET_CODE (operands[2]) == CONST_INT 5181 /* Avoid overflows. */ 5182 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5183 && (INTVAL (operands[2]) == 128 5184 || (INTVAL (operands[2]) < 0 5185 && INTVAL (operands[2]) != -128))) 5186 { 5187 operands[2] = GEN_INT (-INTVAL (operands[2])); 5188 return "sub{q}\t{%2, %0|%0, %2}"; 5189 } 5190 return "add{q}\t{%2, %0|%0, %2}"; 5191 } 5192} 5193 [(set (attr "type") 5194 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5195 (const_string "incdec") 5196 (const_string "alu"))) 5197 (set_attr "mode" "DI")]) 5198 5199(define_insn "*adddi_3_rex64" 5200 [(set (reg FLAGS_REG) 5201 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme")) 5202 (match_operand:DI 1 "x86_64_general_operand" "%0"))) 5203 (clobber (match_scratch:DI 0 "=r"))] 5204 "TARGET_64BIT 5205 && ix86_match_ccmode (insn, CCZmode) 5206 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5207 /* Current assemblers are broken and do not allow @GOTOFF in 5208 ought but a memory context. */ 5209 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5210{ 5211 switch (get_attr_type (insn)) 5212 { 5213 case TYPE_INCDEC: 5214 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5215 if (operands[2] == const1_rtx) 5216 return "inc{q}\t%0"; 5217 else 5218 { 5219 gcc_assert (operands[2] == constm1_rtx); 5220 return "dec{q}\t%0"; 5221 } 5222 5223 default: 5224 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5225 /* ???? We ought to handle there the 32bit case too 5226 - do we need new constraint? */ 5227 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5228 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5229 if (GET_CODE (operands[2]) == CONST_INT 5230 /* Avoid overflows. */ 5231 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5232 && (INTVAL (operands[2]) == 128 5233 || (INTVAL (operands[2]) < 0 5234 && INTVAL (operands[2]) != -128))) 5235 { 5236 operands[2] = GEN_INT (-INTVAL (operands[2])); 5237 return "sub{q}\t{%2, %0|%0, %2}"; 5238 } 5239 return "add{q}\t{%2, %0|%0, %2}"; 5240 } 5241} 5242 [(set (attr "type") 5243 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5244 (const_string "incdec") 5245 (const_string "alu"))) 5246 (set_attr "mode" "DI")]) 5247 5248; For comparisons against 1, -1 and 128, we may generate better code 5249; by converting cmp to add, inc or dec as done by peephole2. This pattern 5250; is matched then. We can't accept general immediate, because for 5251; case of overflows, the result is messed up. 5252; This pattern also don't hold of 0x8000000000000000, since the value overflows 5253; when negated. 5254; Also carry flag is reversed compared to cmp, so this conversion is valid 5255; only for comparisons not depending on it. 5256(define_insn "*adddi_4_rex64" 5257 [(set (reg FLAGS_REG) 5258 (compare (match_operand:DI 1 "nonimmediate_operand" "0") 5259 (match_operand:DI 2 "x86_64_immediate_operand" "e"))) 5260 (clobber (match_scratch:DI 0 "=rm"))] 5261 "TARGET_64BIT 5262 && ix86_match_ccmode (insn, CCGCmode)" 5263{ 5264 switch (get_attr_type (insn)) 5265 { 5266 case TYPE_INCDEC: 5267 if (operands[2] == constm1_rtx) 5268 return "inc{q}\t%0"; 5269 else 5270 { 5271 gcc_assert (operands[2] == const1_rtx); 5272 return "dec{q}\t%0"; 5273 } 5274 5275 default: 5276 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5277 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5278 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5279 if ((INTVAL (operands[2]) == -128 5280 || (INTVAL (operands[2]) > 0 5281 && INTVAL (operands[2]) != 128)) 5282 /* Avoid overflows. */ 5283 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))) 5284 return "sub{q}\t{%2, %0|%0, %2}"; 5285 operands[2] = GEN_INT (-INTVAL (operands[2])); 5286 return "add{q}\t{%2, %0|%0, %2}"; 5287 } 5288} 5289 [(set (attr "type") 5290 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5291 (const_string "incdec") 5292 (const_string "alu"))) 5293 (set_attr "mode" "DI")]) 5294 5295(define_insn "*adddi_5_rex64" 5296 [(set (reg FLAGS_REG) 5297 (compare 5298 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0") 5299 (match_operand:DI 2 "x86_64_general_operand" "rme")) 5300 (const_int 0))) 5301 (clobber (match_scratch:DI 0 "=r"))] 5302 "TARGET_64BIT 5303 && ix86_match_ccmode (insn, CCGOCmode) 5304 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5305 /* Current assemblers are broken and do not allow @GOTOFF in 5306 ought but a memory context. */ 5307 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5308{ 5309 switch (get_attr_type (insn)) 5310 { 5311 case TYPE_INCDEC: 5312 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5313 if (operands[2] == const1_rtx) 5314 return "inc{q}\t%0"; 5315 else 5316 { 5317 gcc_assert (operands[2] == constm1_rtx); 5318 return "dec{q}\t%0"; 5319 } 5320 5321 default: 5322 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5323 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5324 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5325 if (GET_CODE (operands[2]) == CONST_INT 5326 /* Avoid overflows. */ 5327 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5328 && (INTVAL (operands[2]) == 128 5329 || (INTVAL (operands[2]) < 0 5330 && INTVAL (operands[2]) != -128))) 5331 { 5332 operands[2] = GEN_INT (-INTVAL (operands[2])); 5333 return "sub{q}\t{%2, %0|%0, %2}"; 5334 } 5335 return "add{q}\t{%2, %0|%0, %2}"; 5336 } 5337} 5338 [(set (attr "type") 5339 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5340 (const_string "incdec") 5341 (const_string "alu"))) 5342 (set_attr "mode" "DI")]) 5343 5344 5345(define_insn "*addsi_1" 5346 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r") 5347 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r") 5348 (match_operand:SI 2 "general_operand" "rmni,rni,lni"))) 5349 (clobber (reg:CC FLAGS_REG))] 5350 "ix86_binary_operator_ok (PLUS, SImode, operands)" 5351{ 5352 switch (get_attr_type (insn)) 5353 { 5354 case TYPE_LEA: 5355 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 5356 return "lea{l}\t{%a2, %0|%0, %a2}"; 5357 5358 case TYPE_INCDEC: 5359 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5360 if (operands[2] == const1_rtx) 5361 return "inc{l}\t%0"; 5362 else 5363 { 5364 gcc_assert (operands[2] == constm1_rtx); 5365 return "dec{l}\t%0"; 5366 } 5367 5368 default: 5369 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5370 5371 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5372 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5373 if (GET_CODE (operands[2]) == CONST_INT 5374 && (INTVAL (operands[2]) == 128 5375 || (INTVAL (operands[2]) < 0 5376 && INTVAL (operands[2]) != -128))) 5377 { 5378 operands[2] = GEN_INT (-INTVAL (operands[2])); 5379 return "sub{l}\t{%2, %0|%0, %2}"; 5380 } 5381 return "add{l}\t{%2, %0|%0, %2}"; 5382 } 5383} 5384 [(set (attr "type") 5385 (cond [(eq_attr "alternative" "2") 5386 (const_string "lea") 5387 ; Current assemblers are broken and do not allow @GOTOFF in 5388 ; ought but a memory context. 5389 (match_operand:SI 2 "pic_symbolic_operand" "") 5390 (const_string "lea") 5391 (match_operand:SI 2 "incdec_operand" "") 5392 (const_string "incdec") 5393 ] 5394 (const_string "alu"))) 5395 (set_attr "mode" "SI")]) 5396 5397;; Convert lea to the lea pattern to avoid flags dependency. 5398(define_split 5399 [(set (match_operand 0 "register_operand" "") 5400 (plus (match_operand 1 "register_operand" "") 5401 (match_operand 2 "nonmemory_operand" ""))) 5402 (clobber (reg:CC FLAGS_REG))] 5403 "reload_completed 5404 && true_regnum (operands[0]) != true_regnum (operands[1])" 5405 [(const_int 0)] 5406{ 5407 rtx pat; 5408 /* In -fPIC mode the constructs like (const (unspec [symbol_ref])) 5409 may confuse gen_lowpart. */ 5410 if (GET_MODE (operands[0]) != Pmode) 5411 { 5412 operands[1] = gen_lowpart (Pmode, operands[1]); 5413 operands[2] = gen_lowpart (Pmode, operands[2]); 5414 } 5415 operands[0] = gen_lowpart (SImode, operands[0]); 5416 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]); 5417 if (Pmode != SImode) 5418 pat = gen_rtx_SUBREG (SImode, pat, 0); 5419 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5420 DONE; 5421}) 5422 5423;; It may seem that nonimmediate operand is proper one for operand 1. 5424;; The addsi_1 pattern allows nonimmediate operand at that place and 5425;; we take care in ix86_binary_operator_ok to not allow two memory 5426;; operands so proper swapping will be done in reload. This allow 5427;; patterns constructed from addsi_1 to match. 5428(define_insn "addsi_1_zext" 5429 [(set (match_operand:DI 0 "register_operand" "=r,r") 5430 (zero_extend:DI 5431 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") 5432 (match_operand:SI 2 "general_operand" "rmni,lni")))) 5433 (clobber (reg:CC FLAGS_REG))] 5434 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 5435{ 5436 switch (get_attr_type (insn)) 5437 { 5438 case TYPE_LEA: 5439 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 5440 return "lea{l}\t{%a2, %k0|%k0, %a2}"; 5441 5442 case TYPE_INCDEC: 5443 if (operands[2] == const1_rtx) 5444 return "inc{l}\t%k0"; 5445 else 5446 { 5447 gcc_assert (operands[2] == constm1_rtx); 5448 return "dec{l}\t%k0"; 5449 } 5450 5451 default: 5452 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5453 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5454 if (GET_CODE (operands[2]) == CONST_INT 5455 && (INTVAL (operands[2]) == 128 5456 || (INTVAL (operands[2]) < 0 5457 && INTVAL (operands[2]) != -128))) 5458 { 5459 operands[2] = GEN_INT (-INTVAL (operands[2])); 5460 return "sub{l}\t{%2, %k0|%k0, %2}"; 5461 } 5462 return "add{l}\t{%2, %k0|%k0, %2}"; 5463 } 5464} 5465 [(set (attr "type") 5466 (cond [(eq_attr "alternative" "1") 5467 (const_string "lea") 5468 ; Current assemblers are broken and do not allow @GOTOFF in 5469 ; ought but a memory context. 5470 (match_operand:SI 2 "pic_symbolic_operand" "") 5471 (const_string "lea") 5472 (match_operand:SI 2 "incdec_operand" "") 5473 (const_string "incdec") 5474 ] 5475 (const_string "alu"))) 5476 (set_attr "mode" "SI")]) 5477 5478;; Convert lea to the lea pattern to avoid flags dependency. 5479(define_split 5480 [(set (match_operand:DI 0 "register_operand" "") 5481 (zero_extend:DI 5482 (plus:SI (match_operand:SI 1 "register_operand" "") 5483 (match_operand:SI 2 "nonmemory_operand" "")))) 5484 (clobber (reg:CC FLAGS_REG))] 5485 "TARGET_64BIT && reload_completed 5486 && true_regnum (operands[0]) != true_regnum (operands[1])" 5487 [(set (match_dup 0) 5488 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))] 5489{ 5490 operands[1] = gen_lowpart (Pmode, operands[1]); 5491 operands[2] = gen_lowpart (Pmode, operands[2]); 5492}) 5493 5494(define_insn "*addsi_2" 5495 [(set (reg FLAGS_REG) 5496 (compare 5497 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 5498 (match_operand:SI 2 "general_operand" "rmni,rni")) 5499 (const_int 0))) 5500 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 5501 (plus:SI (match_dup 1) (match_dup 2)))] 5502 "ix86_match_ccmode (insn, CCGOCmode) 5503 && ix86_binary_operator_ok (PLUS, SImode, operands) 5504 /* Current assemblers are broken and do not allow @GOTOFF in 5505 ought but a memory context. */ 5506 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5507{ 5508 switch (get_attr_type (insn)) 5509 { 5510 case TYPE_INCDEC: 5511 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5512 if (operands[2] == const1_rtx) 5513 return "inc{l}\t%0"; 5514 else 5515 { 5516 gcc_assert (operands[2] == constm1_rtx); 5517 return "dec{l}\t%0"; 5518 } 5519 5520 default: 5521 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5522 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5523 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5524 if (GET_CODE (operands[2]) == CONST_INT 5525 && (INTVAL (operands[2]) == 128 5526 || (INTVAL (operands[2]) < 0 5527 && INTVAL (operands[2]) != -128))) 5528 { 5529 operands[2] = GEN_INT (-INTVAL (operands[2])); 5530 return "sub{l}\t{%2, %0|%0, %2}"; 5531 } 5532 return "add{l}\t{%2, %0|%0, %2}"; 5533 } 5534} 5535 [(set (attr "type") 5536 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5537 (const_string "incdec") 5538 (const_string "alu"))) 5539 (set_attr "mode" "SI")]) 5540 5541;; See comment for addsi_1_zext why we do use nonimmediate_operand 5542(define_insn "*addsi_2_zext" 5543 [(set (reg FLAGS_REG) 5544 (compare 5545 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 5546 (match_operand:SI 2 "general_operand" "rmni")) 5547 (const_int 0))) 5548 (set (match_operand:DI 0 "register_operand" "=r") 5549 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5550 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 5551 && ix86_binary_operator_ok (PLUS, SImode, operands) 5552 /* Current assemblers are broken and do not allow @GOTOFF in 5553 ought but a memory context. */ 5554 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5555{ 5556 switch (get_attr_type (insn)) 5557 { 5558 case TYPE_INCDEC: 5559 if (operands[2] == const1_rtx) 5560 return "inc{l}\t%k0"; 5561 else 5562 { 5563 gcc_assert (operands[2] == constm1_rtx); 5564 return "dec{l}\t%k0"; 5565 } 5566 5567 default: 5568 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5569 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5570 if (GET_CODE (operands[2]) == CONST_INT 5571 && (INTVAL (operands[2]) == 128 5572 || (INTVAL (operands[2]) < 0 5573 && INTVAL (operands[2]) != -128))) 5574 { 5575 operands[2] = GEN_INT (-INTVAL (operands[2])); 5576 return "sub{l}\t{%2, %k0|%k0, %2}"; 5577 } 5578 return "add{l}\t{%2, %k0|%k0, %2}"; 5579 } 5580} 5581 [(set (attr "type") 5582 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5583 (const_string "incdec") 5584 (const_string "alu"))) 5585 (set_attr "mode" "SI")]) 5586 5587(define_insn "*addsi_3" 5588 [(set (reg FLAGS_REG) 5589 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni")) 5590 (match_operand:SI 1 "nonimmediate_operand" "%0"))) 5591 (clobber (match_scratch:SI 0 "=r"))] 5592 "ix86_match_ccmode (insn, CCZmode) 5593 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5594 /* Current assemblers are broken and do not allow @GOTOFF in 5595 ought but a memory context. */ 5596 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5597{ 5598 switch (get_attr_type (insn)) 5599 { 5600 case TYPE_INCDEC: 5601 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5602 if (operands[2] == const1_rtx) 5603 return "inc{l}\t%0"; 5604 else 5605 { 5606 gcc_assert (operands[2] == constm1_rtx); 5607 return "dec{l}\t%0"; 5608 } 5609 5610 default: 5611 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5612 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5613 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5614 if (GET_CODE (operands[2]) == CONST_INT 5615 && (INTVAL (operands[2]) == 128 5616 || (INTVAL (operands[2]) < 0 5617 && INTVAL (operands[2]) != -128))) 5618 { 5619 operands[2] = GEN_INT (-INTVAL (operands[2])); 5620 return "sub{l}\t{%2, %0|%0, %2}"; 5621 } 5622 return "add{l}\t{%2, %0|%0, %2}"; 5623 } 5624} 5625 [(set (attr "type") 5626 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5627 (const_string "incdec") 5628 (const_string "alu"))) 5629 (set_attr "mode" "SI")]) 5630 5631;; See comment for addsi_1_zext why we do use nonimmediate_operand 5632(define_insn "*addsi_3_zext" 5633 [(set (reg FLAGS_REG) 5634 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni")) 5635 (match_operand:SI 1 "nonimmediate_operand" "%0"))) 5636 (set (match_operand:DI 0 "register_operand" "=r") 5637 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5638 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode) 5639 && ix86_binary_operator_ok (PLUS, SImode, operands) 5640 /* Current assemblers are broken and do not allow @GOTOFF in 5641 ought but a memory context. */ 5642 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5643{ 5644 switch (get_attr_type (insn)) 5645 { 5646 case TYPE_INCDEC: 5647 if (operands[2] == const1_rtx) 5648 return "inc{l}\t%k0"; 5649 else 5650 { 5651 gcc_assert (operands[2] == constm1_rtx); 5652 return "dec{l}\t%k0"; 5653 } 5654 5655 default: 5656 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5657 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5658 if (GET_CODE (operands[2]) == CONST_INT 5659 && (INTVAL (operands[2]) == 128 5660 || (INTVAL (operands[2]) < 0 5661 && INTVAL (operands[2]) != -128))) 5662 { 5663 operands[2] = GEN_INT (-INTVAL (operands[2])); 5664 return "sub{l}\t{%2, %k0|%k0, %2}"; 5665 } 5666 return "add{l}\t{%2, %k0|%k0, %2}"; 5667 } 5668} 5669 [(set (attr "type") 5670 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5671 (const_string "incdec") 5672 (const_string "alu"))) 5673 (set_attr "mode" "SI")]) 5674 5675; For comparisons against 1, -1 and 128, we may generate better code 5676; by converting cmp to add, inc or dec as done by peephole2. This pattern 5677; is matched then. We can't accept general immediate, because for 5678; case of overflows, the result is messed up. 5679; This pattern also don't hold of 0x80000000, since the value overflows 5680; when negated. 5681; Also carry flag is reversed compared to cmp, so this conversion is valid 5682; only for comparisons not depending on it. 5683(define_insn "*addsi_4" 5684 [(set (reg FLAGS_REG) 5685 (compare (match_operand:SI 1 "nonimmediate_operand" "0") 5686 (match_operand:SI 2 "const_int_operand" "n"))) 5687 (clobber (match_scratch:SI 0 "=rm"))] 5688 "ix86_match_ccmode (insn, CCGCmode) 5689 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000" 5690{ 5691 switch (get_attr_type (insn)) 5692 { 5693 case TYPE_INCDEC: 5694 if (operands[2] == constm1_rtx) 5695 return "inc{l}\t%0"; 5696 else 5697 { 5698 gcc_assert (operands[2] == const1_rtx); 5699 return "dec{l}\t%0"; 5700 } 5701 5702 default: 5703 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5704 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5705 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5706 if ((INTVAL (operands[2]) == -128 5707 || (INTVAL (operands[2]) > 0 5708 && INTVAL (operands[2]) != 128))) 5709 return "sub{l}\t{%2, %0|%0, %2}"; 5710 operands[2] = GEN_INT (-INTVAL (operands[2])); 5711 return "add{l}\t{%2, %0|%0, %2}"; 5712 } 5713} 5714 [(set (attr "type") 5715 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5716 (const_string "incdec") 5717 (const_string "alu"))) 5718 (set_attr "mode" "SI")]) 5719 5720(define_insn "*addsi_5" 5721 [(set (reg FLAGS_REG) 5722 (compare 5723 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 5724 (match_operand:SI 2 "general_operand" "rmni")) 5725 (const_int 0))) 5726 (clobber (match_scratch:SI 0 "=r"))] 5727 "ix86_match_ccmode (insn, CCGOCmode) 5728 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5729 /* Current assemblers are broken and do not allow @GOTOFF in 5730 ought but a memory context. */ 5731 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5732{ 5733 switch (get_attr_type (insn)) 5734 { 5735 case TYPE_INCDEC: 5736 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5737 if (operands[2] == const1_rtx) 5738 return "inc{l}\t%0"; 5739 else 5740 { 5741 gcc_assert (operands[2] == constm1_rtx); 5742 return "dec{l}\t%0"; 5743 } 5744 5745 default: 5746 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5747 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5748 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5749 if (GET_CODE (operands[2]) == CONST_INT 5750 && (INTVAL (operands[2]) == 128 5751 || (INTVAL (operands[2]) < 0 5752 && INTVAL (operands[2]) != -128))) 5753 { 5754 operands[2] = GEN_INT (-INTVAL (operands[2])); 5755 return "sub{l}\t{%2, %0|%0, %2}"; 5756 } 5757 return "add{l}\t{%2, %0|%0, %2}"; 5758 } 5759} 5760 [(set (attr "type") 5761 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5762 (const_string "incdec") 5763 (const_string "alu"))) 5764 (set_attr "mode" "SI")]) 5765 5766(define_expand "addhi3" 5767 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 5768 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "") 5769 (match_operand:HI 2 "general_operand" ""))) 5770 (clobber (reg:CC FLAGS_REG))])] 5771 "TARGET_HIMODE_MATH" 5772 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;") 5773 5774;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah 5775;; type optimizations enabled by define-splits. This is not important 5776;; for PII, and in fact harmful because of partial register stalls. 5777 5778(define_insn "*addhi_1_lea" 5779 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") 5780 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r") 5781 (match_operand:HI 2 "general_operand" "ri,rm,lni"))) 5782 (clobber (reg:CC FLAGS_REG))] 5783 "!TARGET_PARTIAL_REG_STALL 5784 && ix86_binary_operator_ok (PLUS, HImode, operands)" 5785{ 5786 switch (get_attr_type (insn)) 5787 { 5788 case TYPE_LEA: 5789 return "#"; 5790 case TYPE_INCDEC: 5791 if (operands[2] == const1_rtx) 5792 return "inc{w}\t%0"; 5793 else 5794 { 5795 gcc_assert (operands[2] == constm1_rtx); 5796 return "dec{w}\t%0"; 5797 } 5798 5799 default: 5800 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5801 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5802 if (GET_CODE (operands[2]) == CONST_INT 5803 && (INTVAL (operands[2]) == 128 5804 || (INTVAL (operands[2]) < 0 5805 && INTVAL (operands[2]) != -128))) 5806 { 5807 operands[2] = GEN_INT (-INTVAL (operands[2])); 5808 return "sub{w}\t{%2, %0|%0, %2}"; 5809 } 5810 return "add{w}\t{%2, %0|%0, %2}"; 5811 } 5812} 5813 [(set (attr "type") 5814 (if_then_else (eq_attr "alternative" "2") 5815 (const_string "lea") 5816 (if_then_else (match_operand:HI 2 "incdec_operand" "") 5817 (const_string "incdec") 5818 (const_string "alu")))) 5819 (set_attr "mode" "HI,HI,SI")]) 5820 5821(define_insn "*addhi_1" 5822 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 5823 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 5824 (match_operand:HI 2 "general_operand" "ri,rm"))) 5825 (clobber (reg:CC FLAGS_REG))] 5826 "TARGET_PARTIAL_REG_STALL 5827 && ix86_binary_operator_ok (PLUS, HImode, operands)" 5828{ 5829 switch (get_attr_type (insn)) 5830 { 5831 case TYPE_INCDEC: 5832 if (operands[2] == const1_rtx) 5833 return "inc{w}\t%0"; 5834 else 5835 { 5836 gcc_assert (operands[2] == constm1_rtx); 5837 return "dec{w}\t%0"; 5838 } 5839 5840 default: 5841 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5842 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5843 if (GET_CODE (operands[2]) == CONST_INT 5844 && (INTVAL (operands[2]) == 128 5845 || (INTVAL (operands[2]) < 0 5846 && INTVAL (operands[2]) != -128))) 5847 { 5848 operands[2] = GEN_INT (-INTVAL (operands[2])); 5849 return "sub{w}\t{%2, %0|%0, %2}"; 5850 } 5851 return "add{w}\t{%2, %0|%0, %2}"; 5852 } 5853} 5854 [(set (attr "type") 5855 (if_then_else (match_operand:HI 2 "incdec_operand" "") 5856 (const_string "incdec") 5857 (const_string "alu"))) 5858 (set_attr "mode" "HI")]) 5859 5860(define_insn "*addhi_2" 5861 [(set (reg FLAGS_REG) 5862 (compare 5863 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 5864 (match_operand:HI 2 "general_operand" "rmni,rni")) 5865 (const_int 0))) 5866 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 5867 (plus:HI (match_dup 1) (match_dup 2)))] 5868 "ix86_match_ccmode (insn, CCGOCmode) 5869 && ix86_binary_operator_ok (PLUS, HImode, operands)" 5870{ 5871 switch (get_attr_type (insn)) 5872 { 5873 case TYPE_INCDEC: 5874 if (operands[2] == const1_rtx) 5875 return "inc{w}\t%0"; 5876 else 5877 { 5878 gcc_assert (operands[2] == constm1_rtx); 5879 return "dec{w}\t%0"; 5880 } 5881 5882 default: 5883 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5884 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5885 if (GET_CODE (operands[2]) == CONST_INT 5886 && (INTVAL (operands[2]) == 128 5887 || (INTVAL (operands[2]) < 0 5888 && INTVAL (operands[2]) != -128))) 5889 { 5890 operands[2] = GEN_INT (-INTVAL (operands[2])); 5891 return "sub{w}\t{%2, %0|%0, %2}"; 5892 } 5893 return "add{w}\t{%2, %0|%0, %2}"; 5894 } 5895} 5896 [(set (attr "type") 5897 (if_then_else (match_operand:HI 2 "incdec_operand" "") 5898 (const_string "incdec") 5899 (const_string "alu"))) 5900 (set_attr "mode" "HI")]) 5901 5902(define_insn "*addhi_3" 5903 [(set (reg FLAGS_REG) 5904 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni")) 5905 (match_operand:HI 1 "nonimmediate_operand" "%0"))) 5906 (clobber (match_scratch:HI 0 "=r"))] 5907 "ix86_match_ccmode (insn, CCZmode) 5908 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 5909{ 5910 switch (get_attr_type (insn)) 5911 { 5912 case TYPE_INCDEC: 5913 if (operands[2] == const1_rtx) 5914 return "inc{w}\t%0"; 5915 else 5916 { 5917 gcc_assert (operands[2] == constm1_rtx); 5918 return "dec{w}\t%0"; 5919 } 5920 5921 default: 5922 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5923 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5924 if (GET_CODE (operands[2]) == CONST_INT 5925 && (INTVAL (operands[2]) == 128 5926 || (INTVAL (operands[2]) < 0 5927 && INTVAL (operands[2]) != -128))) 5928 { 5929 operands[2] = GEN_INT (-INTVAL (operands[2])); 5930 return "sub{w}\t{%2, %0|%0, %2}"; 5931 } 5932 return "add{w}\t{%2, %0|%0, %2}"; 5933 } 5934} 5935 [(set (attr "type") 5936 (if_then_else (match_operand:HI 2 "incdec_operand" "") 5937 (const_string "incdec") 5938 (const_string "alu"))) 5939 (set_attr "mode" "HI")]) 5940 5941; See comments above addsi_4 for details. 5942(define_insn "*addhi_4" 5943 [(set (reg FLAGS_REG) 5944 (compare (match_operand:HI 1 "nonimmediate_operand" "0") 5945 (match_operand:HI 2 "const_int_operand" "n"))) 5946 (clobber (match_scratch:HI 0 "=rm"))] 5947 "ix86_match_ccmode (insn, CCGCmode) 5948 && (INTVAL (operands[2]) & 0xffff) != 0x8000" 5949{ 5950 switch (get_attr_type (insn)) 5951 { 5952 case TYPE_INCDEC: 5953 if (operands[2] == constm1_rtx) 5954 return "inc{w}\t%0"; 5955 else 5956 { 5957 gcc_assert (operands[2] == const1_rtx); 5958 return "dec{w}\t%0"; 5959 } 5960 5961 default: 5962 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5963 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5964 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5965 if ((INTVAL (operands[2]) == -128 5966 || (INTVAL (operands[2]) > 0 5967 && INTVAL (operands[2]) != 128))) 5968 return "sub{w}\t{%2, %0|%0, %2}"; 5969 operands[2] = GEN_INT (-INTVAL (operands[2])); 5970 return "add{w}\t{%2, %0|%0, %2}"; 5971 } 5972} 5973 [(set (attr "type") 5974 (if_then_else (match_operand:HI 2 "incdec_operand" "") 5975 (const_string "incdec") 5976 (const_string "alu"))) 5977 (set_attr "mode" "SI")]) 5978 5979 5980(define_insn "*addhi_5" 5981 [(set (reg FLAGS_REG) 5982 (compare 5983 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0") 5984 (match_operand:HI 2 "general_operand" "rmni")) 5985 (const_int 0))) 5986 (clobber (match_scratch:HI 0 "=r"))] 5987 "ix86_match_ccmode (insn, CCGOCmode) 5988 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 5989{ 5990 switch (get_attr_type (insn)) 5991 { 5992 case TYPE_INCDEC: 5993 if (operands[2] == const1_rtx) 5994 return "inc{w}\t%0"; 5995 else 5996 { 5997 gcc_assert (operands[2] == constm1_rtx); 5998 return "dec{w}\t%0"; 5999 } 6000 6001 default: 6002 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 6003 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 6004 if (GET_CODE (operands[2]) == CONST_INT 6005 && (INTVAL (operands[2]) == 128 6006 || (INTVAL (operands[2]) < 0 6007 && INTVAL (operands[2]) != -128))) 6008 { 6009 operands[2] = GEN_INT (-INTVAL (operands[2])); 6010 return "sub{w}\t{%2, %0|%0, %2}"; 6011 } 6012 return "add{w}\t{%2, %0|%0, %2}"; 6013 } 6014} 6015 [(set (attr "type") 6016 (if_then_else (match_operand:HI 2 "incdec_operand" "") 6017 (const_string "incdec") 6018 (const_string "alu"))) 6019 (set_attr "mode" "HI")]) 6020 6021(define_expand "addqi3" 6022 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") 6023 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "") 6024 (match_operand:QI 2 "general_operand" ""))) 6025 (clobber (reg:CC FLAGS_REG))])] 6026 "TARGET_QIMODE_MATH" 6027 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;") 6028 6029;; %%% Potential partial reg stall on alternative 2. What to do? 6030(define_insn "*addqi_1_lea" 6031 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r") 6032 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r") 6033 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln"))) 6034 (clobber (reg:CC FLAGS_REG))] 6035 "!TARGET_PARTIAL_REG_STALL 6036 && ix86_binary_operator_ok (PLUS, QImode, operands)" 6037{ 6038 int widen = (which_alternative == 2); 6039 switch (get_attr_type (insn)) 6040 { 6041 case TYPE_LEA: 6042 return "#"; 6043 case TYPE_INCDEC: 6044 if (operands[2] == const1_rtx) 6045 return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; 6046 else 6047 { 6048 gcc_assert (operands[2] == constm1_rtx); 6049 return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; 6050 } 6051 6052 default: 6053 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 6054 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 6055 if (GET_CODE (operands[2]) == CONST_INT 6056 && (INTVAL (operands[2]) == 128 6057 || (INTVAL (operands[2]) < 0 6058 && INTVAL (operands[2]) != -128))) 6059 { 6060 operands[2] = GEN_INT (-INTVAL (operands[2])); 6061 if (widen) 6062 return "sub{l}\t{%2, %k0|%k0, %2}"; 6063 else 6064 return "sub{b}\t{%2, %0|%0, %2}"; 6065 } 6066 if (widen) 6067 return "add{l}\t{%k2, %k0|%k0, %k2}"; 6068 else 6069 return "add{b}\t{%2, %0|%0, %2}"; 6070 } 6071} 6072 [(set (attr "type") 6073 (if_then_else (eq_attr "alternative" "3") 6074 (const_string "lea") 6075 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6076 (const_string "incdec") 6077 (const_string "alu")))) 6078 (set_attr "mode" "QI,QI,SI,SI")]) 6079 6080(define_insn "*addqi_1" 6081 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 6082 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 6083 (match_operand:QI 2 "general_operand" "qn,qmn,rn"))) 6084 (clobber (reg:CC FLAGS_REG))] 6085 "TARGET_PARTIAL_REG_STALL 6086 && ix86_binary_operator_ok (PLUS, QImode, operands)" 6087{ 6088 int widen = (which_alternative == 2); 6089 switch (get_attr_type (insn)) 6090 { 6091 case TYPE_INCDEC: 6092 if (operands[2] == const1_rtx) 6093 return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; 6094 else 6095 { 6096 gcc_assert (operands[2] == constm1_rtx); 6097 return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; 6098 } 6099 6100 default: 6101 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 6102 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 6103 if (GET_CODE (operands[2]) == CONST_INT 6104 && (INTVAL (operands[2]) == 128 6105 || (INTVAL (operands[2]) < 0 6106 && INTVAL (operands[2]) != -128))) 6107 { 6108 operands[2] = GEN_INT (-INTVAL (operands[2])); 6109 if (widen) 6110 return "sub{l}\t{%2, %k0|%k0, %2}"; 6111 else 6112 return "sub{b}\t{%2, %0|%0, %2}"; 6113 } 6114 if (widen) 6115 return "add{l}\t{%k2, %k0|%k0, %k2}"; 6116 else 6117 return "add{b}\t{%2, %0|%0, %2}"; 6118 } 6119} 6120 [(set (attr "type") 6121 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6122 (const_string "incdec") 6123 (const_string "alu"))) 6124 (set_attr "mode" "QI,QI,SI")]) 6125 6126(define_insn "*addqi_1_slp" 6127 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 6128 (plus:QI (match_dup 0) 6129 (match_operand:QI 1 "general_operand" "qn,qnm"))) 6130 (clobber (reg:CC FLAGS_REG))] 6131 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 6132 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 6133{ 6134 switch (get_attr_type (insn)) 6135 { 6136 case TYPE_INCDEC: 6137 if (operands[1] == const1_rtx) 6138 return "inc{b}\t%0"; 6139 else 6140 { 6141 gcc_assert (operands[1] == constm1_rtx); 6142 return "dec{b}\t%0"; 6143 } 6144 6145 default: 6146 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */ 6147 if (GET_CODE (operands[1]) == CONST_INT 6148 && INTVAL (operands[1]) < 0) 6149 { 6150 operands[1] = GEN_INT (-INTVAL (operands[1])); 6151 return "sub{b}\t{%1, %0|%0, %1}"; 6152 } 6153 return "add{b}\t{%1, %0|%0, %1}"; 6154 } 6155} 6156 [(set (attr "type") 6157 (if_then_else (match_operand:QI 1 "incdec_operand" "") 6158 (const_string "incdec") 6159 (const_string "alu1"))) 6160 (set (attr "memory") 6161 (if_then_else (match_operand 1 "memory_operand" "") 6162 (const_string "load") 6163 (const_string "none"))) 6164 (set_attr "mode" "QI")]) 6165 6166(define_insn "*addqi_2" 6167 [(set (reg FLAGS_REG) 6168 (compare 6169 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 6170 (match_operand:QI 2 "general_operand" "qmni,qni")) 6171 (const_int 0))) 6172 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 6173 (plus:QI (match_dup 1) (match_dup 2)))] 6174 "ix86_match_ccmode (insn, CCGOCmode) 6175 && ix86_binary_operator_ok (PLUS, QImode, operands)" 6176{ 6177 switch (get_attr_type (insn)) 6178 { 6179 case TYPE_INCDEC: 6180 if (operands[2] == const1_rtx) 6181 return "inc{b}\t%0"; 6182 else 6183 { 6184 gcc_assert (operands[2] == constm1_rtx 6185 || (GET_CODE (operands[2]) == CONST_INT 6186 && INTVAL (operands[2]) == 255)); 6187 return "dec{b}\t%0"; 6188 } 6189 6190 default: 6191 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ 6192 if (GET_CODE (operands[2]) == CONST_INT 6193 && INTVAL (operands[2]) < 0) 6194 { 6195 operands[2] = GEN_INT (-INTVAL (operands[2])); 6196 return "sub{b}\t{%2, %0|%0, %2}"; 6197 } 6198 return "add{b}\t{%2, %0|%0, %2}"; 6199 } 6200} 6201 [(set (attr "type") 6202 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6203 (const_string "incdec") 6204 (const_string "alu"))) 6205 (set_attr "mode" "QI")]) 6206 6207(define_insn "*addqi_3" 6208 [(set (reg FLAGS_REG) 6209 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni")) 6210 (match_operand:QI 1 "nonimmediate_operand" "%0"))) 6211 (clobber (match_scratch:QI 0 "=q"))] 6212 "ix86_match_ccmode (insn, CCZmode) 6213 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6214{ 6215 switch (get_attr_type (insn)) 6216 { 6217 case TYPE_INCDEC: 6218 if (operands[2] == const1_rtx) 6219 return "inc{b}\t%0"; 6220 else 6221 { 6222 gcc_assert (operands[2] == constm1_rtx 6223 || (GET_CODE (operands[2]) == CONST_INT 6224 && INTVAL (operands[2]) == 255)); 6225 return "dec{b}\t%0"; 6226 } 6227 6228 default: 6229 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ 6230 if (GET_CODE (operands[2]) == CONST_INT 6231 && INTVAL (operands[2]) < 0) 6232 { 6233 operands[2] = GEN_INT (-INTVAL (operands[2])); 6234 return "sub{b}\t{%2, %0|%0, %2}"; 6235 } 6236 return "add{b}\t{%2, %0|%0, %2}"; 6237 } 6238} 6239 [(set (attr "type") 6240 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6241 (const_string "incdec") 6242 (const_string "alu"))) 6243 (set_attr "mode" "QI")]) 6244 6245; See comments above addsi_4 for details. 6246(define_insn "*addqi_4" 6247 [(set (reg FLAGS_REG) 6248 (compare (match_operand:QI 1 "nonimmediate_operand" "0") 6249 (match_operand:QI 2 "const_int_operand" "n"))) 6250 (clobber (match_scratch:QI 0 "=qm"))] 6251 "ix86_match_ccmode (insn, CCGCmode) 6252 && (INTVAL (operands[2]) & 0xff) != 0x80" 6253{ 6254 switch (get_attr_type (insn)) 6255 { 6256 case TYPE_INCDEC: 6257 if (operands[2] == constm1_rtx 6258 || (GET_CODE (operands[2]) == CONST_INT 6259 && INTVAL (operands[2]) == 255)) 6260 return "inc{b}\t%0"; 6261 else 6262 { 6263 gcc_assert (operands[2] == const1_rtx); 6264 return "dec{b}\t%0"; 6265 } 6266 6267 default: 6268 gcc_assert (rtx_equal_p (operands[0], operands[1])); 6269 if (INTVAL (operands[2]) < 0) 6270 { 6271 operands[2] = GEN_INT (-INTVAL (operands[2])); 6272 return "add{b}\t{%2, %0|%0, %2}"; 6273 } 6274 return "sub{b}\t{%2, %0|%0, %2}"; 6275 } 6276} 6277 [(set (attr "type") 6278 (if_then_else (match_operand:HI 2 "incdec_operand" "") 6279 (const_string "incdec") 6280 (const_string "alu"))) 6281 (set_attr "mode" "QI")]) 6282 6283 6284(define_insn "*addqi_5" 6285 [(set (reg FLAGS_REG) 6286 (compare 6287 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 6288 (match_operand:QI 2 "general_operand" "qmni")) 6289 (const_int 0))) 6290 (clobber (match_scratch:QI 0 "=q"))] 6291 "ix86_match_ccmode (insn, CCGOCmode) 6292 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6293{ 6294 switch (get_attr_type (insn)) 6295 { 6296 case TYPE_INCDEC: 6297 if (operands[2] == const1_rtx) 6298 return "inc{b}\t%0"; 6299 else 6300 { 6301 gcc_assert (operands[2] == constm1_rtx 6302 || (GET_CODE (operands[2]) == CONST_INT 6303 && INTVAL (operands[2]) == 255)); 6304 return "dec{b}\t%0"; 6305 } 6306 6307 default: 6308 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ 6309 if (GET_CODE (operands[2]) == CONST_INT 6310 && INTVAL (operands[2]) < 0) 6311 { 6312 operands[2] = GEN_INT (-INTVAL (operands[2])); 6313 return "sub{b}\t{%2, %0|%0, %2}"; 6314 } 6315 return "add{b}\t{%2, %0|%0, %2}"; 6316 } 6317} 6318 [(set (attr "type") 6319 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6320 (const_string "incdec") 6321 (const_string "alu"))) 6322 (set_attr "mode" "QI")]) 6323 6324 6325(define_insn "addqi_ext_1" 6326 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6327 (const_int 8) 6328 (const_int 8)) 6329 (plus:SI 6330 (zero_extract:SI 6331 (match_operand 1 "ext_register_operand" "0") 6332 (const_int 8) 6333 (const_int 8)) 6334 (match_operand:QI 2 "general_operand" "Qmn"))) 6335 (clobber (reg:CC FLAGS_REG))] 6336 "!TARGET_64BIT" 6337{ 6338 switch (get_attr_type (insn)) 6339 { 6340 case TYPE_INCDEC: 6341 if (operands[2] == const1_rtx) 6342 return "inc{b}\t%h0"; 6343 else 6344 { 6345 gcc_assert (operands[2] == constm1_rtx 6346 || (GET_CODE (operands[2]) == CONST_INT 6347 && INTVAL (operands[2]) == 255)); 6348 return "dec{b}\t%h0"; 6349 } 6350 6351 default: 6352 return "add{b}\t{%2, %h0|%h0, %2}"; 6353 } 6354} 6355 [(set (attr "type") 6356 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6357 (const_string "incdec") 6358 (const_string "alu"))) 6359 (set_attr "mode" "QI")]) 6360 6361(define_insn "*addqi_ext_1_rex64" 6362 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6363 (const_int 8) 6364 (const_int 8)) 6365 (plus:SI 6366 (zero_extract:SI 6367 (match_operand 1 "ext_register_operand" "0") 6368 (const_int 8) 6369 (const_int 8)) 6370 (match_operand:QI 2 "nonmemory_operand" "Qn"))) 6371 (clobber (reg:CC FLAGS_REG))] 6372 "TARGET_64BIT" 6373{ 6374 switch (get_attr_type (insn)) 6375 { 6376 case TYPE_INCDEC: 6377 if (operands[2] == const1_rtx) 6378 return "inc{b}\t%h0"; 6379 else 6380 { 6381 gcc_assert (operands[2] == constm1_rtx 6382 || (GET_CODE (operands[2]) == CONST_INT 6383 && INTVAL (operands[2]) == 255)); 6384 return "dec{b}\t%h0"; 6385 } 6386 6387 default: 6388 return "add{b}\t{%2, %h0|%h0, %2}"; 6389 } 6390} 6391 [(set (attr "type") 6392 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6393 (const_string "incdec") 6394 (const_string "alu"))) 6395 (set_attr "mode" "QI")]) 6396 6397(define_insn "*addqi_ext_2" 6398 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6399 (const_int 8) 6400 (const_int 8)) 6401 (plus:SI 6402 (zero_extract:SI 6403 (match_operand 1 "ext_register_operand" "%0") 6404 (const_int 8) 6405 (const_int 8)) 6406 (zero_extract:SI 6407 (match_operand 2 "ext_register_operand" "Q") 6408 (const_int 8) 6409 (const_int 8)))) 6410 (clobber (reg:CC FLAGS_REG))] 6411 "" 6412 "add{b}\t{%h2, %h0|%h0, %h2}" 6413 [(set_attr "type" "alu") 6414 (set_attr "mode" "QI")]) 6415 6416;; The patterns that match these are at the end of this file. 6417 6418(define_expand "addxf3" 6419 [(set (match_operand:XF 0 "register_operand" "") 6420 (plus:XF (match_operand:XF 1 "register_operand" "") 6421 (match_operand:XF 2 "register_operand" "")))] 6422 "TARGET_80387" 6423 "") 6424 6425(define_expand "adddf3" 6426 [(set (match_operand:DF 0 "register_operand" "") 6427 (plus:DF (match_operand:DF 1 "register_operand" "") 6428 (match_operand:DF 2 "nonimmediate_operand" "")))] 6429 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 6430 "") 6431 6432(define_expand "addsf3" 6433 [(set (match_operand:SF 0 "register_operand" "") 6434 (plus:SF (match_operand:SF 1 "register_operand" "") 6435 (match_operand:SF 2 "nonimmediate_operand" "")))] 6436 "TARGET_80387 || TARGET_SSE_MATH" 6437 "") 6438 6439;; Subtract instructions 6440 6441;; %%% splits for subditi3 6442 6443(define_expand "subti3" 6444 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "") 6445 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "") 6446 (match_operand:TI 2 "x86_64_general_operand" ""))) 6447 (clobber (reg:CC FLAGS_REG))])] 6448 "TARGET_64BIT" 6449 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;") 6450 6451(define_insn "*subti3_1" 6452 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o") 6453 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0") 6454 (match_operand:TI 2 "general_operand" "roiF,riF"))) 6455 (clobber (reg:CC FLAGS_REG))] 6456 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)" 6457 "#") 6458 6459(define_split 6460 [(set (match_operand:TI 0 "nonimmediate_operand" "") 6461 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "") 6462 (match_operand:TI 2 "general_operand" ""))) 6463 (clobber (reg:CC FLAGS_REG))] 6464 "TARGET_64BIT && reload_completed" 6465 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2))) 6466 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))]) 6467 (parallel [(set (match_dup 3) 6468 (minus:DI (match_dup 4) 6469 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) 6470 (match_dup 5)))) 6471 (clobber (reg:CC FLAGS_REG))])] 6472 "split_ti (operands+0, 1, operands+0, operands+3); 6473 split_ti (operands+1, 1, operands+1, operands+4); 6474 split_ti (operands+2, 1, operands+2, operands+5);") 6475 6476;; %%% splits for subsidi3 6477 6478(define_expand "subdi3" 6479 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 6480 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "") 6481 (match_operand:DI 2 "x86_64_general_operand" ""))) 6482 (clobber (reg:CC FLAGS_REG))])] 6483 "" 6484 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;") 6485 6486(define_insn "*subdi3_1" 6487 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") 6488 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6489 (match_operand:DI 2 "general_operand" "roiF,riF"))) 6490 (clobber (reg:CC FLAGS_REG))] 6491 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" 6492 "#") 6493 6494(define_split 6495 [(set (match_operand:DI 0 "nonimmediate_operand" "") 6496 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "") 6497 (match_operand:DI 2 "general_operand" ""))) 6498 (clobber (reg:CC FLAGS_REG))] 6499 "!TARGET_64BIT && reload_completed" 6500 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2))) 6501 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 6502 (parallel [(set (match_dup 3) 6503 (minus:SI (match_dup 4) 6504 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) 6505 (match_dup 5)))) 6506 (clobber (reg:CC FLAGS_REG))])] 6507 "split_di (operands+0, 1, operands+0, operands+3); 6508 split_di (operands+1, 1, operands+1, operands+4); 6509 split_di (operands+2, 1, operands+2, operands+5);") 6510 6511(define_insn "subdi3_carry_rex64" 6512 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6513 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6514 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "") 6515 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))) 6516 (clobber (reg:CC FLAGS_REG))] 6517 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" 6518 "sbb{q}\t{%2, %0|%0, %2}" 6519 [(set_attr "type" "alu") 6520 (set_attr "pent_pair" "pu") 6521 (set_attr "mode" "DI")]) 6522 6523(define_insn "*subdi_1_rex64" 6524 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6525 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6526 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 6527 (clobber (reg:CC FLAGS_REG))] 6528 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" 6529 "sub{q}\t{%2, %0|%0, %2}" 6530 [(set_attr "type" "alu") 6531 (set_attr "mode" "DI")]) 6532 6533(define_insn "*subdi_2_rex64" 6534 [(set (reg FLAGS_REG) 6535 (compare 6536 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6537 (match_operand:DI 2 "x86_64_general_operand" "re,rm")) 6538 (const_int 0))) 6539 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6540 (minus:DI (match_dup 1) (match_dup 2)))] 6541 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 6542 && ix86_binary_operator_ok (MINUS, DImode, operands)" 6543 "sub{q}\t{%2, %0|%0, %2}" 6544 [(set_attr "type" "alu") 6545 (set_attr "mode" "DI")]) 6546 6547(define_insn "*subdi_3_rex63" 6548 [(set (reg FLAGS_REG) 6549 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0") 6550 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 6551 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6552 (minus:DI (match_dup 1) (match_dup 2)))] 6553 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 6554 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6555 "sub{q}\t{%2, %0|%0, %2}" 6556 [(set_attr "type" "alu") 6557 (set_attr "mode" "DI")]) 6558 6559(define_insn "subqi3_carry" 6560 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 6561 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 6562 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "") 6563 (match_operand:QI 2 "general_operand" "qi,qm")))) 6564 (clobber (reg:CC FLAGS_REG))] 6565 "ix86_binary_operator_ok (MINUS, QImode, operands)" 6566 "sbb{b}\t{%2, %0|%0, %2}" 6567 [(set_attr "type" "alu") 6568 (set_attr "pent_pair" "pu") 6569 (set_attr "mode" "QI")]) 6570 6571(define_insn "subhi3_carry" 6572 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6573 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 6574 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "") 6575 (match_operand:HI 2 "general_operand" "ri,rm")))) 6576 (clobber (reg:CC FLAGS_REG))] 6577 "ix86_binary_operator_ok (MINUS, HImode, operands)" 6578 "sbb{w}\t{%2, %0|%0, %2}" 6579 [(set_attr "type" "alu") 6580 (set_attr "pent_pair" "pu") 6581 (set_attr "mode" "HI")]) 6582 6583(define_insn "subsi3_carry" 6584 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6585 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6586 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 6587 (match_operand:SI 2 "general_operand" "ri,rm")))) 6588 (clobber (reg:CC FLAGS_REG))] 6589 "ix86_binary_operator_ok (MINUS, SImode, operands)" 6590 "sbb{l}\t{%2, %0|%0, %2}" 6591 [(set_attr "type" "alu") 6592 (set_attr "pent_pair" "pu") 6593 (set_attr "mode" "SI")]) 6594 6595(define_insn "subsi3_carry_zext" 6596 [(set (match_operand:DI 0 "register_operand" "=rm,r") 6597 (zero_extend:DI 6598 (minus:SI (match_operand:SI 1 "register_operand" "0,0") 6599 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 6600 (match_operand:SI 2 "general_operand" "ri,rm"))))) 6601 (clobber (reg:CC FLAGS_REG))] 6602 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6603 "sbb{l}\t{%2, %k0|%k0, %2}" 6604 [(set_attr "type" "alu") 6605 (set_attr "pent_pair" "pu") 6606 (set_attr "mode" "SI")]) 6607 6608(define_expand "subsi3" 6609 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 6610 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "") 6611 (match_operand:SI 2 "general_operand" ""))) 6612 (clobber (reg:CC FLAGS_REG))])] 6613 "" 6614 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;") 6615 6616(define_insn "*subsi_1" 6617 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6618 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6619 (match_operand:SI 2 "general_operand" "ri,rm"))) 6620 (clobber (reg:CC FLAGS_REG))] 6621 "ix86_binary_operator_ok (MINUS, SImode, operands)" 6622 "sub{l}\t{%2, %0|%0, %2}" 6623 [(set_attr "type" "alu") 6624 (set_attr "mode" "SI")]) 6625 6626(define_insn "*subsi_1_zext" 6627 [(set (match_operand:DI 0 "register_operand" "=r") 6628 (zero_extend:DI 6629 (minus:SI (match_operand:SI 1 "register_operand" "0") 6630 (match_operand:SI 2 "general_operand" "rim")))) 6631 (clobber (reg:CC FLAGS_REG))] 6632 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6633 "sub{l}\t{%2, %k0|%k0, %2}" 6634 [(set_attr "type" "alu") 6635 (set_attr "mode" "SI")]) 6636 6637(define_insn "*subsi_2" 6638 [(set (reg FLAGS_REG) 6639 (compare 6640 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6641 (match_operand:SI 2 "general_operand" "ri,rm")) 6642 (const_int 0))) 6643 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6644 (minus:SI (match_dup 1) (match_dup 2)))] 6645 "ix86_match_ccmode (insn, CCGOCmode) 6646 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6647 "sub{l}\t{%2, %0|%0, %2}" 6648 [(set_attr "type" "alu") 6649 (set_attr "mode" "SI")]) 6650 6651(define_insn "*subsi_2_zext" 6652 [(set (reg FLAGS_REG) 6653 (compare 6654 (minus:SI (match_operand:SI 1 "register_operand" "0") 6655 (match_operand:SI 2 "general_operand" "rim")) 6656 (const_int 0))) 6657 (set (match_operand:DI 0 "register_operand" "=r") 6658 (zero_extend:DI 6659 (minus:SI (match_dup 1) 6660 (match_dup 2))))] 6661 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 6662 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6663 "sub{l}\t{%2, %k0|%k0, %2}" 6664 [(set_attr "type" "alu") 6665 (set_attr "mode" "SI")]) 6666 6667(define_insn "*subsi_3" 6668 [(set (reg FLAGS_REG) 6669 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0") 6670 (match_operand:SI 2 "general_operand" "ri,rm"))) 6671 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6672 (minus:SI (match_dup 1) (match_dup 2)))] 6673 "ix86_match_ccmode (insn, CCmode) 6674 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6675 "sub{l}\t{%2, %0|%0, %2}" 6676 [(set_attr "type" "alu") 6677 (set_attr "mode" "SI")]) 6678 6679(define_insn "*subsi_3_zext" 6680 [(set (reg FLAGS_REG) 6681 (compare (match_operand:SI 1 "register_operand" "0") 6682 (match_operand:SI 2 "general_operand" "rim"))) 6683 (set (match_operand:DI 0 "register_operand" "=r") 6684 (zero_extend:DI 6685 (minus:SI (match_dup 1) 6686 (match_dup 2))))] 6687 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 6688 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6689 "sub{q}\t{%2, %0|%0, %2}" 6690 [(set_attr "type" "alu") 6691 (set_attr "mode" "DI")]) 6692 6693(define_expand "subhi3" 6694 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 6695 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "") 6696 (match_operand:HI 2 "general_operand" ""))) 6697 (clobber (reg:CC FLAGS_REG))])] 6698 "TARGET_HIMODE_MATH" 6699 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;") 6700 6701(define_insn "*subhi_1" 6702 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6703 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 6704 (match_operand:HI 2 "general_operand" "ri,rm"))) 6705 (clobber (reg:CC FLAGS_REG))] 6706 "ix86_binary_operator_ok (MINUS, HImode, operands)" 6707 "sub{w}\t{%2, %0|%0, %2}" 6708 [(set_attr "type" "alu") 6709 (set_attr "mode" "HI")]) 6710 6711(define_insn "*subhi_2" 6712 [(set (reg FLAGS_REG) 6713 (compare 6714 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 6715 (match_operand:HI 2 "general_operand" "ri,rm")) 6716 (const_int 0))) 6717 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6718 (minus:HI (match_dup 1) (match_dup 2)))] 6719 "ix86_match_ccmode (insn, CCGOCmode) 6720 && ix86_binary_operator_ok (MINUS, HImode, operands)" 6721 "sub{w}\t{%2, %0|%0, %2}" 6722 [(set_attr "type" "alu") 6723 (set_attr "mode" "HI")]) 6724 6725(define_insn "*subhi_3" 6726 [(set (reg FLAGS_REG) 6727 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0") 6728 (match_operand:HI 2 "general_operand" "ri,rm"))) 6729 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6730 (minus:HI (match_dup 1) (match_dup 2)))] 6731 "ix86_match_ccmode (insn, CCmode) 6732 && ix86_binary_operator_ok (MINUS, HImode, operands)" 6733 "sub{w}\t{%2, %0|%0, %2}" 6734 [(set_attr "type" "alu") 6735 (set_attr "mode" "HI")]) 6736 6737(define_expand "subqi3" 6738 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") 6739 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "") 6740 (match_operand:QI 2 "general_operand" ""))) 6741 (clobber (reg:CC FLAGS_REG))])] 6742 "TARGET_QIMODE_MATH" 6743 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;") 6744 6745(define_insn "*subqi_1" 6746 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 6747 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 6748 (match_operand:QI 2 "general_operand" "qn,qmn"))) 6749 (clobber (reg:CC FLAGS_REG))] 6750 "ix86_binary_operator_ok (MINUS, QImode, operands)" 6751 "sub{b}\t{%2, %0|%0, %2}" 6752 [(set_attr "type" "alu") 6753 (set_attr "mode" "QI")]) 6754 6755(define_insn "*subqi_1_slp" 6756 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 6757 (minus:QI (match_dup 0) 6758 (match_operand:QI 1 "general_operand" "qn,qmn"))) 6759 (clobber (reg:CC FLAGS_REG))] 6760 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 6761 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 6762 "sub{b}\t{%1, %0|%0, %1}" 6763 [(set_attr "type" "alu1") 6764 (set_attr "mode" "QI")]) 6765 6766(define_insn "*subqi_2" 6767 [(set (reg FLAGS_REG) 6768 (compare 6769 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 6770 (match_operand:QI 2 "general_operand" "qi,qm")) 6771 (const_int 0))) 6772 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q") 6773 (minus:HI (match_dup 1) (match_dup 2)))] 6774 "ix86_match_ccmode (insn, CCGOCmode) 6775 && ix86_binary_operator_ok (MINUS, QImode, operands)" 6776 "sub{b}\t{%2, %0|%0, %2}" 6777 [(set_attr "type" "alu") 6778 (set_attr "mode" "QI")]) 6779 6780(define_insn "*subqi_3" 6781 [(set (reg FLAGS_REG) 6782 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0") 6783 (match_operand:QI 2 "general_operand" "qi,qm"))) 6784 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q") 6785 (minus:HI (match_dup 1) (match_dup 2)))] 6786 "ix86_match_ccmode (insn, CCmode) 6787 && ix86_binary_operator_ok (MINUS, QImode, operands)" 6788 "sub{b}\t{%2, %0|%0, %2}" 6789 [(set_attr "type" "alu") 6790 (set_attr "mode" "QI")]) 6791 6792;; The patterns that match these are at the end of this file. 6793 6794(define_expand "subxf3" 6795 [(set (match_operand:XF 0 "register_operand" "") 6796 (minus:XF (match_operand:XF 1 "register_operand" "") 6797 (match_operand:XF 2 "register_operand" "")))] 6798 "TARGET_80387" 6799 "") 6800 6801(define_expand "subdf3" 6802 [(set (match_operand:DF 0 "register_operand" "") 6803 (minus:DF (match_operand:DF 1 "register_operand" "") 6804 (match_operand:DF 2 "nonimmediate_operand" "")))] 6805 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 6806 "") 6807 6808(define_expand "subsf3" 6809 [(set (match_operand:SF 0 "register_operand" "") 6810 (minus:SF (match_operand:SF 1 "register_operand" "") 6811 (match_operand:SF 2 "nonimmediate_operand" "")))] 6812 "TARGET_80387 || TARGET_SSE_MATH" 6813 "") 6814 6815;; Multiply instructions 6816 6817(define_expand "muldi3" 6818 [(parallel [(set (match_operand:DI 0 "register_operand" "") 6819 (mult:DI (match_operand:DI 1 "register_operand" "") 6820 (match_operand:DI 2 "x86_64_general_operand" ""))) 6821 (clobber (reg:CC FLAGS_REG))])] 6822 "TARGET_64BIT" 6823 "") 6824 6825(define_insn "*muldi3_1_rex64" 6826 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 6827 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0") 6828 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr"))) 6829 (clobber (reg:CC FLAGS_REG))] 6830 "TARGET_64BIT 6831 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6832 "@ 6833 imul{q}\t{%2, %1, %0|%0, %1, %2} 6834 imul{q}\t{%2, %1, %0|%0, %1, %2} 6835 imul{q}\t{%2, %0|%0, %2}" 6836 [(set_attr "type" "imul") 6837 (set_attr "prefix_0f" "0,0,1") 6838 (set (attr "athlon_decode") 6839 (cond [(eq_attr "cpu" "athlon") 6840 (const_string "vector") 6841 (eq_attr "alternative" "1") 6842 (const_string "vector") 6843 (and (eq_attr "alternative" "2") 6844 (match_operand 1 "memory_operand" "")) 6845 (const_string "vector")] 6846 (const_string "direct"))) 6847 (set_attr "mode" "DI")]) 6848 6849(define_expand "mulsi3" 6850 [(parallel [(set (match_operand:SI 0 "register_operand" "") 6851 (mult:SI (match_operand:SI 1 "register_operand" "") 6852 (match_operand:SI 2 "general_operand" ""))) 6853 (clobber (reg:CC FLAGS_REG))])] 6854 "" 6855 "") 6856 6857(define_insn "*mulsi3_1" 6858 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 6859 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") 6860 (match_operand:SI 2 "general_operand" "K,i,mr"))) 6861 (clobber (reg:CC FLAGS_REG))] 6862 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 6863 "@ 6864 imul{l}\t{%2, %1, %0|%0, %1, %2} 6865 imul{l}\t{%2, %1, %0|%0, %1, %2} 6866 imul{l}\t{%2, %0|%0, %2}" 6867 [(set_attr "type" "imul") 6868 (set_attr "prefix_0f" "0,0,1") 6869 (set (attr "athlon_decode") 6870 (cond [(eq_attr "cpu" "athlon") 6871 (const_string "vector") 6872 (eq_attr "alternative" "1") 6873 (const_string "vector") 6874 (and (eq_attr "alternative" "2") 6875 (match_operand 1 "memory_operand" "")) 6876 (const_string "vector")] 6877 (const_string "direct"))) 6878 (set_attr "mode" "SI")]) 6879 6880(define_insn "*mulsi3_1_zext" 6881 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 6882 (zero_extend:DI 6883 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") 6884 (match_operand:SI 2 "general_operand" "K,i,mr")))) 6885 (clobber (reg:CC FLAGS_REG))] 6886 "TARGET_64BIT 6887 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6888 "@ 6889 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6890 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6891 imul{l}\t{%2, %k0|%k0, %2}" 6892 [(set_attr "type" "imul") 6893 (set_attr "prefix_0f" "0,0,1") 6894 (set (attr "athlon_decode") 6895 (cond [(eq_attr "cpu" "athlon") 6896 (const_string "vector") 6897 (eq_attr "alternative" "1") 6898 (const_string "vector") 6899 (and (eq_attr "alternative" "2") 6900 (match_operand 1 "memory_operand" "")) 6901 (const_string "vector")] 6902 (const_string "direct"))) 6903 (set_attr "mode" "SI")]) 6904 6905(define_expand "mulhi3" 6906 [(parallel [(set (match_operand:HI 0 "register_operand" "") 6907 (mult:HI (match_operand:HI 1 "register_operand" "") 6908 (match_operand:HI 2 "general_operand" ""))) 6909 (clobber (reg:CC FLAGS_REG))])] 6910 "TARGET_HIMODE_MATH" 6911 "") 6912 6913(define_insn "*mulhi3_1" 6914 [(set (match_operand:HI 0 "register_operand" "=r,r,r") 6915 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0") 6916 (match_operand:HI 2 "general_operand" "K,i,mr"))) 6917 (clobber (reg:CC FLAGS_REG))] 6918 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 6919 "@ 6920 imul{w}\t{%2, %1, %0|%0, %1, %2} 6921 imul{w}\t{%2, %1, %0|%0, %1, %2} 6922 imul{w}\t{%2, %0|%0, %2}" 6923 [(set_attr "type" "imul") 6924 (set_attr "prefix_0f" "0,0,1") 6925 (set (attr "athlon_decode") 6926 (cond [(eq_attr "cpu" "athlon") 6927 (const_string "vector") 6928 (eq_attr "alternative" "1,2") 6929 (const_string "vector")] 6930 (const_string "direct"))) 6931 (set_attr "mode" "HI")]) 6932 6933(define_expand "mulqi3" 6934 [(parallel [(set (match_operand:QI 0 "register_operand" "") 6935 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "") 6936 (match_operand:QI 2 "register_operand" ""))) 6937 (clobber (reg:CC FLAGS_REG))])] 6938 "TARGET_QIMODE_MATH" 6939 "") 6940 6941(define_insn "*mulqi3_1" 6942 [(set (match_operand:QI 0 "register_operand" "=a") 6943 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 6944 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 6945 (clobber (reg:CC FLAGS_REG))] 6946 "TARGET_QIMODE_MATH 6947 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6948 "mul{b}\t%2" 6949 [(set_attr "type" "imul") 6950 (set_attr "length_immediate" "0") 6951 (set (attr "athlon_decode") 6952 (if_then_else (eq_attr "cpu" "athlon") 6953 (const_string "vector") 6954 (const_string "direct"))) 6955 (set_attr "mode" "QI")]) 6956 6957(define_expand "umulqihi3" 6958 [(parallel [(set (match_operand:HI 0 "register_operand" "") 6959 (mult:HI (zero_extend:HI 6960 (match_operand:QI 1 "nonimmediate_operand" "")) 6961 (zero_extend:HI 6962 (match_operand:QI 2 "register_operand" "")))) 6963 (clobber (reg:CC FLAGS_REG))])] 6964 "TARGET_QIMODE_MATH" 6965 "") 6966 6967(define_insn "*umulqihi3_1" 6968 [(set (match_operand:HI 0 "register_operand" "=a") 6969 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0")) 6970 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm")))) 6971 (clobber (reg:CC FLAGS_REG))] 6972 "TARGET_QIMODE_MATH 6973 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6974 "mul{b}\t%2" 6975 [(set_attr "type" "imul") 6976 (set_attr "length_immediate" "0") 6977 (set (attr "athlon_decode") 6978 (if_then_else (eq_attr "cpu" "athlon") 6979 (const_string "vector") 6980 (const_string "direct"))) 6981 (set_attr "mode" "QI")]) 6982 6983(define_expand "mulqihi3" 6984 [(parallel [(set (match_operand:HI 0 "register_operand" "") 6985 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")) 6986 (sign_extend:HI (match_operand:QI 2 "register_operand" "")))) 6987 (clobber (reg:CC FLAGS_REG))])] 6988 "TARGET_QIMODE_MATH" 6989 "") 6990 6991(define_insn "*mulqihi3_insn" 6992 [(set (match_operand:HI 0 "register_operand" "=a") 6993 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0")) 6994 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm")))) 6995 (clobber (reg:CC FLAGS_REG))] 6996 "TARGET_QIMODE_MATH 6997 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6998 "imul{b}\t%2" 6999 [(set_attr "type" "imul") 7000 (set_attr "length_immediate" "0") 7001 (set (attr "athlon_decode") 7002 (if_then_else (eq_attr "cpu" "athlon") 7003 (const_string "vector") 7004 (const_string "direct"))) 7005 (set_attr "mode" "QI")]) 7006 7007(define_expand "umulditi3" 7008 [(parallel [(set (match_operand:TI 0 "register_operand" "") 7009 (mult:TI (zero_extend:TI 7010 (match_operand:DI 1 "nonimmediate_operand" "")) 7011 (zero_extend:TI 7012 (match_operand:DI 2 "register_operand" "")))) 7013 (clobber (reg:CC FLAGS_REG))])] 7014 "TARGET_64BIT" 7015 "") 7016 7017(define_insn "*umulditi3_insn" 7018 [(set (match_operand:TI 0 "register_operand" "=A") 7019 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0")) 7020 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm")))) 7021 (clobber (reg:CC FLAGS_REG))] 7022 "TARGET_64BIT 7023 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7024 "mul{q}\t%2" 7025 [(set_attr "type" "imul") 7026 (set_attr "length_immediate" "0") 7027 (set (attr "athlon_decode") 7028 (if_then_else (eq_attr "cpu" "athlon") 7029 (const_string "vector") 7030 (const_string "double"))) 7031 (set_attr "mode" "DI")]) 7032 7033;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers 7034(define_expand "umulsidi3" 7035 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7036 (mult:DI (zero_extend:DI 7037 (match_operand:SI 1 "nonimmediate_operand" "")) 7038 (zero_extend:DI 7039 (match_operand:SI 2 "register_operand" "")))) 7040 (clobber (reg:CC FLAGS_REG))])] 7041 "!TARGET_64BIT" 7042 "") 7043 7044(define_insn "*umulsidi3_insn" 7045 [(set (match_operand:DI 0 "register_operand" "=A") 7046 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0")) 7047 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))) 7048 (clobber (reg:CC FLAGS_REG))] 7049 "!TARGET_64BIT 7050 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7051 "mul{l}\t%2" 7052 [(set_attr "type" "imul") 7053 (set_attr "length_immediate" "0") 7054 (set (attr "athlon_decode") 7055 (if_then_else (eq_attr "cpu" "athlon") 7056 (const_string "vector") 7057 (const_string "double"))) 7058 (set_attr "mode" "SI")]) 7059 7060(define_expand "mulditi3" 7061 [(parallel [(set (match_operand:TI 0 "register_operand" "") 7062 (mult:TI (sign_extend:TI 7063 (match_operand:DI 1 "nonimmediate_operand" "")) 7064 (sign_extend:TI 7065 (match_operand:DI 2 "register_operand" "")))) 7066 (clobber (reg:CC FLAGS_REG))])] 7067 "TARGET_64BIT" 7068 "") 7069 7070(define_insn "*mulditi3_insn" 7071 [(set (match_operand:TI 0 "register_operand" "=A") 7072 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0")) 7073 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm")))) 7074 (clobber (reg:CC FLAGS_REG))] 7075 "TARGET_64BIT 7076 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7077 "imul{q}\t%2" 7078 [(set_attr "type" "imul") 7079 (set_attr "length_immediate" "0") 7080 (set (attr "athlon_decode") 7081 (if_then_else (eq_attr "cpu" "athlon") 7082 (const_string "vector") 7083 (const_string "double"))) 7084 (set_attr "mode" "DI")]) 7085 7086(define_expand "mulsidi3" 7087 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7088 (mult:DI (sign_extend:DI 7089 (match_operand:SI 1 "nonimmediate_operand" "")) 7090 (sign_extend:DI 7091 (match_operand:SI 2 "register_operand" "")))) 7092 (clobber (reg:CC FLAGS_REG))])] 7093 "!TARGET_64BIT" 7094 "") 7095 7096(define_insn "*mulsidi3_insn" 7097 [(set (match_operand:DI 0 "register_operand" "=A") 7098 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0")) 7099 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))) 7100 (clobber (reg:CC FLAGS_REG))] 7101 "!TARGET_64BIT 7102 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7103 "imul{l}\t%2" 7104 [(set_attr "type" "imul") 7105 (set_attr "length_immediate" "0") 7106 (set (attr "athlon_decode") 7107 (if_then_else (eq_attr "cpu" "athlon") 7108 (const_string "vector") 7109 (const_string "double"))) 7110 (set_attr "mode" "SI")]) 7111 7112(define_expand "umuldi3_highpart" 7113 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7114 (truncate:DI 7115 (lshiftrt:TI 7116 (mult:TI (zero_extend:TI 7117 (match_operand:DI 1 "nonimmediate_operand" "")) 7118 (zero_extend:TI 7119 (match_operand:DI 2 "register_operand" ""))) 7120 (const_int 64)))) 7121 (clobber (match_scratch:DI 3 "")) 7122 (clobber (reg:CC FLAGS_REG))])] 7123 "TARGET_64BIT" 7124 "") 7125 7126(define_insn "*umuldi3_highpart_rex64" 7127 [(set (match_operand:DI 0 "register_operand" "=d") 7128 (truncate:DI 7129 (lshiftrt:TI 7130 (mult:TI (zero_extend:TI 7131 (match_operand:DI 1 "nonimmediate_operand" "%a")) 7132 (zero_extend:TI 7133 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7134 (const_int 64)))) 7135 (clobber (match_scratch:DI 3 "=1")) 7136 (clobber (reg:CC FLAGS_REG))] 7137 "TARGET_64BIT 7138 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7139 "mul{q}\t%2" 7140 [(set_attr "type" "imul") 7141 (set_attr "length_immediate" "0") 7142 (set (attr "athlon_decode") 7143 (if_then_else (eq_attr "cpu" "athlon") 7144 (const_string "vector") 7145 (const_string "double"))) 7146 (set_attr "mode" "DI")]) 7147 7148(define_expand "umulsi3_highpart" 7149 [(parallel [(set (match_operand:SI 0 "register_operand" "") 7150 (truncate:SI 7151 (lshiftrt:DI 7152 (mult:DI (zero_extend:DI 7153 (match_operand:SI 1 "nonimmediate_operand" "")) 7154 (zero_extend:DI 7155 (match_operand:SI 2 "register_operand" ""))) 7156 (const_int 32)))) 7157 (clobber (match_scratch:SI 3 "")) 7158 (clobber (reg:CC FLAGS_REG))])] 7159 "" 7160 "") 7161 7162(define_insn "*umulsi3_highpart_insn" 7163 [(set (match_operand:SI 0 "register_operand" "=d") 7164 (truncate:SI 7165 (lshiftrt:DI 7166 (mult:DI (zero_extend:DI 7167 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7168 (zero_extend:DI 7169 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7170 (const_int 32)))) 7171 (clobber (match_scratch:SI 3 "=1")) 7172 (clobber (reg:CC FLAGS_REG))] 7173 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 7174 "mul{l}\t%2" 7175 [(set_attr "type" "imul") 7176 (set_attr "length_immediate" "0") 7177 (set (attr "athlon_decode") 7178 (if_then_else (eq_attr "cpu" "athlon") 7179 (const_string "vector") 7180 (const_string "double"))) 7181 (set_attr "mode" "SI")]) 7182 7183(define_insn "*umulsi3_highpart_zext" 7184 [(set (match_operand:DI 0 "register_operand" "=d") 7185 (zero_extend:DI (truncate:SI 7186 (lshiftrt:DI 7187 (mult:DI (zero_extend:DI 7188 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7189 (zero_extend:DI 7190 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7191 (const_int 32))))) 7192 (clobber (match_scratch:SI 3 "=1")) 7193 (clobber (reg:CC FLAGS_REG))] 7194 "TARGET_64BIT 7195 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7196 "mul{l}\t%2" 7197 [(set_attr "type" "imul") 7198 (set_attr "length_immediate" "0") 7199 (set (attr "athlon_decode") 7200 (if_then_else (eq_attr "cpu" "athlon") 7201 (const_string "vector") 7202 (const_string "double"))) 7203 (set_attr "mode" "SI")]) 7204 7205(define_expand "smuldi3_highpart" 7206 [(parallel [(set (match_operand:DI 0 "register_operand" "=d") 7207 (truncate:DI 7208 (lshiftrt:TI 7209 (mult:TI (sign_extend:TI 7210 (match_operand:DI 1 "nonimmediate_operand" "")) 7211 (sign_extend:TI 7212 (match_operand:DI 2 "register_operand" ""))) 7213 (const_int 64)))) 7214 (clobber (match_scratch:DI 3 "")) 7215 (clobber (reg:CC FLAGS_REG))])] 7216 "TARGET_64BIT" 7217 "") 7218 7219(define_insn "*smuldi3_highpart_rex64" 7220 [(set (match_operand:DI 0 "register_operand" "=d") 7221 (truncate:DI 7222 (lshiftrt:TI 7223 (mult:TI (sign_extend:TI 7224 (match_operand:DI 1 "nonimmediate_operand" "%a")) 7225 (sign_extend:TI 7226 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7227 (const_int 64)))) 7228 (clobber (match_scratch:DI 3 "=1")) 7229 (clobber (reg:CC FLAGS_REG))] 7230 "TARGET_64BIT 7231 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7232 "imul{q}\t%2" 7233 [(set_attr "type" "imul") 7234 (set (attr "athlon_decode") 7235 (if_then_else (eq_attr "cpu" "athlon") 7236 (const_string "vector") 7237 (const_string "double"))) 7238 (set_attr "mode" "DI")]) 7239 7240(define_expand "smulsi3_highpart" 7241 [(parallel [(set (match_operand:SI 0 "register_operand" "") 7242 (truncate:SI 7243 (lshiftrt:DI 7244 (mult:DI (sign_extend:DI 7245 (match_operand:SI 1 "nonimmediate_operand" "")) 7246 (sign_extend:DI 7247 (match_operand:SI 2 "register_operand" ""))) 7248 (const_int 32)))) 7249 (clobber (match_scratch:SI 3 "")) 7250 (clobber (reg:CC FLAGS_REG))])] 7251 "" 7252 "") 7253 7254(define_insn "*smulsi3_highpart_insn" 7255 [(set (match_operand:SI 0 "register_operand" "=d") 7256 (truncate:SI 7257 (lshiftrt:DI 7258 (mult:DI (sign_extend:DI 7259 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7260 (sign_extend:DI 7261 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7262 (const_int 32)))) 7263 (clobber (match_scratch:SI 3 "=1")) 7264 (clobber (reg:CC FLAGS_REG))] 7265 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 7266 "imul{l}\t%2" 7267 [(set_attr "type" "imul") 7268 (set (attr "athlon_decode") 7269 (if_then_else (eq_attr "cpu" "athlon") 7270 (const_string "vector") 7271 (const_string "double"))) 7272 (set_attr "mode" "SI")]) 7273 7274(define_insn "*smulsi3_highpart_zext" 7275 [(set (match_operand:DI 0 "register_operand" "=d") 7276 (zero_extend:DI (truncate:SI 7277 (lshiftrt:DI 7278 (mult:DI (sign_extend:DI 7279 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7280 (sign_extend:DI 7281 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7282 (const_int 32))))) 7283 (clobber (match_scratch:SI 3 "=1")) 7284 (clobber (reg:CC FLAGS_REG))] 7285 "TARGET_64BIT 7286 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7287 "imul{l}\t%2" 7288 [(set_attr "type" "imul") 7289 (set (attr "athlon_decode") 7290 (if_then_else (eq_attr "cpu" "athlon") 7291 (const_string "vector") 7292 (const_string "double"))) 7293 (set_attr "mode" "SI")]) 7294 7295;; The patterns that match these are at the end of this file. 7296 7297(define_expand "mulxf3" 7298 [(set (match_operand:XF 0 "register_operand" "") 7299 (mult:XF (match_operand:XF 1 "register_operand" "") 7300 (match_operand:XF 2 "register_operand" "")))] 7301 "TARGET_80387" 7302 "") 7303 7304(define_expand "muldf3" 7305 [(set (match_operand:DF 0 "register_operand" "") 7306 (mult:DF (match_operand:DF 1 "register_operand" "") 7307 (match_operand:DF 2 "nonimmediate_operand" "")))] 7308 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 7309 "") 7310 7311(define_expand "mulsf3" 7312 [(set (match_operand:SF 0 "register_operand" "") 7313 (mult:SF (match_operand:SF 1 "register_operand" "") 7314 (match_operand:SF 2 "nonimmediate_operand" "")))] 7315 "TARGET_80387 || TARGET_SSE_MATH" 7316 "") 7317 7318;; Divide instructions 7319 7320(define_insn "divqi3" 7321 [(set (match_operand:QI 0 "register_operand" "=a") 7322 (div:QI (match_operand:HI 1 "register_operand" "0") 7323 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 7324 (clobber (reg:CC FLAGS_REG))] 7325 "TARGET_QIMODE_MATH" 7326 "idiv{b}\t%2" 7327 [(set_attr "type" "idiv") 7328 (set_attr "mode" "QI")]) 7329 7330(define_insn "udivqi3" 7331 [(set (match_operand:QI 0 "register_operand" "=a") 7332 (udiv:QI (match_operand:HI 1 "register_operand" "0") 7333 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 7334 (clobber (reg:CC FLAGS_REG))] 7335 "TARGET_QIMODE_MATH" 7336 "div{b}\t%2" 7337 [(set_attr "type" "idiv") 7338 (set_attr "mode" "QI")]) 7339 7340;; The patterns that match these are at the end of this file. 7341 7342(define_expand "divxf3" 7343 [(set (match_operand:XF 0 "register_operand" "") 7344 (div:XF (match_operand:XF 1 "register_operand" "") 7345 (match_operand:XF 2 "register_operand" "")))] 7346 "TARGET_80387" 7347 "") 7348 7349(define_expand "divdf3" 7350 [(set (match_operand:DF 0 "register_operand" "") 7351 (div:DF (match_operand:DF 1 "register_operand" "") 7352 (match_operand:DF 2 "nonimmediate_operand" "")))] 7353 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 7354 "") 7355 7356(define_expand "divsf3" 7357 [(set (match_operand:SF 0 "register_operand" "") 7358 (div:SF (match_operand:SF 1 "register_operand" "") 7359 (match_operand:SF 2 "nonimmediate_operand" "")))] 7360 "TARGET_80387 || TARGET_SSE_MATH" 7361 "") 7362 7363;; Remainder instructions. 7364 7365(define_expand "divmoddi4" 7366 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7367 (div:DI (match_operand:DI 1 "register_operand" "") 7368 (match_operand:DI 2 "nonimmediate_operand" ""))) 7369 (set (match_operand:DI 3 "register_operand" "") 7370 (mod:DI (match_dup 1) (match_dup 2))) 7371 (clobber (reg:CC FLAGS_REG))])] 7372 "TARGET_64BIT" 7373 "") 7374 7375;; Allow to come the parameter in eax or edx to avoid extra moves. 7376;; Penalize eax case slightly because it results in worse scheduling 7377;; of code. 7378(define_insn "*divmoddi4_nocltd_rex64" 7379 [(set (match_operand:DI 0 "register_operand" "=&a,?a") 7380 (div:DI (match_operand:DI 2 "register_operand" "1,0") 7381 (match_operand:DI 3 "nonimmediate_operand" "rm,rm"))) 7382 (set (match_operand:DI 1 "register_operand" "=&d,&d") 7383 (mod:DI (match_dup 2) (match_dup 3))) 7384 (clobber (reg:CC FLAGS_REG))] 7385 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD" 7386 "#" 7387 [(set_attr "type" "multi")]) 7388 7389(define_insn "*divmoddi4_cltd_rex64" 7390 [(set (match_operand:DI 0 "register_operand" "=a") 7391 (div:DI (match_operand:DI 2 "register_operand" "a") 7392 (match_operand:DI 3 "nonimmediate_operand" "rm"))) 7393 (set (match_operand:DI 1 "register_operand" "=&d") 7394 (mod:DI (match_dup 2) (match_dup 3))) 7395 (clobber (reg:CC FLAGS_REG))] 7396 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)" 7397 "#" 7398 [(set_attr "type" "multi")]) 7399 7400(define_insn "*divmoddi_noext_rex64" 7401 [(set (match_operand:DI 0 "register_operand" "=a") 7402 (div:DI (match_operand:DI 1 "register_operand" "0") 7403 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7404 (set (match_operand:DI 3 "register_operand" "=d") 7405 (mod:DI (match_dup 1) (match_dup 2))) 7406 (use (match_operand:DI 4 "register_operand" "3")) 7407 (clobber (reg:CC FLAGS_REG))] 7408 "TARGET_64BIT" 7409 "idiv{q}\t%2" 7410 [(set_attr "type" "idiv") 7411 (set_attr "mode" "DI")]) 7412 7413(define_split 7414 [(set (match_operand:DI 0 "register_operand" "") 7415 (div:DI (match_operand:DI 1 "register_operand" "") 7416 (match_operand:DI 2 "nonimmediate_operand" ""))) 7417 (set (match_operand:DI 3 "register_operand" "") 7418 (mod:DI (match_dup 1) (match_dup 2))) 7419 (clobber (reg:CC FLAGS_REG))] 7420 "TARGET_64BIT && reload_completed" 7421 [(parallel [(set (match_dup 3) 7422 (ashiftrt:DI (match_dup 4) (const_int 63))) 7423 (clobber (reg:CC FLAGS_REG))]) 7424 (parallel [(set (match_dup 0) 7425 (div:DI (reg:DI 0) (match_dup 2))) 7426 (set (match_dup 3) 7427 (mod:DI (reg:DI 0) (match_dup 2))) 7428 (use (match_dup 3)) 7429 (clobber (reg:CC FLAGS_REG))])] 7430{ 7431 /* Avoid use of cltd in favor of a mov+shift. */ 7432 if (!TARGET_USE_CLTD && !optimize_size) 7433 { 7434 if (true_regnum (operands[1])) 7435 emit_move_insn (operands[0], operands[1]); 7436 else 7437 emit_move_insn (operands[3], operands[1]); 7438 operands[4] = operands[3]; 7439 } 7440 else 7441 { 7442 gcc_assert (!true_regnum (operands[1])); 7443 operands[4] = operands[1]; 7444 } 7445}) 7446 7447 7448(define_expand "divmodsi4" 7449 [(parallel [(set (match_operand:SI 0 "register_operand" "") 7450 (div:SI (match_operand:SI 1 "register_operand" "") 7451 (match_operand:SI 2 "nonimmediate_operand" ""))) 7452 (set (match_operand:SI 3 "register_operand" "") 7453 (mod:SI (match_dup 1) (match_dup 2))) 7454 (clobber (reg:CC FLAGS_REG))])] 7455 "" 7456 "") 7457 7458;; Allow to come the parameter in eax or edx to avoid extra moves. 7459;; Penalize eax case slightly because it results in worse scheduling 7460;; of code. 7461(define_insn "*divmodsi4_nocltd" 7462 [(set (match_operand:SI 0 "register_operand" "=&a,?a") 7463 (div:SI (match_operand:SI 2 "register_operand" "1,0") 7464 (match_operand:SI 3 "nonimmediate_operand" "rm,rm"))) 7465 (set (match_operand:SI 1 "register_operand" "=&d,&d") 7466 (mod:SI (match_dup 2) (match_dup 3))) 7467 (clobber (reg:CC FLAGS_REG))] 7468 "!optimize_size && !TARGET_USE_CLTD" 7469 "#" 7470 [(set_attr "type" "multi")]) 7471 7472(define_insn "*divmodsi4_cltd" 7473 [(set (match_operand:SI 0 "register_operand" "=a") 7474 (div:SI (match_operand:SI 2 "register_operand" "a") 7475 (match_operand:SI 3 "nonimmediate_operand" "rm"))) 7476 (set (match_operand:SI 1 "register_operand" "=&d") 7477 (mod:SI (match_dup 2) (match_dup 3))) 7478 (clobber (reg:CC FLAGS_REG))] 7479 "optimize_size || TARGET_USE_CLTD" 7480 "#" 7481 [(set_attr "type" "multi")]) 7482 7483(define_insn "*divmodsi_noext" 7484 [(set (match_operand:SI 0 "register_operand" "=a") 7485 (div:SI (match_operand:SI 1 "register_operand" "0") 7486 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7487 (set (match_operand:SI 3 "register_operand" "=d") 7488 (mod:SI (match_dup 1) (match_dup 2))) 7489 (use (match_operand:SI 4 "register_operand" "3")) 7490 (clobber (reg:CC FLAGS_REG))] 7491 "" 7492 "idiv{l}\t%2" 7493 [(set_attr "type" "idiv") 7494 (set_attr "mode" "SI")]) 7495 7496(define_split 7497 [(set (match_operand:SI 0 "register_operand" "") 7498 (div:SI (match_operand:SI 1 "register_operand" "") 7499 (match_operand:SI 2 "nonimmediate_operand" ""))) 7500 (set (match_operand:SI 3 "register_operand" "") 7501 (mod:SI (match_dup 1) (match_dup 2))) 7502 (clobber (reg:CC FLAGS_REG))] 7503 "reload_completed" 7504 [(parallel [(set (match_dup 3) 7505 (ashiftrt:SI (match_dup 4) (const_int 31))) 7506 (clobber (reg:CC FLAGS_REG))]) 7507 (parallel [(set (match_dup 0) 7508 (div:SI (reg:SI 0) (match_dup 2))) 7509 (set (match_dup 3) 7510 (mod:SI (reg:SI 0) (match_dup 2))) 7511 (use (match_dup 3)) 7512 (clobber (reg:CC FLAGS_REG))])] 7513{ 7514 /* Avoid use of cltd in favor of a mov+shift. */ 7515 if (!TARGET_USE_CLTD && !optimize_size) 7516 { 7517 if (true_regnum (operands[1])) 7518 emit_move_insn (operands[0], operands[1]); 7519 else 7520 emit_move_insn (operands[3], operands[1]); 7521 operands[4] = operands[3]; 7522 } 7523 else 7524 { 7525 gcc_assert (!true_regnum (operands[1])); 7526 operands[4] = operands[1]; 7527 } 7528}) 7529;; %%% Split me. 7530(define_insn "divmodhi4" 7531 [(set (match_operand:HI 0 "register_operand" "=a") 7532 (div:HI (match_operand:HI 1 "register_operand" "0") 7533 (match_operand:HI 2 "nonimmediate_operand" "rm"))) 7534 (set (match_operand:HI 3 "register_operand" "=&d") 7535 (mod:HI (match_dup 1) (match_dup 2))) 7536 (clobber (reg:CC FLAGS_REG))] 7537 "TARGET_HIMODE_MATH" 7538 "cwtd\;idiv{w}\t%2" 7539 [(set_attr "type" "multi") 7540 (set_attr "length_immediate" "0") 7541 (set_attr "mode" "SI")]) 7542 7543(define_insn "udivmoddi4" 7544 [(set (match_operand:DI 0 "register_operand" "=a") 7545 (udiv:DI (match_operand:DI 1 "register_operand" "0") 7546 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7547 (set (match_operand:DI 3 "register_operand" "=&d") 7548 (umod:DI (match_dup 1) (match_dup 2))) 7549 (clobber (reg:CC FLAGS_REG))] 7550 "TARGET_64BIT" 7551 "xor{q}\t%3, %3\;div{q}\t%2" 7552 [(set_attr "type" "multi") 7553 (set_attr "length_immediate" "0") 7554 (set_attr "mode" "DI")]) 7555 7556(define_insn "*udivmoddi4_noext" 7557 [(set (match_operand:DI 0 "register_operand" "=a") 7558 (udiv:DI (match_operand:DI 1 "register_operand" "0") 7559 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7560 (set (match_operand:DI 3 "register_operand" "=d") 7561 (umod:DI (match_dup 1) (match_dup 2))) 7562 (use (match_dup 3)) 7563 (clobber (reg:CC FLAGS_REG))] 7564 "TARGET_64BIT" 7565 "div{q}\t%2" 7566 [(set_attr "type" "idiv") 7567 (set_attr "mode" "DI")]) 7568 7569(define_split 7570 [(set (match_operand:DI 0 "register_operand" "") 7571 (udiv:DI (match_operand:DI 1 "register_operand" "") 7572 (match_operand:DI 2 "nonimmediate_operand" ""))) 7573 (set (match_operand:DI 3 "register_operand" "") 7574 (umod:DI (match_dup 1) (match_dup 2))) 7575 (clobber (reg:CC FLAGS_REG))] 7576 "TARGET_64BIT && reload_completed" 7577 [(set (match_dup 3) (const_int 0)) 7578 (parallel [(set (match_dup 0) 7579 (udiv:DI (match_dup 1) (match_dup 2))) 7580 (set (match_dup 3) 7581 (umod:DI (match_dup 1) (match_dup 2))) 7582 (use (match_dup 3)) 7583 (clobber (reg:CC FLAGS_REG))])] 7584 "") 7585 7586(define_insn "udivmodsi4" 7587 [(set (match_operand:SI 0 "register_operand" "=a") 7588 (udiv:SI (match_operand:SI 1 "register_operand" "0") 7589 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7590 (set (match_operand:SI 3 "register_operand" "=&d") 7591 (umod:SI (match_dup 1) (match_dup 2))) 7592 (clobber (reg:CC FLAGS_REG))] 7593 "" 7594 "xor{l}\t%3, %3\;div{l}\t%2" 7595 [(set_attr "type" "multi") 7596 (set_attr "length_immediate" "0") 7597 (set_attr "mode" "SI")]) 7598 7599(define_insn "*udivmodsi4_noext" 7600 [(set (match_operand:SI 0 "register_operand" "=a") 7601 (udiv:SI (match_operand:SI 1 "register_operand" "0") 7602 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7603 (set (match_operand:SI 3 "register_operand" "=d") 7604 (umod:SI (match_dup 1) (match_dup 2))) 7605 (use (match_dup 3)) 7606 (clobber (reg:CC FLAGS_REG))] 7607 "" 7608 "div{l}\t%2" 7609 [(set_attr "type" "idiv") 7610 (set_attr "mode" "SI")]) 7611 7612(define_split 7613 [(set (match_operand:SI 0 "register_operand" "") 7614 (udiv:SI (match_operand:SI 1 "register_operand" "") 7615 (match_operand:SI 2 "nonimmediate_operand" ""))) 7616 (set (match_operand:SI 3 "register_operand" "") 7617 (umod:SI (match_dup 1) (match_dup 2))) 7618 (clobber (reg:CC FLAGS_REG))] 7619 "reload_completed" 7620 [(set (match_dup 3) (const_int 0)) 7621 (parallel [(set (match_dup 0) 7622 (udiv:SI (match_dup 1) (match_dup 2))) 7623 (set (match_dup 3) 7624 (umod:SI (match_dup 1) (match_dup 2))) 7625 (use (match_dup 3)) 7626 (clobber (reg:CC FLAGS_REG))])] 7627 "") 7628 7629(define_expand "udivmodhi4" 7630 [(set (match_dup 4) (const_int 0)) 7631 (parallel [(set (match_operand:HI 0 "register_operand" "") 7632 (udiv:HI (match_operand:HI 1 "register_operand" "") 7633 (match_operand:HI 2 "nonimmediate_operand" ""))) 7634 (set (match_operand:HI 3 "register_operand" "") 7635 (umod:HI (match_dup 1) (match_dup 2))) 7636 (use (match_dup 4)) 7637 (clobber (reg:CC FLAGS_REG))])] 7638 "TARGET_HIMODE_MATH" 7639 "operands[4] = gen_reg_rtx (HImode);") 7640 7641(define_insn "*udivmodhi_noext" 7642 [(set (match_operand:HI 0 "register_operand" "=a") 7643 (udiv:HI (match_operand:HI 1 "register_operand" "0") 7644 (match_operand:HI 2 "nonimmediate_operand" "rm"))) 7645 (set (match_operand:HI 3 "register_operand" "=d") 7646 (umod:HI (match_dup 1) (match_dup 2))) 7647 (use (match_operand:HI 4 "register_operand" "3")) 7648 (clobber (reg:CC FLAGS_REG))] 7649 "" 7650 "div{w}\t%2" 7651 [(set_attr "type" "idiv") 7652 (set_attr "mode" "HI")]) 7653 7654;; We cannot use div/idiv for double division, because it causes 7655;; "division by zero" on the overflow and that's not what we expect 7656;; from truncate. Because true (non truncating) double division is 7657;; never generated, we can't create this insn anyway. 7658; 7659;(define_insn "" 7660; [(set (match_operand:SI 0 "register_operand" "=a") 7661; (truncate:SI 7662; (udiv:DI (match_operand:DI 1 "register_operand" "A") 7663; (zero_extend:DI 7664; (match_operand:SI 2 "nonimmediate_operand" "rm"))))) 7665; (set (match_operand:SI 3 "register_operand" "=d") 7666; (truncate:SI 7667; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2))))) 7668; (clobber (reg:CC FLAGS_REG))] 7669; "" 7670; "div{l}\t{%2, %0|%0, %2}" 7671; [(set_attr "type" "idiv")]) 7672 7673;;- Logical AND instructions 7674 7675;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al. 7676;; Note that this excludes ah. 7677 7678(define_insn "*testdi_1_rex64" 7679 [(set (reg FLAGS_REG) 7680 (compare 7681 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm") 7682 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re")) 7683 (const_int 0)))] 7684 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7685 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7686 "@ 7687 test{l}\t{%k1, %k0|%k0, %k1} 7688 test{l}\t{%k1, %k0|%k0, %k1} 7689 test{q}\t{%1, %0|%0, %1} 7690 test{q}\t{%1, %0|%0, %1} 7691 test{q}\t{%1, %0|%0, %1}" 7692 [(set_attr "type" "test") 7693 (set_attr "modrm" "0,1,0,1,1") 7694 (set_attr "mode" "SI,SI,DI,DI,DI") 7695 (set_attr "pent_pair" "uv,np,uv,np,uv")]) 7696 7697(define_insn "testsi_1" 7698 [(set (reg FLAGS_REG) 7699 (compare 7700 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm") 7701 (match_operand:SI 1 "general_operand" "in,in,rin")) 7702 (const_int 0)))] 7703 "ix86_match_ccmode (insn, CCNOmode) 7704 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7705 "test{l}\t{%1, %0|%0, %1}" 7706 [(set_attr "type" "test") 7707 (set_attr "modrm" "0,1,1") 7708 (set_attr "mode" "SI") 7709 (set_attr "pent_pair" "uv,np,uv")]) 7710 7711(define_expand "testsi_ccno_1" 7712 [(set (reg:CCNO FLAGS_REG) 7713 (compare:CCNO 7714 (and:SI (match_operand:SI 0 "nonimmediate_operand" "") 7715 (match_operand:SI 1 "nonmemory_operand" "")) 7716 (const_int 0)))] 7717 "" 7718 "") 7719 7720(define_insn "*testhi_1" 7721 [(set (reg FLAGS_REG) 7722 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm") 7723 (match_operand:HI 1 "general_operand" "n,n,rn")) 7724 (const_int 0)))] 7725 "ix86_match_ccmode (insn, CCNOmode) 7726 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7727 "test{w}\t{%1, %0|%0, %1}" 7728 [(set_attr "type" "test") 7729 (set_attr "modrm" "0,1,1") 7730 (set_attr "mode" "HI") 7731 (set_attr "pent_pair" "uv,np,uv")]) 7732 7733(define_expand "testqi_ccz_1" 7734 [(set (reg:CCZ FLAGS_REG) 7735 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "") 7736 (match_operand:QI 1 "nonmemory_operand" "")) 7737 (const_int 0)))] 7738 "" 7739 "") 7740 7741(define_insn "*testqi_1_maybe_si" 7742 [(set (reg FLAGS_REG) 7743 (compare 7744 (and:QI 7745 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r") 7746 (match_operand:QI 1 "general_operand" "n,n,qn,n")) 7747 (const_int 0)))] 7748 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 7749 && ix86_match_ccmode (insn, 7750 GET_CODE (operands[1]) == CONST_INT 7751 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)" 7752{ 7753 if (which_alternative == 3) 7754 { 7755 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0) 7756 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); 7757 return "test{l}\t{%1, %k0|%k0, %1}"; 7758 } 7759 return "test{b}\t{%1, %0|%0, %1}"; 7760} 7761 [(set_attr "type" "test") 7762 (set_attr "modrm" "0,1,1,1") 7763 (set_attr "mode" "QI,QI,QI,SI") 7764 (set_attr "pent_pair" "uv,np,uv,np")]) 7765 7766(define_insn "*testqi_1" 7767 [(set (reg FLAGS_REG) 7768 (compare 7769 (and:QI 7770 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm") 7771 (match_operand:QI 1 "general_operand" "n,n,qn")) 7772 (const_int 0)))] 7773 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 7774 && ix86_match_ccmode (insn, CCNOmode)" 7775 "test{b}\t{%1, %0|%0, %1}" 7776 [(set_attr "type" "test") 7777 (set_attr "modrm" "0,1,1") 7778 (set_attr "mode" "QI") 7779 (set_attr "pent_pair" "uv,np,uv")]) 7780 7781(define_expand "testqi_ext_ccno_0" 7782 [(set (reg:CCNO FLAGS_REG) 7783 (compare:CCNO 7784 (and:SI 7785 (zero_extract:SI 7786 (match_operand 0 "ext_register_operand" "") 7787 (const_int 8) 7788 (const_int 8)) 7789 (match_operand 1 "const_int_operand" "")) 7790 (const_int 0)))] 7791 "" 7792 "") 7793 7794(define_insn "*testqi_ext_0" 7795 [(set (reg FLAGS_REG) 7796 (compare 7797 (and:SI 7798 (zero_extract:SI 7799 (match_operand 0 "ext_register_operand" "Q") 7800 (const_int 8) 7801 (const_int 8)) 7802 (match_operand 1 "const_int_operand" "n")) 7803 (const_int 0)))] 7804 "ix86_match_ccmode (insn, CCNOmode)" 7805 "test{b}\t{%1, %h0|%h0, %1}" 7806 [(set_attr "type" "test") 7807 (set_attr "mode" "QI") 7808 (set_attr "length_immediate" "1") 7809 (set_attr "pent_pair" "np")]) 7810 7811(define_insn "*testqi_ext_1" 7812 [(set (reg FLAGS_REG) 7813 (compare 7814 (and:SI 7815 (zero_extract:SI 7816 (match_operand 0 "ext_register_operand" "Q") 7817 (const_int 8) 7818 (const_int 8)) 7819 (zero_extend:SI 7820 (match_operand:QI 1 "general_operand" "Qm"))) 7821 (const_int 0)))] 7822 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7823 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7824 "test{b}\t{%1, %h0|%h0, %1}" 7825 [(set_attr "type" "test") 7826 (set_attr "mode" "QI")]) 7827 7828(define_insn "*testqi_ext_1_rex64" 7829 [(set (reg FLAGS_REG) 7830 (compare 7831 (and:SI 7832 (zero_extract:SI 7833 (match_operand 0 "ext_register_operand" "Q") 7834 (const_int 8) 7835 (const_int 8)) 7836 (zero_extend:SI 7837 (match_operand:QI 1 "register_operand" "Q"))) 7838 (const_int 0)))] 7839 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 7840 "test{b}\t{%1, %h0|%h0, %1}" 7841 [(set_attr "type" "test") 7842 (set_attr "mode" "QI")]) 7843 7844(define_insn "*testqi_ext_2" 7845 [(set (reg FLAGS_REG) 7846 (compare 7847 (and:SI 7848 (zero_extract:SI 7849 (match_operand 0 "ext_register_operand" "Q") 7850 (const_int 8) 7851 (const_int 8)) 7852 (zero_extract:SI 7853 (match_operand 1 "ext_register_operand" "Q") 7854 (const_int 8) 7855 (const_int 8))) 7856 (const_int 0)))] 7857 "ix86_match_ccmode (insn, CCNOmode)" 7858 "test{b}\t{%h1, %h0|%h0, %h1}" 7859 [(set_attr "type" "test") 7860 (set_attr "mode" "QI")]) 7861 7862;; Combine likes to form bit extractions for some tests. Humor it. 7863(define_insn "*testqi_ext_3" 7864 [(set (reg FLAGS_REG) 7865 (compare (zero_extract:SI 7866 (match_operand 0 "nonimmediate_operand" "rm") 7867 (match_operand:SI 1 "const_int_operand" "") 7868 (match_operand:SI 2 "const_int_operand" "")) 7869 (const_int 0)))] 7870 "ix86_match_ccmode (insn, CCNOmode) 7871 && INTVAL (operands[1]) > 0 7872 && INTVAL (operands[2]) >= 0 7873 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 7874 && (GET_MODE (operands[0]) == SImode 7875 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode) 7876 || GET_MODE (operands[0]) == HImode 7877 || GET_MODE (operands[0]) == QImode)" 7878 "#") 7879 7880(define_insn "*testqi_ext_3_rex64" 7881 [(set (reg FLAGS_REG) 7882 (compare (zero_extract:DI 7883 (match_operand 0 "nonimmediate_operand" "rm") 7884 (match_operand:DI 1 "const_int_operand" "") 7885 (match_operand:DI 2 "const_int_operand" "")) 7886 (const_int 0)))] 7887 "TARGET_64BIT 7888 && ix86_match_ccmode (insn, CCNOmode) 7889 && INTVAL (operands[1]) > 0 7890 && INTVAL (operands[2]) >= 0 7891 /* Ensure that resulting mask is zero or sign extended operand. */ 7892 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 7893 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64 7894 && INTVAL (operands[1]) > 32)) 7895 && (GET_MODE (operands[0]) == SImode 7896 || GET_MODE (operands[0]) == DImode 7897 || GET_MODE (operands[0]) == HImode 7898 || GET_MODE (operands[0]) == QImode)" 7899 "#") 7900 7901(define_split 7902 [(set (match_operand 0 "flags_reg_operand" "") 7903 (match_operator 1 "compare_operator" 7904 [(zero_extract 7905 (match_operand 2 "nonimmediate_operand" "") 7906 (match_operand 3 "const_int_operand" "") 7907 (match_operand 4 "const_int_operand" "")) 7908 (const_int 0)]))] 7909 "ix86_match_ccmode (insn, CCNOmode)" 7910 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))] 7911{ 7912 rtx val = operands[2]; 7913 HOST_WIDE_INT len = INTVAL (operands[3]); 7914 HOST_WIDE_INT pos = INTVAL (operands[4]); 7915 HOST_WIDE_INT mask; 7916 enum machine_mode mode, submode; 7917 7918 mode = GET_MODE (val); 7919 if (GET_CODE (val) == MEM) 7920 { 7921 /* ??? Combine likes to put non-volatile mem extractions in QImode 7922 no matter the size of the test. So find a mode that works. */ 7923 if (! MEM_VOLATILE_P (val)) 7924 { 7925 mode = smallest_mode_for_size (pos + len, MODE_INT); 7926 val = adjust_address (val, mode, 0); 7927 } 7928 } 7929 else if (GET_CODE (val) == SUBREG 7930 && (submode = GET_MODE (SUBREG_REG (val)), 7931 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)) 7932 && pos + len <= GET_MODE_BITSIZE (submode)) 7933 { 7934 /* Narrow a paradoxical subreg to prevent partial register stalls. */ 7935 mode = submode; 7936 val = SUBREG_REG (val); 7937 } 7938 else if (mode == HImode && pos + len <= 8) 7939 { 7940 /* Small HImode tests can be converted to QImode. */ 7941 mode = QImode; 7942 val = gen_lowpart (QImode, val); 7943 } 7944 7945 if (len == HOST_BITS_PER_WIDE_INT) 7946 mask = -1; 7947 else 7948 mask = ((HOST_WIDE_INT)1 << len) - 1; 7949 mask <<= pos; 7950 7951 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode)); 7952}) 7953 7954;; Convert HImode/SImode test instructions with immediate to QImode ones. 7955;; i386 does not allow to encode test with 8bit sign extended immediate, so 7956;; this is relatively important trick. 7957;; Do the conversion only post-reload to avoid limiting of the register class 7958;; to QI regs. 7959(define_split 7960 [(set (match_operand 0 "flags_reg_operand" "") 7961 (match_operator 1 "compare_operator" 7962 [(and (match_operand 2 "register_operand" "") 7963 (match_operand 3 "const_int_operand" "")) 7964 (const_int 0)]))] 7965 "reload_completed 7966 && QI_REG_P (operands[2]) 7967 && GET_MODE (operands[2]) != QImode 7968 && ((ix86_match_ccmode (insn, CCZmode) 7969 && !(INTVAL (operands[3]) & ~(255 << 8))) 7970 || (ix86_match_ccmode (insn, CCNOmode) 7971 && !(INTVAL (operands[3]) & ~(127 << 8))))" 7972 [(set (match_dup 0) 7973 (match_op_dup 1 7974 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8)) 7975 (match_dup 3)) 7976 (const_int 0)]))] 7977 "operands[2] = gen_lowpart (SImode, operands[2]); 7978 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);") 7979 7980(define_split 7981 [(set (match_operand 0 "flags_reg_operand" "") 7982 (match_operator 1 "compare_operator" 7983 [(and (match_operand 2 "nonimmediate_operand" "") 7984 (match_operand 3 "const_int_operand" "")) 7985 (const_int 0)]))] 7986 "reload_completed 7987 && GET_MODE (operands[2]) != QImode 7988 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2])) 7989 && ((ix86_match_ccmode (insn, CCZmode) 7990 && !(INTVAL (operands[3]) & ~255)) 7991 || (ix86_match_ccmode (insn, CCNOmode) 7992 && !(INTVAL (operands[3]) & ~127)))" 7993 [(set (match_dup 0) 7994 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 7995 (const_int 0)]))] 7996 "operands[2] = gen_lowpart (QImode, operands[2]); 7997 operands[3] = gen_lowpart (QImode, operands[3]);") 7998 7999 8000;; %%% This used to optimize known byte-wide and operations to memory, 8001;; and sometimes to QImode registers. If this is considered useful, 8002;; it should be done with splitters. 8003 8004(define_expand "anddi3" 8005 [(set (match_operand:DI 0 "nonimmediate_operand" "") 8006 (and:DI (match_operand:DI 1 "nonimmediate_operand" "") 8007 (match_operand:DI 2 "x86_64_szext_general_operand" ""))) 8008 (clobber (reg:CC FLAGS_REG))] 8009 "TARGET_64BIT" 8010 "ix86_expand_binary_operator (AND, DImode, operands); DONE;") 8011 8012(define_insn "*anddi_1_rex64" 8013 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r") 8014 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm") 8015 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L"))) 8016 (clobber (reg:CC FLAGS_REG))] 8017 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)" 8018{ 8019 switch (get_attr_type (insn)) 8020 { 8021 case TYPE_IMOVX: 8022 { 8023 enum machine_mode mode; 8024 8025 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 8026 if (INTVAL (operands[2]) == 0xff) 8027 mode = QImode; 8028 else 8029 { 8030 gcc_assert (INTVAL (operands[2]) == 0xffff); 8031 mode = HImode; 8032 } 8033 8034 operands[1] = gen_lowpart (mode, operands[1]); 8035 if (mode == QImode) 8036 return "movz{bq|x}\t{%1,%0|%0, %1}"; 8037 else 8038 return "movz{wq|x}\t{%1,%0|%0, %1}"; 8039 } 8040 8041 default: 8042 gcc_assert (rtx_equal_p (operands[0], operands[1])); 8043 if (get_attr_mode (insn) == MODE_SI) 8044 return "and{l}\t{%k2, %k0|%k0, %k2}"; 8045 else 8046 return "and{q}\t{%2, %0|%0, %2}"; 8047 } 8048} 8049 [(set_attr "type" "alu,alu,alu,imovx") 8050 (set_attr "length_immediate" "*,*,*,0") 8051 (set_attr "mode" "SI,DI,DI,DI")]) 8052 8053(define_insn "*anddi_2" 8054 [(set (reg FLAGS_REG) 8055 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") 8056 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re")) 8057 (const_int 0))) 8058 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm") 8059 (and:DI (match_dup 1) (match_dup 2)))] 8060 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8061 && ix86_binary_operator_ok (AND, DImode, operands)" 8062 "@ 8063 and{l}\t{%k2, %k0|%k0, %k2} 8064 and{q}\t{%2, %0|%0, %2} 8065 and{q}\t{%2, %0|%0, %2}" 8066 [(set_attr "type" "alu") 8067 (set_attr "mode" "SI,DI,DI")]) 8068 8069(define_expand "andsi3" 8070 [(set (match_operand:SI 0 "nonimmediate_operand" "") 8071 (and:SI (match_operand:SI 1 "nonimmediate_operand" "") 8072 (match_operand:SI 2 "general_operand" ""))) 8073 (clobber (reg:CC FLAGS_REG))] 8074 "" 8075 "ix86_expand_binary_operator (AND, SImode, operands); DONE;") 8076 8077(define_insn "*andsi_1" 8078 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r") 8079 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm") 8080 (match_operand:SI 2 "general_operand" "ri,rm,L"))) 8081 (clobber (reg:CC FLAGS_REG))] 8082 "ix86_binary_operator_ok (AND, SImode, operands)" 8083{ 8084 switch (get_attr_type (insn)) 8085 { 8086 case TYPE_IMOVX: 8087 { 8088 enum machine_mode mode; 8089 8090 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 8091 if (INTVAL (operands[2]) == 0xff) 8092 mode = QImode; 8093 else 8094 { 8095 gcc_assert (INTVAL (operands[2]) == 0xffff); 8096 mode = HImode; 8097 } 8098 8099 operands[1] = gen_lowpart (mode, operands[1]); 8100 if (mode == QImode) 8101 return "movz{bl|x}\t{%1,%0|%0, %1}"; 8102 else 8103 return "movz{wl|x}\t{%1,%0|%0, %1}"; 8104 } 8105 8106 default: 8107 gcc_assert (rtx_equal_p (operands[0], operands[1])); 8108 return "and{l}\t{%2, %0|%0, %2}"; 8109 } 8110} 8111 [(set_attr "type" "alu,alu,imovx") 8112 (set_attr "length_immediate" "*,*,0") 8113 (set_attr "mode" "SI")]) 8114 8115(define_split 8116 [(set (match_operand 0 "register_operand" "") 8117 (and (match_dup 0) 8118 (const_int -65536))) 8119 (clobber (reg:CC FLAGS_REG))] 8120 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)" 8121 [(set (strict_low_part (match_dup 1)) (const_int 0))] 8122 "operands[1] = gen_lowpart (HImode, operands[0]);") 8123 8124(define_split 8125 [(set (match_operand 0 "ext_register_operand" "") 8126 (and (match_dup 0) 8127 (const_int -256))) 8128 (clobber (reg:CC FLAGS_REG))] 8129 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed" 8130 [(set (strict_low_part (match_dup 1)) (const_int 0))] 8131 "operands[1] = gen_lowpart (QImode, operands[0]);") 8132 8133(define_split 8134 [(set (match_operand 0 "ext_register_operand" "") 8135 (and (match_dup 0) 8136 (const_int -65281))) 8137 (clobber (reg:CC FLAGS_REG))] 8138 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed" 8139 [(parallel [(set (zero_extract:SI (match_dup 0) 8140 (const_int 8) 8141 (const_int 8)) 8142 (xor:SI 8143 (zero_extract:SI (match_dup 0) 8144 (const_int 8) 8145 (const_int 8)) 8146 (zero_extract:SI (match_dup 0) 8147 (const_int 8) 8148 (const_int 8)))) 8149 (clobber (reg:CC FLAGS_REG))])] 8150 "operands[0] = gen_lowpart (SImode, operands[0]);") 8151 8152;; See comment for addsi_1_zext why we do use nonimmediate_operand 8153(define_insn "*andsi_1_zext" 8154 [(set (match_operand:DI 0 "register_operand" "=r") 8155 (zero_extend:DI 8156 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8157 (match_operand:SI 2 "general_operand" "rim")))) 8158 (clobber (reg:CC FLAGS_REG))] 8159 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" 8160 "and{l}\t{%2, %k0|%k0, %2}" 8161 [(set_attr "type" "alu") 8162 (set_attr "mode" "SI")]) 8163 8164(define_insn "*andsi_2" 8165 [(set (reg FLAGS_REG) 8166 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8167 (match_operand:SI 2 "general_operand" "rim,ri")) 8168 (const_int 0))) 8169 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 8170 (and:SI (match_dup 1) (match_dup 2)))] 8171 "ix86_match_ccmode (insn, CCNOmode) 8172 && ix86_binary_operator_ok (AND, SImode, operands)" 8173 "and{l}\t{%2, %0|%0, %2}" 8174 [(set_attr "type" "alu") 8175 (set_attr "mode" "SI")]) 8176 8177;; See comment for addsi_1_zext why we do use nonimmediate_operand 8178(define_insn "*andsi_2_zext" 8179 [(set (reg FLAGS_REG) 8180 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8181 (match_operand:SI 2 "general_operand" "rim")) 8182 (const_int 0))) 8183 (set (match_operand:DI 0 "register_operand" "=r") 8184 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] 8185 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8186 && ix86_binary_operator_ok (AND, SImode, operands)" 8187 "and{l}\t{%2, %k0|%k0, %2}" 8188 [(set_attr "type" "alu") 8189 (set_attr "mode" "SI")]) 8190 8191(define_expand "andhi3" 8192 [(set (match_operand:HI 0 "nonimmediate_operand" "") 8193 (and:HI (match_operand:HI 1 "nonimmediate_operand" "") 8194 (match_operand:HI 2 "general_operand" ""))) 8195 (clobber (reg:CC FLAGS_REG))] 8196 "TARGET_HIMODE_MATH" 8197 "ix86_expand_binary_operator (AND, HImode, operands); DONE;") 8198 8199(define_insn "*andhi_1" 8200 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") 8201 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm") 8202 (match_operand:HI 2 "general_operand" "ri,rm,L"))) 8203 (clobber (reg:CC FLAGS_REG))] 8204 "ix86_binary_operator_ok (AND, HImode, operands)" 8205{ 8206 switch (get_attr_type (insn)) 8207 { 8208 case TYPE_IMOVX: 8209 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 8210 gcc_assert (INTVAL (operands[2]) == 0xff); 8211 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}"; 8212 8213 default: 8214 gcc_assert (rtx_equal_p (operands[0], operands[1])); 8215 8216 return "and{w}\t{%2, %0|%0, %2}"; 8217 } 8218} 8219 [(set_attr "type" "alu,alu,imovx") 8220 (set_attr "length_immediate" "*,*,0") 8221 (set_attr "mode" "HI,HI,SI")]) 8222 8223(define_insn "*andhi_2" 8224 [(set (reg FLAGS_REG) 8225 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 8226 (match_operand:HI 2 "general_operand" "rim,ri")) 8227 (const_int 0))) 8228 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 8229 (and:HI (match_dup 1) (match_dup 2)))] 8230 "ix86_match_ccmode (insn, CCNOmode) 8231 && ix86_binary_operator_ok (AND, HImode, operands)" 8232 "and{w}\t{%2, %0|%0, %2}" 8233 [(set_attr "type" "alu") 8234 (set_attr "mode" "HI")]) 8235 8236(define_expand "andqi3" 8237 [(set (match_operand:QI 0 "nonimmediate_operand" "") 8238 (and:QI (match_operand:QI 1 "nonimmediate_operand" "") 8239 (match_operand:QI 2 "general_operand" ""))) 8240 (clobber (reg:CC FLAGS_REG))] 8241 "TARGET_QIMODE_MATH" 8242 "ix86_expand_binary_operator (AND, QImode, operands); DONE;") 8243 8244;; %%% Potential partial reg stall on alternative 2. What to do? 8245(define_insn "*andqi_1" 8246 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 8247 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8248 (match_operand:QI 2 "general_operand" "qi,qmi,ri"))) 8249 (clobber (reg:CC FLAGS_REG))] 8250 "ix86_binary_operator_ok (AND, QImode, operands)" 8251 "@ 8252 and{b}\t{%2, %0|%0, %2} 8253 and{b}\t{%2, %0|%0, %2} 8254 and{l}\t{%k2, %k0|%k0, %k2}" 8255 [(set_attr "type" "alu") 8256 (set_attr "mode" "QI,QI,SI")]) 8257 8258(define_insn "*andqi_1_slp" 8259 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 8260 (and:QI (match_dup 0) 8261 (match_operand:QI 1 "general_operand" "qi,qmi"))) 8262 (clobber (reg:CC FLAGS_REG))] 8263 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8264 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8265 "and{b}\t{%1, %0|%0, %1}" 8266 [(set_attr "type" "alu1") 8267 (set_attr "mode" "QI")]) 8268 8269(define_insn "*andqi_2_maybe_si" 8270 [(set (reg FLAGS_REG) 8271 (compare (and:QI 8272 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8273 (match_operand:QI 2 "general_operand" "qim,qi,i")) 8274 (const_int 0))) 8275 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r") 8276 (and:QI (match_dup 1) (match_dup 2)))] 8277 "ix86_binary_operator_ok (AND, QImode, operands) 8278 && ix86_match_ccmode (insn, 8279 GET_CODE (operands[2]) == CONST_INT 8280 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)" 8281{ 8282 if (which_alternative == 2) 8283 { 8284 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) 8285 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); 8286 return "and{l}\t{%2, %k0|%k0, %2}"; 8287 } 8288 return "and{b}\t{%2, %0|%0, %2}"; 8289} 8290 [(set_attr "type" "alu") 8291 (set_attr "mode" "QI,QI,SI")]) 8292 8293(define_insn "*andqi_2" 8294 [(set (reg FLAGS_REG) 8295 (compare (and:QI 8296 (match_operand:QI 1 "nonimmediate_operand" "%0,0") 8297 (match_operand:QI 2 "general_operand" "qim,qi")) 8298 (const_int 0))) 8299 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 8300 (and:QI (match_dup 1) (match_dup 2)))] 8301 "ix86_match_ccmode (insn, CCNOmode) 8302 && ix86_binary_operator_ok (AND, QImode, operands)" 8303 "and{b}\t{%2, %0|%0, %2}" 8304 [(set_attr "type" "alu") 8305 (set_attr "mode" "QI")]) 8306 8307(define_insn "*andqi_2_slp" 8308 [(set (reg FLAGS_REG) 8309 (compare (and:QI 8310 (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 8311 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi")) 8312 (const_int 0))) 8313 (set (strict_low_part (match_dup 0)) 8314 (and:QI (match_dup 0) (match_dup 1)))] 8315 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8316 && ix86_match_ccmode (insn, CCNOmode) 8317 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8318 "and{b}\t{%1, %0|%0, %1}" 8319 [(set_attr "type" "alu1") 8320 (set_attr "mode" "QI")]) 8321 8322;; ??? A bug in recog prevents it from recognizing a const_int as an 8323;; operand to zero_extend in andqi_ext_1. It was checking explicitly 8324;; for a QImode operand, which of course failed. 8325 8326(define_insn "andqi_ext_0" 8327 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8328 (const_int 8) 8329 (const_int 8)) 8330 (and:SI 8331 (zero_extract:SI 8332 (match_operand 1 "ext_register_operand" "0") 8333 (const_int 8) 8334 (const_int 8)) 8335 (match_operand 2 "const_int_operand" "n"))) 8336 (clobber (reg:CC FLAGS_REG))] 8337 "" 8338 "and{b}\t{%2, %h0|%h0, %2}" 8339 [(set_attr "type" "alu") 8340 (set_attr "length_immediate" "1") 8341 (set_attr "mode" "QI")]) 8342 8343;; Generated by peephole translating test to and. This shows up 8344;; often in fp comparisons. 8345 8346(define_insn "*andqi_ext_0_cc" 8347 [(set (reg FLAGS_REG) 8348 (compare 8349 (and:SI 8350 (zero_extract:SI 8351 (match_operand 1 "ext_register_operand" "0") 8352 (const_int 8) 8353 (const_int 8)) 8354 (match_operand 2 "const_int_operand" "n")) 8355 (const_int 0))) 8356 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8357 (const_int 8) 8358 (const_int 8)) 8359 (and:SI 8360 (zero_extract:SI 8361 (match_dup 1) 8362 (const_int 8) 8363 (const_int 8)) 8364 (match_dup 2)))] 8365 "ix86_match_ccmode (insn, CCNOmode)" 8366 "and{b}\t{%2, %h0|%h0, %2}" 8367 [(set_attr "type" "alu") 8368 (set_attr "length_immediate" "1") 8369 (set_attr "mode" "QI")]) 8370 8371(define_insn "*andqi_ext_1" 8372 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8373 (const_int 8) 8374 (const_int 8)) 8375 (and:SI 8376 (zero_extract:SI 8377 (match_operand 1 "ext_register_operand" "0") 8378 (const_int 8) 8379 (const_int 8)) 8380 (zero_extend:SI 8381 (match_operand:QI 2 "general_operand" "Qm")))) 8382 (clobber (reg:CC FLAGS_REG))] 8383 "!TARGET_64BIT" 8384 "and{b}\t{%2, %h0|%h0, %2}" 8385 [(set_attr "type" "alu") 8386 (set_attr "length_immediate" "0") 8387 (set_attr "mode" "QI")]) 8388 8389(define_insn "*andqi_ext_1_rex64" 8390 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8391 (const_int 8) 8392 (const_int 8)) 8393 (and:SI 8394 (zero_extract:SI 8395 (match_operand 1 "ext_register_operand" "0") 8396 (const_int 8) 8397 (const_int 8)) 8398 (zero_extend:SI 8399 (match_operand 2 "ext_register_operand" "Q")))) 8400 (clobber (reg:CC FLAGS_REG))] 8401 "TARGET_64BIT" 8402 "and{b}\t{%2, %h0|%h0, %2}" 8403 [(set_attr "type" "alu") 8404 (set_attr "length_immediate" "0") 8405 (set_attr "mode" "QI")]) 8406 8407(define_insn "*andqi_ext_2" 8408 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8409 (const_int 8) 8410 (const_int 8)) 8411 (and:SI 8412 (zero_extract:SI 8413 (match_operand 1 "ext_register_operand" "%0") 8414 (const_int 8) 8415 (const_int 8)) 8416 (zero_extract:SI 8417 (match_operand 2 "ext_register_operand" "Q") 8418 (const_int 8) 8419 (const_int 8)))) 8420 (clobber (reg:CC FLAGS_REG))] 8421 "" 8422 "and{b}\t{%h2, %h0|%h0, %h2}" 8423 [(set_attr "type" "alu") 8424 (set_attr "length_immediate" "0") 8425 (set_attr "mode" "QI")]) 8426 8427;; Convert wide AND instructions with immediate operand to shorter QImode 8428;; equivalents when possible. 8429;; Don't do the splitting with memory operands, since it introduces risk 8430;; of memory mismatch stalls. We may want to do the splitting for optimizing 8431;; for size, but that can (should?) be handled by generic code instead. 8432(define_split 8433 [(set (match_operand 0 "register_operand" "") 8434 (and (match_operand 1 "register_operand" "") 8435 (match_operand 2 "const_int_operand" ""))) 8436 (clobber (reg:CC FLAGS_REG))] 8437 "reload_completed 8438 && QI_REG_P (operands[0]) 8439 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8440 && !(~INTVAL (operands[2]) & ~(255 << 8)) 8441 && GET_MODE (operands[0]) != QImode" 8442 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8443 (and:SI (zero_extract:SI (match_dup 1) 8444 (const_int 8) (const_int 8)) 8445 (match_dup 2))) 8446 (clobber (reg:CC FLAGS_REG))])] 8447 "operands[0] = gen_lowpart (SImode, operands[0]); 8448 operands[1] = gen_lowpart (SImode, operands[1]); 8449 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") 8450 8451;; Since AND can be encoded with sign extended immediate, this is only 8452;; profitable when 7th bit is not set. 8453(define_split 8454 [(set (match_operand 0 "register_operand" "") 8455 (and (match_operand 1 "general_operand" "") 8456 (match_operand 2 "const_int_operand" ""))) 8457 (clobber (reg:CC FLAGS_REG))] 8458 "reload_completed 8459 && ANY_QI_REG_P (operands[0]) 8460 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8461 && !(~INTVAL (operands[2]) & ~255) 8462 && !(INTVAL (operands[2]) & 128) 8463 && GET_MODE (operands[0]) != QImode" 8464 [(parallel [(set (strict_low_part (match_dup 0)) 8465 (and:QI (match_dup 1) 8466 (match_dup 2))) 8467 (clobber (reg:CC FLAGS_REG))])] 8468 "operands[0] = gen_lowpart (QImode, operands[0]); 8469 operands[1] = gen_lowpart (QImode, operands[1]); 8470 operands[2] = gen_lowpart (QImode, operands[2]);") 8471 8472;; Logical inclusive OR instructions 8473 8474;; %%% This used to optimize known byte-wide and operations to memory. 8475;; If this is considered useful, it should be done with splitters. 8476 8477(define_expand "iordi3" 8478 [(set (match_operand:DI 0 "nonimmediate_operand" "") 8479 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "") 8480 (match_operand:DI 2 "x86_64_general_operand" ""))) 8481 (clobber (reg:CC FLAGS_REG))] 8482 "TARGET_64BIT" 8483 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;") 8484 8485(define_insn "*iordi_1_rex64" 8486 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 8487 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8488 (match_operand:DI 2 "x86_64_general_operand" "re,rme"))) 8489 (clobber (reg:CC FLAGS_REG))] 8490 "TARGET_64BIT 8491 && ix86_binary_operator_ok (IOR, DImode, operands)" 8492 "or{q}\t{%2, %0|%0, %2}" 8493 [(set_attr "type" "alu") 8494 (set_attr "mode" "DI")]) 8495 8496(define_insn "*iordi_2_rex64" 8497 [(set (reg FLAGS_REG) 8498 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8499 (match_operand:DI 2 "x86_64_general_operand" "rem,re")) 8500 (const_int 0))) 8501 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") 8502 (ior:DI (match_dup 1) (match_dup 2)))] 8503 "TARGET_64BIT 8504 && ix86_match_ccmode (insn, CCNOmode) 8505 && ix86_binary_operator_ok (IOR, DImode, operands)" 8506 "or{q}\t{%2, %0|%0, %2}" 8507 [(set_attr "type" "alu") 8508 (set_attr "mode" "DI")]) 8509 8510(define_insn "*iordi_3_rex64" 8511 [(set (reg FLAGS_REG) 8512 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0") 8513 (match_operand:DI 2 "x86_64_general_operand" "rem")) 8514 (const_int 0))) 8515 (clobber (match_scratch:DI 0 "=r"))] 8516 "TARGET_64BIT 8517 && ix86_match_ccmode (insn, CCNOmode) 8518 && ix86_binary_operator_ok (IOR, DImode, operands)" 8519 "or{q}\t{%2, %0|%0, %2}" 8520 [(set_attr "type" "alu") 8521 (set_attr "mode" "DI")]) 8522 8523 8524(define_expand "iorsi3" 8525 [(set (match_operand:SI 0 "nonimmediate_operand" "") 8526 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "") 8527 (match_operand:SI 2 "general_operand" ""))) 8528 (clobber (reg:CC FLAGS_REG))] 8529 "" 8530 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;") 8531 8532(define_insn "*iorsi_1" 8533 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 8534 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8535 (match_operand:SI 2 "general_operand" "ri,rmi"))) 8536 (clobber (reg:CC FLAGS_REG))] 8537 "ix86_binary_operator_ok (IOR, SImode, operands)" 8538 "or{l}\t{%2, %0|%0, %2}" 8539 [(set_attr "type" "alu") 8540 (set_attr "mode" "SI")]) 8541 8542;; See comment for addsi_1_zext why we do use nonimmediate_operand 8543(define_insn "*iorsi_1_zext" 8544 [(set (match_operand:DI 0 "register_operand" "=rm") 8545 (zero_extend:DI 8546 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8547 (match_operand:SI 2 "general_operand" "rim")))) 8548 (clobber (reg:CC FLAGS_REG))] 8549 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)" 8550 "or{l}\t{%2, %k0|%k0, %2}" 8551 [(set_attr "type" "alu") 8552 (set_attr "mode" "SI")]) 8553 8554(define_insn "*iorsi_1_zext_imm" 8555 [(set (match_operand:DI 0 "register_operand" "=rm") 8556 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 8557 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 8558 (clobber (reg:CC FLAGS_REG))] 8559 "TARGET_64BIT" 8560 "or{l}\t{%2, %k0|%k0, %2}" 8561 [(set_attr "type" "alu") 8562 (set_attr "mode" "SI")]) 8563 8564(define_insn "*iorsi_2" 8565 [(set (reg FLAGS_REG) 8566 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8567 (match_operand:SI 2 "general_operand" "rim,ri")) 8568 (const_int 0))) 8569 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 8570 (ior:SI (match_dup 1) (match_dup 2)))] 8571 "ix86_match_ccmode (insn, CCNOmode) 8572 && ix86_binary_operator_ok (IOR, SImode, operands)" 8573 "or{l}\t{%2, %0|%0, %2}" 8574 [(set_attr "type" "alu") 8575 (set_attr "mode" "SI")]) 8576 8577;; See comment for addsi_1_zext why we do use nonimmediate_operand 8578;; ??? Special case for immediate operand is missing - it is tricky. 8579(define_insn "*iorsi_2_zext" 8580 [(set (reg FLAGS_REG) 8581 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8582 (match_operand:SI 2 "general_operand" "rim")) 8583 (const_int 0))) 8584 (set (match_operand:DI 0 "register_operand" "=r") 8585 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))] 8586 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8587 && ix86_binary_operator_ok (IOR, SImode, operands)" 8588 "or{l}\t{%2, %k0|%k0, %2}" 8589 [(set_attr "type" "alu") 8590 (set_attr "mode" "SI")]) 8591 8592(define_insn "*iorsi_2_zext_imm" 8593 [(set (reg FLAGS_REG) 8594 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8595 (match_operand 2 "x86_64_zext_immediate_operand" "Z")) 8596 (const_int 0))) 8597 (set (match_operand:DI 0 "register_operand" "=r") 8598 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 8599 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8600 && ix86_binary_operator_ok (IOR, SImode, operands)" 8601 "or{l}\t{%2, %k0|%k0, %2}" 8602 [(set_attr "type" "alu") 8603 (set_attr "mode" "SI")]) 8604 8605(define_insn "*iorsi_3" 8606 [(set (reg FLAGS_REG) 8607 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8608 (match_operand:SI 2 "general_operand" "rim")) 8609 (const_int 0))) 8610 (clobber (match_scratch:SI 0 "=r"))] 8611 "ix86_match_ccmode (insn, CCNOmode) 8612 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 8613 "or{l}\t{%2, %0|%0, %2}" 8614 [(set_attr "type" "alu") 8615 (set_attr "mode" "SI")]) 8616 8617(define_expand "iorhi3" 8618 [(set (match_operand:HI 0 "nonimmediate_operand" "") 8619 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "") 8620 (match_operand:HI 2 "general_operand" ""))) 8621 (clobber (reg:CC FLAGS_REG))] 8622 "TARGET_HIMODE_MATH" 8623 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;") 8624 8625(define_insn "*iorhi_1" 8626 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m") 8627 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 8628 (match_operand:HI 2 "general_operand" "rmi,ri"))) 8629 (clobber (reg:CC FLAGS_REG))] 8630 "ix86_binary_operator_ok (IOR, HImode, operands)" 8631 "or{w}\t{%2, %0|%0, %2}" 8632 [(set_attr "type" "alu") 8633 (set_attr "mode" "HI")]) 8634 8635(define_insn "*iorhi_2" 8636 [(set (reg FLAGS_REG) 8637 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 8638 (match_operand:HI 2 "general_operand" "rim,ri")) 8639 (const_int 0))) 8640 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 8641 (ior:HI (match_dup 1) (match_dup 2)))] 8642 "ix86_match_ccmode (insn, CCNOmode) 8643 && ix86_binary_operator_ok (IOR, HImode, operands)" 8644 "or{w}\t{%2, %0|%0, %2}" 8645 [(set_attr "type" "alu") 8646 (set_attr "mode" "HI")]) 8647 8648(define_insn "*iorhi_3" 8649 [(set (reg FLAGS_REG) 8650 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0") 8651 (match_operand:HI 2 "general_operand" "rim")) 8652 (const_int 0))) 8653 (clobber (match_scratch:HI 0 "=r"))] 8654 "ix86_match_ccmode (insn, CCNOmode) 8655 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 8656 "or{w}\t{%2, %0|%0, %2}" 8657 [(set_attr "type" "alu") 8658 (set_attr "mode" "HI")]) 8659 8660(define_expand "iorqi3" 8661 [(set (match_operand:QI 0 "nonimmediate_operand" "") 8662 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "") 8663 (match_operand:QI 2 "general_operand" ""))) 8664 (clobber (reg:CC FLAGS_REG))] 8665 "TARGET_QIMODE_MATH" 8666 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;") 8667 8668;; %%% Potential partial reg stall on alternative 2. What to do? 8669(define_insn "*iorqi_1" 8670 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") 8671 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8672 (match_operand:QI 2 "general_operand" "qmi,qi,ri"))) 8673 (clobber (reg:CC FLAGS_REG))] 8674 "ix86_binary_operator_ok (IOR, QImode, operands)" 8675 "@ 8676 or{b}\t{%2, %0|%0, %2} 8677 or{b}\t{%2, %0|%0, %2} 8678 or{l}\t{%k2, %k0|%k0, %k2}" 8679 [(set_attr "type" "alu") 8680 (set_attr "mode" "QI,QI,SI")]) 8681 8682(define_insn "*iorqi_1_slp" 8683 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m")) 8684 (ior:QI (match_dup 0) 8685 (match_operand:QI 1 "general_operand" "qmi,qi"))) 8686 (clobber (reg:CC FLAGS_REG))] 8687 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8688 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8689 "or{b}\t{%1, %0|%0, %1}" 8690 [(set_attr "type" "alu1") 8691 (set_attr "mode" "QI")]) 8692 8693(define_insn "*iorqi_2" 8694 [(set (reg FLAGS_REG) 8695 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 8696 (match_operand:QI 2 "general_operand" "qim,qi")) 8697 (const_int 0))) 8698 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 8699 (ior:QI (match_dup 1) (match_dup 2)))] 8700 "ix86_match_ccmode (insn, CCNOmode) 8701 && ix86_binary_operator_ok (IOR, QImode, operands)" 8702 "or{b}\t{%2, %0|%0, %2}" 8703 [(set_attr "type" "alu") 8704 (set_attr "mode" "QI")]) 8705 8706(define_insn "*iorqi_2_slp" 8707 [(set (reg FLAGS_REG) 8708 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 8709 (match_operand:QI 1 "general_operand" "qim,qi")) 8710 (const_int 0))) 8711 (set (strict_low_part (match_dup 0)) 8712 (ior:QI (match_dup 0) (match_dup 1)))] 8713 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8714 && ix86_match_ccmode (insn, CCNOmode) 8715 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8716 "or{b}\t{%1, %0|%0, %1}" 8717 [(set_attr "type" "alu1") 8718 (set_attr "mode" "QI")]) 8719 8720(define_insn "*iorqi_3" 8721 [(set (reg FLAGS_REG) 8722 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 8723 (match_operand:QI 2 "general_operand" "qim")) 8724 (const_int 0))) 8725 (clobber (match_scratch:QI 0 "=q"))] 8726 "ix86_match_ccmode (insn, CCNOmode) 8727 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 8728 "or{b}\t{%2, %0|%0, %2}" 8729 [(set_attr "type" "alu") 8730 (set_attr "mode" "QI")]) 8731 8732(define_insn "iorqi_ext_0" 8733 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8734 (const_int 8) 8735 (const_int 8)) 8736 (ior:SI 8737 (zero_extract:SI 8738 (match_operand 1 "ext_register_operand" "0") 8739 (const_int 8) 8740 (const_int 8)) 8741 (match_operand 2 "const_int_operand" "n"))) 8742 (clobber (reg:CC FLAGS_REG))] 8743 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 8744 "or{b}\t{%2, %h0|%h0, %2}" 8745 [(set_attr "type" "alu") 8746 (set_attr "length_immediate" "1") 8747 (set_attr "mode" "QI")]) 8748 8749(define_insn "*iorqi_ext_1" 8750 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8751 (const_int 8) 8752 (const_int 8)) 8753 (ior:SI 8754 (zero_extract:SI 8755 (match_operand 1 "ext_register_operand" "0") 8756 (const_int 8) 8757 (const_int 8)) 8758 (zero_extend:SI 8759 (match_operand:QI 2 "general_operand" "Qm")))) 8760 (clobber (reg:CC FLAGS_REG))] 8761 "!TARGET_64BIT 8762 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 8763 "or{b}\t{%2, %h0|%h0, %2}" 8764 [(set_attr "type" "alu") 8765 (set_attr "length_immediate" "0") 8766 (set_attr "mode" "QI")]) 8767 8768(define_insn "*iorqi_ext_1_rex64" 8769 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8770 (const_int 8) 8771 (const_int 8)) 8772 (ior:SI 8773 (zero_extract:SI 8774 (match_operand 1 "ext_register_operand" "0") 8775 (const_int 8) 8776 (const_int 8)) 8777 (zero_extend:SI 8778 (match_operand 2 "ext_register_operand" "Q")))) 8779 (clobber (reg:CC FLAGS_REG))] 8780 "TARGET_64BIT 8781 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 8782 "or{b}\t{%2, %h0|%h0, %2}" 8783 [(set_attr "type" "alu") 8784 (set_attr "length_immediate" "0") 8785 (set_attr "mode" "QI")]) 8786 8787(define_insn "*iorqi_ext_2" 8788 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8789 (const_int 8) 8790 (const_int 8)) 8791 (ior:SI 8792 (zero_extract:SI (match_operand 1 "ext_register_operand" "0") 8793 (const_int 8) 8794 (const_int 8)) 8795 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 8796 (const_int 8) 8797 (const_int 8)))) 8798 (clobber (reg:CC FLAGS_REG))] 8799 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 8800 "ior{b}\t{%h2, %h0|%h0, %h2}" 8801 [(set_attr "type" "alu") 8802 (set_attr "length_immediate" "0") 8803 (set_attr "mode" "QI")]) 8804 8805(define_split 8806 [(set (match_operand 0 "register_operand" "") 8807 (ior (match_operand 1 "register_operand" "") 8808 (match_operand 2 "const_int_operand" ""))) 8809 (clobber (reg:CC FLAGS_REG))] 8810 "reload_completed 8811 && QI_REG_P (operands[0]) 8812 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8813 && !(INTVAL (operands[2]) & ~(255 << 8)) 8814 && GET_MODE (operands[0]) != QImode" 8815 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8816 (ior:SI (zero_extract:SI (match_dup 1) 8817 (const_int 8) (const_int 8)) 8818 (match_dup 2))) 8819 (clobber (reg:CC FLAGS_REG))])] 8820 "operands[0] = gen_lowpart (SImode, operands[0]); 8821 operands[1] = gen_lowpart (SImode, operands[1]); 8822 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") 8823 8824;; Since OR can be encoded with sign extended immediate, this is only 8825;; profitable when 7th bit is set. 8826(define_split 8827 [(set (match_operand 0 "register_operand" "") 8828 (ior (match_operand 1 "general_operand" "") 8829 (match_operand 2 "const_int_operand" ""))) 8830 (clobber (reg:CC FLAGS_REG))] 8831 "reload_completed 8832 && ANY_QI_REG_P (operands[0]) 8833 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8834 && !(INTVAL (operands[2]) & ~255) 8835 && (INTVAL (operands[2]) & 128) 8836 && GET_MODE (operands[0]) != QImode" 8837 [(parallel [(set (strict_low_part (match_dup 0)) 8838 (ior:QI (match_dup 1) 8839 (match_dup 2))) 8840 (clobber (reg:CC FLAGS_REG))])] 8841 "operands[0] = gen_lowpart (QImode, operands[0]); 8842 operands[1] = gen_lowpart (QImode, operands[1]); 8843 operands[2] = gen_lowpart (QImode, operands[2]);") 8844 8845;; Logical XOR instructions 8846 8847;; %%% This used to optimize known byte-wide and operations to memory. 8848;; If this is considered useful, it should be done with splitters. 8849 8850(define_expand "xordi3" 8851 [(set (match_operand:DI 0 "nonimmediate_operand" "") 8852 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "") 8853 (match_operand:DI 2 "x86_64_general_operand" ""))) 8854 (clobber (reg:CC FLAGS_REG))] 8855 "TARGET_64BIT" 8856 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;") 8857 8858(define_insn "*xordi_1_rex64" 8859 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 8860 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8861 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 8862 (clobber (reg:CC FLAGS_REG))] 8863 "TARGET_64BIT 8864 && ix86_binary_operator_ok (XOR, DImode, operands)" 8865 "@ 8866 xor{q}\t{%2, %0|%0, %2} 8867 xor{q}\t{%2, %0|%0, %2}" 8868 [(set_attr "type" "alu") 8869 (set_attr "mode" "DI,DI")]) 8870 8871(define_insn "*xordi_2_rex64" 8872 [(set (reg FLAGS_REG) 8873 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8874 (match_operand:DI 2 "x86_64_general_operand" "rem,re")) 8875 (const_int 0))) 8876 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") 8877 (xor:DI (match_dup 1) (match_dup 2)))] 8878 "TARGET_64BIT 8879 && ix86_match_ccmode (insn, CCNOmode) 8880 && ix86_binary_operator_ok (XOR, DImode, operands)" 8881 "@ 8882 xor{q}\t{%2, %0|%0, %2} 8883 xor{q}\t{%2, %0|%0, %2}" 8884 [(set_attr "type" "alu") 8885 (set_attr "mode" "DI,DI")]) 8886 8887(define_insn "*xordi_3_rex64" 8888 [(set (reg FLAGS_REG) 8889 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0") 8890 (match_operand:DI 2 "x86_64_general_operand" "rem")) 8891 (const_int 0))) 8892 (clobber (match_scratch:DI 0 "=r"))] 8893 "TARGET_64BIT 8894 && ix86_match_ccmode (insn, CCNOmode) 8895 && ix86_binary_operator_ok (XOR, DImode, operands)" 8896 "xor{q}\t{%2, %0|%0, %2}" 8897 [(set_attr "type" "alu") 8898 (set_attr "mode" "DI")]) 8899 8900(define_expand "xorsi3" 8901 [(set (match_operand:SI 0 "nonimmediate_operand" "") 8902 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "") 8903 (match_operand:SI 2 "general_operand" ""))) 8904 (clobber (reg:CC FLAGS_REG))] 8905 "" 8906 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;") 8907 8908(define_insn "*xorsi_1" 8909 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 8910 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8911 (match_operand:SI 2 "general_operand" "ri,rm"))) 8912 (clobber (reg:CC FLAGS_REG))] 8913 "ix86_binary_operator_ok (XOR, SImode, operands)" 8914 "xor{l}\t{%2, %0|%0, %2}" 8915 [(set_attr "type" "alu") 8916 (set_attr "mode" "SI")]) 8917 8918;; See comment for addsi_1_zext why we do use nonimmediate_operand 8919;; Add speccase for immediates 8920(define_insn "*xorsi_1_zext" 8921 [(set (match_operand:DI 0 "register_operand" "=r") 8922 (zero_extend:DI 8923 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8924 (match_operand:SI 2 "general_operand" "rim")))) 8925 (clobber (reg:CC FLAGS_REG))] 8926 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)" 8927 "xor{l}\t{%2, %k0|%k0, %2}" 8928 [(set_attr "type" "alu") 8929 (set_attr "mode" "SI")]) 8930 8931(define_insn "*xorsi_1_zext_imm" 8932 [(set (match_operand:DI 0 "register_operand" "=r") 8933 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 8934 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 8935 (clobber (reg:CC FLAGS_REG))] 8936 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)" 8937 "xor{l}\t{%2, %k0|%k0, %2}" 8938 [(set_attr "type" "alu") 8939 (set_attr "mode" "SI")]) 8940 8941(define_insn "*xorsi_2" 8942 [(set (reg FLAGS_REG) 8943 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8944 (match_operand:SI 2 "general_operand" "rim,ri")) 8945 (const_int 0))) 8946 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 8947 (xor:SI (match_dup 1) (match_dup 2)))] 8948 "ix86_match_ccmode (insn, CCNOmode) 8949 && ix86_binary_operator_ok (XOR, SImode, operands)" 8950 "xor{l}\t{%2, %0|%0, %2}" 8951 [(set_attr "type" "alu") 8952 (set_attr "mode" "SI")]) 8953 8954;; See comment for addsi_1_zext why we do use nonimmediate_operand 8955;; ??? Special case for immediate operand is missing - it is tricky. 8956(define_insn "*xorsi_2_zext" 8957 [(set (reg FLAGS_REG) 8958 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8959 (match_operand:SI 2 "general_operand" "rim")) 8960 (const_int 0))) 8961 (set (match_operand:DI 0 "register_operand" "=r") 8962 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))] 8963 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8964 && ix86_binary_operator_ok (XOR, SImode, operands)" 8965 "xor{l}\t{%2, %k0|%k0, %2}" 8966 [(set_attr "type" "alu") 8967 (set_attr "mode" "SI")]) 8968 8969(define_insn "*xorsi_2_zext_imm" 8970 [(set (reg FLAGS_REG) 8971 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8972 (match_operand 2 "x86_64_zext_immediate_operand" "Z")) 8973 (const_int 0))) 8974 (set (match_operand:DI 0 "register_operand" "=r") 8975 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 8976 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8977 && ix86_binary_operator_ok (XOR, SImode, operands)" 8978 "xor{l}\t{%2, %k0|%k0, %2}" 8979 [(set_attr "type" "alu") 8980 (set_attr "mode" "SI")]) 8981 8982(define_insn "*xorsi_3" 8983 [(set (reg FLAGS_REG) 8984 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8985 (match_operand:SI 2 "general_operand" "rim")) 8986 (const_int 0))) 8987 (clobber (match_scratch:SI 0 "=r"))] 8988 "ix86_match_ccmode (insn, CCNOmode) 8989 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 8990 "xor{l}\t{%2, %0|%0, %2}" 8991 [(set_attr "type" "alu") 8992 (set_attr "mode" "SI")]) 8993 8994(define_expand "xorhi3" 8995 [(set (match_operand:HI 0 "nonimmediate_operand" "") 8996 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "") 8997 (match_operand:HI 2 "general_operand" ""))) 8998 (clobber (reg:CC FLAGS_REG))] 8999 "TARGET_HIMODE_MATH" 9000 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;") 9001 9002(define_insn "*xorhi_1" 9003 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m") 9004 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 9005 (match_operand:HI 2 "general_operand" "rmi,ri"))) 9006 (clobber (reg:CC FLAGS_REG))] 9007 "ix86_binary_operator_ok (XOR, HImode, operands)" 9008 "xor{w}\t{%2, %0|%0, %2}" 9009 [(set_attr "type" "alu") 9010 (set_attr "mode" "HI")]) 9011 9012(define_insn "*xorhi_2" 9013 [(set (reg FLAGS_REG) 9014 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 9015 (match_operand:HI 2 "general_operand" "rim,ri")) 9016 (const_int 0))) 9017 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 9018 (xor:HI (match_dup 1) (match_dup 2)))] 9019 "ix86_match_ccmode (insn, CCNOmode) 9020 && ix86_binary_operator_ok (XOR, HImode, operands)" 9021 "xor{w}\t{%2, %0|%0, %2}" 9022 [(set_attr "type" "alu") 9023 (set_attr "mode" "HI")]) 9024 9025(define_insn "*xorhi_3" 9026 [(set (reg FLAGS_REG) 9027 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0") 9028 (match_operand:HI 2 "general_operand" "rim")) 9029 (const_int 0))) 9030 (clobber (match_scratch:HI 0 "=r"))] 9031 "ix86_match_ccmode (insn, CCNOmode) 9032 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 9033 "xor{w}\t{%2, %0|%0, %2}" 9034 [(set_attr "type" "alu") 9035 (set_attr "mode" "HI")]) 9036 9037(define_expand "xorqi3" 9038 [(set (match_operand:QI 0 "nonimmediate_operand" "") 9039 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "") 9040 (match_operand:QI 2 "general_operand" ""))) 9041 (clobber (reg:CC FLAGS_REG))] 9042 "TARGET_QIMODE_MATH" 9043 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;") 9044 9045;; %%% Potential partial reg stall on alternative 2. What to do? 9046(define_insn "*xorqi_1" 9047 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") 9048 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 9049 (match_operand:QI 2 "general_operand" "qmi,qi,ri"))) 9050 (clobber (reg:CC FLAGS_REG))] 9051 "ix86_binary_operator_ok (XOR, QImode, operands)" 9052 "@ 9053 xor{b}\t{%2, %0|%0, %2} 9054 xor{b}\t{%2, %0|%0, %2} 9055 xor{l}\t{%k2, %k0|%k0, %k2}" 9056 [(set_attr "type" "alu") 9057 (set_attr "mode" "QI,QI,SI")]) 9058 9059(define_insn "*xorqi_1_slp" 9060 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 9061 (xor:QI (match_dup 0) 9062 (match_operand:QI 1 "general_operand" "qi,qmi"))) 9063 (clobber (reg:CC FLAGS_REG))] 9064 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 9065 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 9066 "xor{b}\t{%1, %0|%0, %1}" 9067 [(set_attr "type" "alu1") 9068 (set_attr "mode" "QI")]) 9069 9070(define_insn "xorqi_ext_0" 9071 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9072 (const_int 8) 9073 (const_int 8)) 9074 (xor:SI 9075 (zero_extract:SI 9076 (match_operand 1 "ext_register_operand" "0") 9077 (const_int 8) 9078 (const_int 8)) 9079 (match_operand 2 "const_int_operand" "n"))) 9080 (clobber (reg:CC FLAGS_REG))] 9081 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 9082 "xor{b}\t{%2, %h0|%h0, %2}" 9083 [(set_attr "type" "alu") 9084 (set_attr "length_immediate" "1") 9085 (set_attr "mode" "QI")]) 9086 9087(define_insn "*xorqi_ext_1" 9088 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9089 (const_int 8) 9090 (const_int 8)) 9091 (xor:SI 9092 (zero_extract:SI 9093 (match_operand 1 "ext_register_operand" "0") 9094 (const_int 8) 9095 (const_int 8)) 9096 (zero_extend:SI 9097 (match_operand:QI 2 "general_operand" "Qm")))) 9098 (clobber (reg:CC FLAGS_REG))] 9099 "!TARGET_64BIT 9100 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 9101 "xor{b}\t{%2, %h0|%h0, %2}" 9102 [(set_attr "type" "alu") 9103 (set_attr "length_immediate" "0") 9104 (set_attr "mode" "QI")]) 9105 9106(define_insn "*xorqi_ext_1_rex64" 9107 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9108 (const_int 8) 9109 (const_int 8)) 9110 (xor:SI 9111 (zero_extract:SI 9112 (match_operand 1 "ext_register_operand" "0") 9113 (const_int 8) 9114 (const_int 8)) 9115 (zero_extend:SI 9116 (match_operand 2 "ext_register_operand" "Q")))) 9117 (clobber (reg:CC FLAGS_REG))] 9118 "TARGET_64BIT 9119 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 9120 "xor{b}\t{%2, %h0|%h0, %2}" 9121 [(set_attr "type" "alu") 9122 (set_attr "length_immediate" "0") 9123 (set_attr "mode" "QI")]) 9124 9125(define_insn "*xorqi_ext_2" 9126 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9127 (const_int 8) 9128 (const_int 8)) 9129 (xor:SI 9130 (zero_extract:SI (match_operand 1 "ext_register_operand" "0") 9131 (const_int 8) 9132 (const_int 8)) 9133 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 9134 (const_int 8) 9135 (const_int 8)))) 9136 (clobber (reg:CC FLAGS_REG))] 9137 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 9138 "xor{b}\t{%h2, %h0|%h0, %h2}" 9139 [(set_attr "type" "alu") 9140 (set_attr "length_immediate" "0") 9141 (set_attr "mode" "QI")]) 9142 9143(define_insn "*xorqi_cc_1" 9144 [(set (reg FLAGS_REG) 9145 (compare 9146 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 9147 (match_operand:QI 2 "general_operand" "qim,qi")) 9148 (const_int 0))) 9149 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 9150 (xor:QI (match_dup 1) (match_dup 2)))] 9151 "ix86_match_ccmode (insn, CCNOmode) 9152 && ix86_binary_operator_ok (XOR, QImode, operands)" 9153 "xor{b}\t{%2, %0|%0, %2}" 9154 [(set_attr "type" "alu") 9155 (set_attr "mode" "QI")]) 9156 9157(define_insn "*xorqi_2_slp" 9158 [(set (reg FLAGS_REG) 9159 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 9160 (match_operand:QI 1 "general_operand" "qim,qi")) 9161 (const_int 0))) 9162 (set (strict_low_part (match_dup 0)) 9163 (xor:QI (match_dup 0) (match_dup 1)))] 9164 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 9165 && ix86_match_ccmode (insn, CCNOmode) 9166 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 9167 "xor{b}\t{%1, %0|%0, %1}" 9168 [(set_attr "type" "alu1") 9169 (set_attr "mode" "QI")]) 9170 9171(define_insn "*xorqi_cc_2" 9172 [(set (reg FLAGS_REG) 9173 (compare 9174 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 9175 (match_operand:QI 2 "general_operand" "qim")) 9176 (const_int 0))) 9177 (clobber (match_scratch:QI 0 "=q"))] 9178 "ix86_match_ccmode (insn, CCNOmode) 9179 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 9180 "xor{b}\t{%2, %0|%0, %2}" 9181 [(set_attr "type" "alu") 9182 (set_attr "mode" "QI")]) 9183 9184(define_insn "*xorqi_cc_ext_1" 9185 [(set (reg FLAGS_REG) 9186 (compare 9187 (xor:SI 9188 (zero_extract:SI 9189 (match_operand 1 "ext_register_operand" "0") 9190 (const_int 8) 9191 (const_int 8)) 9192 (match_operand:QI 2 "general_operand" "qmn")) 9193 (const_int 0))) 9194 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q") 9195 (const_int 8) 9196 (const_int 8)) 9197 (xor:SI 9198 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) 9199 (match_dup 2)))] 9200 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 9201 "xor{b}\t{%2, %h0|%h0, %2}" 9202 [(set_attr "type" "alu") 9203 (set_attr "mode" "QI")]) 9204 9205(define_insn "*xorqi_cc_ext_1_rex64" 9206 [(set (reg FLAGS_REG) 9207 (compare 9208 (xor:SI 9209 (zero_extract:SI 9210 (match_operand 1 "ext_register_operand" "0") 9211 (const_int 8) 9212 (const_int 8)) 9213 (match_operand:QI 2 "nonmemory_operand" "Qn")) 9214 (const_int 0))) 9215 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9216 (const_int 8) 9217 (const_int 8)) 9218 (xor:SI 9219 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) 9220 (match_dup 2)))] 9221 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 9222 "xor{b}\t{%2, %h0|%h0, %2}" 9223 [(set_attr "type" "alu") 9224 (set_attr "mode" "QI")]) 9225 9226(define_expand "xorqi_cc_ext_1" 9227 [(parallel [ 9228 (set (reg:CCNO FLAGS_REG) 9229 (compare:CCNO 9230 (xor:SI 9231 (zero_extract:SI 9232 (match_operand 1 "ext_register_operand" "") 9233 (const_int 8) 9234 (const_int 8)) 9235 (match_operand:QI 2 "general_operand" "")) 9236 (const_int 0))) 9237 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "") 9238 (const_int 8) 9239 (const_int 8)) 9240 (xor:SI 9241 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) 9242 (match_dup 2)))])] 9243 "" 9244 "") 9245 9246(define_split 9247 [(set (match_operand 0 "register_operand" "") 9248 (xor (match_operand 1 "register_operand" "") 9249 (match_operand 2 "const_int_operand" ""))) 9250 (clobber (reg:CC FLAGS_REG))] 9251 "reload_completed 9252 && QI_REG_P (operands[0]) 9253 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 9254 && !(INTVAL (operands[2]) & ~(255 << 8)) 9255 && GET_MODE (operands[0]) != QImode" 9256 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 9257 (xor:SI (zero_extract:SI (match_dup 1) 9258 (const_int 8) (const_int 8)) 9259 (match_dup 2))) 9260 (clobber (reg:CC FLAGS_REG))])] 9261 "operands[0] = gen_lowpart (SImode, operands[0]); 9262 operands[1] = gen_lowpart (SImode, operands[1]); 9263 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") 9264 9265;; Since XOR can be encoded with sign extended immediate, this is only 9266;; profitable when 7th bit is set. 9267(define_split 9268 [(set (match_operand 0 "register_operand" "") 9269 (xor (match_operand 1 "general_operand" "") 9270 (match_operand 2 "const_int_operand" ""))) 9271 (clobber (reg:CC FLAGS_REG))] 9272 "reload_completed 9273 && ANY_QI_REG_P (operands[0]) 9274 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 9275 && !(INTVAL (operands[2]) & ~255) 9276 && (INTVAL (operands[2]) & 128) 9277 && GET_MODE (operands[0]) != QImode" 9278 [(parallel [(set (strict_low_part (match_dup 0)) 9279 (xor:QI (match_dup 1) 9280 (match_dup 2))) 9281 (clobber (reg:CC FLAGS_REG))])] 9282 "operands[0] = gen_lowpart (QImode, operands[0]); 9283 operands[1] = gen_lowpart (QImode, operands[1]); 9284 operands[2] = gen_lowpart (QImode, operands[2]);") 9285 9286;; Negation instructions 9287 9288(define_expand "negti2" 9289 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "") 9290 (neg:TI (match_operand:TI 1 "nonimmediate_operand" ""))) 9291 (clobber (reg:CC FLAGS_REG))])] 9292 "TARGET_64BIT" 9293 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;") 9294 9295(define_insn "*negti2_1" 9296 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro") 9297 (neg:TI (match_operand:TI 1 "general_operand" "0"))) 9298 (clobber (reg:CC FLAGS_REG))] 9299 "TARGET_64BIT 9300 && ix86_unary_operator_ok (NEG, TImode, operands)" 9301 "#") 9302 9303(define_split 9304 [(set (match_operand:TI 0 "nonimmediate_operand" "") 9305 (neg:TI (match_operand:TI 1 "general_operand" ""))) 9306 (clobber (reg:CC FLAGS_REG))] 9307 "TARGET_64BIT && reload_completed" 9308 [(parallel 9309 [(set (reg:CCZ FLAGS_REG) 9310 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0))) 9311 (set (match_dup 0) (neg:DI (match_dup 2)))]) 9312 (parallel 9313 [(set (match_dup 1) 9314 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) 9315 (match_dup 3)) 9316 (const_int 0))) 9317 (clobber (reg:CC FLAGS_REG))]) 9318 (parallel 9319 [(set (match_dup 1) 9320 (neg:DI (match_dup 1))) 9321 (clobber (reg:CC FLAGS_REG))])] 9322 "split_ti (operands+1, 1, operands+2, operands+3); 9323 split_ti (operands+0, 1, operands+0, operands+1);") 9324 9325(define_expand "negdi2" 9326 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 9327 (neg:DI (match_operand:DI 1 "nonimmediate_operand" ""))) 9328 (clobber (reg:CC FLAGS_REG))])] 9329 "" 9330 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;") 9331 9332(define_insn "*negdi2_1" 9333 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro") 9334 (neg:DI (match_operand:DI 1 "general_operand" "0"))) 9335 (clobber (reg:CC FLAGS_REG))] 9336 "!TARGET_64BIT 9337 && ix86_unary_operator_ok (NEG, DImode, operands)" 9338 "#") 9339 9340(define_split 9341 [(set (match_operand:DI 0 "nonimmediate_operand" "") 9342 (neg:DI (match_operand:DI 1 "general_operand" ""))) 9343 (clobber (reg:CC FLAGS_REG))] 9344 "!TARGET_64BIT && reload_completed" 9345 [(parallel 9346 [(set (reg:CCZ FLAGS_REG) 9347 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0))) 9348 (set (match_dup 0) (neg:SI (match_dup 2)))]) 9349 (parallel 9350 [(set (match_dup 1) 9351 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) 9352 (match_dup 3)) 9353 (const_int 0))) 9354 (clobber (reg:CC FLAGS_REG))]) 9355 (parallel 9356 [(set (match_dup 1) 9357 (neg:SI (match_dup 1))) 9358 (clobber (reg:CC FLAGS_REG))])] 9359 "split_di (operands+1, 1, operands+2, operands+3); 9360 split_di (operands+0, 1, operands+0, operands+1);") 9361 9362(define_insn "*negdi2_1_rex64" 9363 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9364 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))) 9365 (clobber (reg:CC FLAGS_REG))] 9366 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)" 9367 "neg{q}\t%0" 9368 [(set_attr "type" "negnot") 9369 (set_attr "mode" "DI")]) 9370 9371;; The problem with neg is that it does not perform (compare x 0), 9372;; it really performs (compare 0 x), which leaves us with the zero 9373;; flag being the only useful item. 9374 9375(define_insn "*negdi2_cmpz_rex64" 9376 [(set (reg:CCZ FLAGS_REG) 9377 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")) 9378 (const_int 0))) 9379 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9380 (neg:DI (match_dup 1)))] 9381 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)" 9382 "neg{q}\t%0" 9383 [(set_attr "type" "negnot") 9384 (set_attr "mode" "DI")]) 9385 9386 9387(define_expand "negsi2" 9388 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 9389 (neg:SI (match_operand:SI 1 "nonimmediate_operand" ""))) 9390 (clobber (reg:CC FLAGS_REG))])] 9391 "" 9392 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;") 9393 9394(define_insn "*negsi2_1" 9395 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 9396 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))) 9397 (clobber (reg:CC FLAGS_REG))] 9398 "ix86_unary_operator_ok (NEG, SImode, operands)" 9399 "neg{l}\t%0" 9400 [(set_attr "type" "negnot") 9401 (set_attr "mode" "SI")]) 9402 9403;; Combine is quite creative about this pattern. 9404(define_insn "*negsi2_1_zext" 9405 [(set (match_operand:DI 0 "register_operand" "=r") 9406 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0") 9407 (const_int 32))) 9408 (const_int 32))) 9409 (clobber (reg:CC FLAGS_REG))] 9410 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9411 "neg{l}\t%k0" 9412 [(set_attr "type" "negnot") 9413 (set_attr "mode" "SI")]) 9414 9415;; The problem with neg is that it does not perform (compare x 0), 9416;; it really performs (compare 0 x), which leaves us with the zero 9417;; flag being the only useful item. 9418 9419(define_insn "*negsi2_cmpz" 9420 [(set (reg:CCZ FLAGS_REG) 9421 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")) 9422 (const_int 0))) 9423 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 9424 (neg:SI (match_dup 1)))] 9425 "ix86_unary_operator_ok (NEG, SImode, operands)" 9426 "neg{l}\t%0" 9427 [(set_attr "type" "negnot") 9428 (set_attr "mode" "SI")]) 9429 9430(define_insn "*negsi2_cmpz_zext" 9431 [(set (reg:CCZ FLAGS_REG) 9432 (compare:CCZ (lshiftrt:DI 9433 (neg:DI (ashift:DI 9434 (match_operand:DI 1 "register_operand" "0") 9435 (const_int 32))) 9436 (const_int 32)) 9437 (const_int 0))) 9438 (set (match_operand:DI 0 "register_operand" "=r") 9439 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1) 9440 (const_int 32))) 9441 (const_int 32)))] 9442 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9443 "neg{l}\t%k0" 9444 [(set_attr "type" "negnot") 9445 (set_attr "mode" "SI")]) 9446 9447(define_expand "neghi2" 9448 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 9449 (neg:HI (match_operand:HI 1 "nonimmediate_operand" ""))) 9450 (clobber (reg:CC FLAGS_REG))])] 9451 "TARGET_HIMODE_MATH" 9452 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;") 9453 9454(define_insn "*neghi2_1" 9455 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 9456 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))) 9457 (clobber (reg:CC FLAGS_REG))] 9458 "ix86_unary_operator_ok (NEG, HImode, operands)" 9459 "neg{w}\t%0" 9460 [(set_attr "type" "negnot") 9461 (set_attr "mode" "HI")]) 9462 9463(define_insn "*neghi2_cmpz" 9464 [(set (reg:CCZ FLAGS_REG) 9465 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")) 9466 (const_int 0))) 9467 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 9468 (neg:HI (match_dup 1)))] 9469 "ix86_unary_operator_ok (NEG, HImode, operands)" 9470 "neg{w}\t%0" 9471 [(set_attr "type" "negnot") 9472 (set_attr "mode" "HI")]) 9473 9474(define_expand "negqi2" 9475 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") 9476 (neg:QI (match_operand:QI 1 "nonimmediate_operand" ""))) 9477 (clobber (reg:CC FLAGS_REG))])] 9478 "TARGET_QIMODE_MATH" 9479 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;") 9480 9481(define_insn "*negqi2_1" 9482 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 9483 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))) 9484 (clobber (reg:CC FLAGS_REG))] 9485 "ix86_unary_operator_ok (NEG, QImode, operands)" 9486 "neg{b}\t%0" 9487 [(set_attr "type" "negnot") 9488 (set_attr "mode" "QI")]) 9489 9490(define_insn "*negqi2_cmpz" 9491 [(set (reg:CCZ FLAGS_REG) 9492 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")) 9493 (const_int 0))) 9494 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 9495 (neg:QI (match_dup 1)))] 9496 "ix86_unary_operator_ok (NEG, QImode, operands)" 9497 "neg{b}\t%0" 9498 [(set_attr "type" "negnot") 9499 (set_attr "mode" "QI")]) 9500 9501;; Changing of sign for FP values is doable using integer unit too. 9502 9503(define_expand "negsf2" 9504 [(set (match_operand:SF 0 "nonimmediate_operand" "") 9505 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))] 9506 "TARGET_80387 || TARGET_SSE_MATH" 9507 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;") 9508 9509(define_expand "abssf2" 9510 [(set (match_operand:SF 0 "nonimmediate_operand" "") 9511 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))] 9512 "TARGET_80387 || TARGET_SSE_MATH" 9513 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;") 9514 9515(define_insn "*absnegsf2_mixed" 9516 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#f,x#f,f#x,rm") 9517 (match_operator:SF 3 "absneg_operator" 9518 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#f,0 ,0")])) 9519 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X")) 9520 (clobber (reg:CC FLAGS_REG))] 9521 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387 9522 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)" 9523 "#") 9524 9525(define_insn "*absnegsf2_sse" 9526 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm") 9527 (match_operator:SF 3 "absneg_operator" 9528 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")])) 9529 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X")) 9530 (clobber (reg:CC FLAGS_REG))] 9531 "TARGET_SSE_MATH 9532 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)" 9533 "#") 9534 9535(define_insn "*absnegsf2_i387" 9536 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm") 9537 (match_operator:SF 3 "absneg_operator" 9538 [(match_operand:SF 1 "nonimmediate_operand" "0,0")])) 9539 (use (match_operand 2 "" "")) 9540 (clobber (reg:CC FLAGS_REG))] 9541 "TARGET_80387 && !TARGET_SSE_MATH 9542 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)" 9543 "#") 9544 9545(define_expand "copysignsf3" 9546 [(match_operand:SF 0 "register_operand" "") 9547 (match_operand:SF 1 "nonmemory_operand" "") 9548 (match_operand:SF 2 "register_operand" "")] 9549 "TARGET_SSE_MATH" 9550{ 9551 ix86_expand_copysign (operands); 9552 DONE; 9553}) 9554 9555(define_insn_and_split "copysignsf3_const" 9556 [(set (match_operand:SF 0 "register_operand" "=x") 9557 (unspec:SF 9558 [(match_operand:V4SF 1 "vector_move_operand" "xmC") 9559 (match_operand:SF 2 "register_operand" "0") 9560 (match_operand:V4SF 3 "nonimmediate_operand" "xm")] 9561 UNSPEC_COPYSIGN))] 9562 "TARGET_SSE_MATH" 9563 "#" 9564 "&& reload_completed" 9565 [(const_int 0)] 9566{ 9567 ix86_split_copysign_const (operands); 9568 DONE; 9569}) 9570 9571(define_insn "copysignsf3_var" 9572 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x") 9573 (unspec:SF 9574 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x") 9575 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x") 9576 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0") 9577 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")] 9578 UNSPEC_COPYSIGN)) 9579 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))] 9580 "TARGET_SSE_MATH" 9581 "#") 9582 9583(define_split 9584 [(set (match_operand:SF 0 "register_operand" "") 9585 (unspec:SF 9586 [(match_operand:SF 2 "register_operand" "") 9587 (match_operand:SF 3 "register_operand" "") 9588 (match_operand:V4SF 4 "" "") 9589 (match_operand:V4SF 5 "" "")] 9590 UNSPEC_COPYSIGN)) 9591 (clobber (match_scratch:V4SF 1 ""))] 9592 "TARGET_SSE_MATH && reload_completed" 9593 [(const_int 0)] 9594{ 9595 ix86_split_copysign_var (operands); 9596 DONE; 9597}) 9598 9599(define_expand "negdf2" 9600 [(set (match_operand:DF 0 "nonimmediate_operand" "") 9601 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))] 9602 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 9603 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;") 9604 9605(define_expand "absdf2" 9606 [(set (match_operand:DF 0 "nonimmediate_operand" "") 9607 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))] 9608 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 9609 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;") 9610 9611(define_insn "*absnegdf2_mixed" 9612 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,f#Y,rm") 9613 (match_operator:DF 3 "absneg_operator" 9614 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#f,0 ,0")])) 9615 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X")) 9616 (clobber (reg:CC FLAGS_REG))] 9617 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387 9618 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)" 9619 "#") 9620 9621(define_insn "*absnegdf2_sse" 9622 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm") 9623 (match_operator:DF 3 "absneg_operator" 9624 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")])) 9625 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X")) 9626 (clobber (reg:CC FLAGS_REG))] 9627 "TARGET_SSE2 && TARGET_SSE_MATH 9628 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)" 9629 "#") 9630 9631(define_insn "*absnegdf2_i387" 9632 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm") 9633 (match_operator:DF 3 "absneg_operator" 9634 [(match_operand:DF 1 "nonimmediate_operand" "0,0")])) 9635 (use (match_operand 2 "" "")) 9636 (clobber (reg:CC FLAGS_REG))] 9637 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH) 9638 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)" 9639 "#") 9640 9641(define_expand "copysigndf3" 9642 [(match_operand:DF 0 "register_operand" "") 9643 (match_operand:DF 1 "nonmemory_operand" "") 9644 (match_operand:DF 2 "register_operand" "")] 9645 "TARGET_SSE2 && TARGET_SSE_MATH" 9646{ 9647 ix86_expand_copysign (operands); 9648 DONE; 9649}) 9650 9651(define_insn_and_split "copysigndf3_const" 9652 [(set (match_operand:DF 0 "register_operand" "=x") 9653 (unspec:DF 9654 [(match_operand:V2DF 1 "vector_move_operand" "xmC") 9655 (match_operand:DF 2 "register_operand" "0") 9656 (match_operand:V2DF 3 "nonimmediate_operand" "xm")] 9657 UNSPEC_COPYSIGN))] 9658 "TARGET_SSE2 && TARGET_SSE_MATH" 9659 "#" 9660 "&& reload_completed" 9661 [(const_int 0)] 9662{ 9663 ix86_split_copysign_const (operands); 9664 DONE; 9665}) 9666 9667(define_insn "copysigndf3_var" 9668 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x") 9669 (unspec:DF 9670 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x") 9671 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x") 9672 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0") 9673 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")] 9674 UNSPEC_COPYSIGN)) 9675 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))] 9676 "TARGET_SSE2 && TARGET_SSE_MATH" 9677 "#") 9678 9679(define_split 9680 [(set (match_operand:DF 0 "register_operand" "") 9681 (unspec:DF 9682 [(match_operand:DF 2 "register_operand" "") 9683 (match_operand:DF 3 "register_operand" "") 9684 (match_operand:V2DF 4 "" "") 9685 (match_operand:V2DF 5 "" "")] 9686 UNSPEC_COPYSIGN)) 9687 (clobber (match_scratch:V2DF 1 ""))] 9688 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed" 9689 [(const_int 0)] 9690{ 9691 ix86_split_copysign_var (operands); 9692 DONE; 9693}) 9694 9695(define_expand "negxf2" 9696 [(set (match_operand:XF 0 "nonimmediate_operand" "") 9697 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))] 9698 "TARGET_80387" 9699 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;") 9700 9701(define_expand "absxf2" 9702 [(set (match_operand:XF 0 "nonimmediate_operand" "") 9703 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))] 9704 "TARGET_80387" 9705 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;") 9706 9707(define_insn "*absnegxf2_i387" 9708 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm") 9709 (match_operator:XF 3 "absneg_operator" 9710 [(match_operand:XF 1 "nonimmediate_operand" "0,0")])) 9711 (use (match_operand 2 "" "")) 9712 (clobber (reg:CC FLAGS_REG))] 9713 "TARGET_80387 9714 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)" 9715 "#") 9716 9717;; Splitters for fp abs and neg. 9718 9719(define_split 9720 [(set (match_operand 0 "fp_register_operand" "") 9721 (match_operator 1 "absneg_operator" [(match_dup 0)])) 9722 (use (match_operand 2 "" "")) 9723 (clobber (reg:CC FLAGS_REG))] 9724 "reload_completed" 9725 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))]) 9726 9727(define_split 9728 [(set (match_operand 0 "register_operand" "") 9729 (match_operator 3 "absneg_operator" 9730 [(match_operand 1 "register_operand" "")])) 9731 (use (match_operand 2 "nonimmediate_operand" "")) 9732 (clobber (reg:CC FLAGS_REG))] 9733 "reload_completed && SSE_REG_P (operands[0])" 9734 [(set (match_dup 0) (match_dup 3))] 9735{ 9736 enum machine_mode mode = GET_MODE (operands[0]); 9737 enum machine_mode vmode = GET_MODE (operands[2]); 9738 rtx tmp; 9739 9740 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0); 9741 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0); 9742 if (operands_match_p (operands[0], operands[2])) 9743 { 9744 tmp = operands[1]; 9745 operands[1] = operands[2]; 9746 operands[2] = tmp; 9747 } 9748 if (GET_CODE (operands[3]) == ABS) 9749 tmp = gen_rtx_AND (vmode, operands[1], operands[2]); 9750 else 9751 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]); 9752 operands[3] = tmp; 9753}) 9754 9755(define_split 9756 [(set (match_operand:SF 0 "register_operand" "") 9757 (match_operator:SF 1 "absneg_operator" [(match_dup 0)])) 9758 (use (match_operand:V4SF 2 "" "")) 9759 (clobber (reg:CC FLAGS_REG))] 9760 "reload_completed" 9761 [(parallel [(set (match_dup 0) (match_dup 1)) 9762 (clobber (reg:CC FLAGS_REG))])] 9763{ 9764 rtx tmp; 9765 operands[0] = gen_lowpart (SImode, operands[0]); 9766 if (GET_CODE (operands[1]) == ABS) 9767 { 9768 tmp = gen_int_mode (0x7fffffff, SImode); 9769 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9770 } 9771 else 9772 { 9773 tmp = gen_int_mode (0x80000000, SImode); 9774 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 9775 } 9776 operands[1] = tmp; 9777}) 9778 9779(define_split 9780 [(set (match_operand:DF 0 "register_operand" "") 9781 (match_operator:DF 1 "absneg_operator" [(match_dup 0)])) 9782 (use (match_operand 2 "" "")) 9783 (clobber (reg:CC FLAGS_REG))] 9784 "reload_completed" 9785 [(parallel [(set (match_dup 0) (match_dup 1)) 9786 (clobber (reg:CC FLAGS_REG))])] 9787{ 9788 rtx tmp; 9789 if (TARGET_64BIT) 9790 { 9791 tmp = gen_lowpart (DImode, operands[0]); 9792 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63)); 9793 operands[0] = tmp; 9794 9795 if (GET_CODE (operands[1]) == ABS) 9796 tmp = const0_rtx; 9797 else 9798 tmp = gen_rtx_NOT (DImode, tmp); 9799 } 9800 else 9801 { 9802 operands[0] = gen_highpart (SImode, operands[0]); 9803 if (GET_CODE (operands[1]) == ABS) 9804 { 9805 tmp = gen_int_mode (0x7fffffff, SImode); 9806 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9807 } 9808 else 9809 { 9810 tmp = gen_int_mode (0x80000000, SImode); 9811 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 9812 } 9813 } 9814 operands[1] = tmp; 9815}) 9816 9817(define_split 9818 [(set (match_operand:XF 0 "register_operand" "") 9819 (match_operator:XF 1 "absneg_operator" [(match_dup 0)])) 9820 (use (match_operand 2 "" "")) 9821 (clobber (reg:CC FLAGS_REG))] 9822 "reload_completed" 9823 [(parallel [(set (match_dup 0) (match_dup 1)) 9824 (clobber (reg:CC FLAGS_REG))])] 9825{ 9826 rtx tmp; 9827 operands[0] = gen_rtx_REG (SImode, 9828 true_regnum (operands[0]) 9829 + (TARGET_64BIT ? 1 : 2)); 9830 if (GET_CODE (operands[1]) == ABS) 9831 { 9832 tmp = GEN_INT (0x7fff); 9833 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9834 } 9835 else 9836 { 9837 tmp = GEN_INT (0x8000); 9838 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 9839 } 9840 operands[1] = tmp; 9841}) 9842 9843(define_split 9844 [(set (match_operand 0 "memory_operand" "") 9845 (match_operator 1 "absneg_operator" [(match_dup 0)])) 9846 (use (match_operand 2 "" "")) 9847 (clobber (reg:CC FLAGS_REG))] 9848 "reload_completed" 9849 [(parallel [(set (match_dup 0) (match_dup 1)) 9850 (clobber (reg:CC FLAGS_REG))])] 9851{ 9852 enum machine_mode mode = GET_MODE (operands[0]); 9853 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode); 9854 rtx tmp; 9855 9856 operands[0] = adjust_address (operands[0], QImode, size - 1); 9857 if (GET_CODE (operands[1]) == ABS) 9858 { 9859 tmp = gen_int_mode (0x7f, QImode); 9860 tmp = gen_rtx_AND (QImode, operands[0], tmp); 9861 } 9862 else 9863 { 9864 tmp = gen_int_mode (0x80, QImode); 9865 tmp = gen_rtx_XOR (QImode, operands[0], tmp); 9866 } 9867 operands[1] = tmp; 9868}) 9869 9870;; Conditionalize these after reload. If they match before reload, we 9871;; lose the clobber and ability to use integer instructions. 9872 9873(define_insn "*negsf2_1" 9874 [(set (match_operand:SF 0 "register_operand" "=f") 9875 (neg:SF (match_operand:SF 1 "register_operand" "0")))] 9876 "TARGET_80387 && reload_completed" 9877 "fchs" 9878 [(set_attr "type" "fsgn") 9879 (set_attr "mode" "SF")]) 9880 9881(define_insn "*negdf2_1" 9882 [(set (match_operand:DF 0 "register_operand" "=f") 9883 (neg:DF (match_operand:DF 1 "register_operand" "0")))] 9884 "TARGET_80387 && reload_completed" 9885 "fchs" 9886 [(set_attr "type" "fsgn") 9887 (set_attr "mode" "DF")]) 9888 9889(define_insn "*negxf2_1" 9890 [(set (match_operand:XF 0 "register_operand" "=f") 9891 (neg:XF (match_operand:XF 1 "register_operand" "0")))] 9892 "TARGET_80387 && reload_completed" 9893 "fchs" 9894 [(set_attr "type" "fsgn") 9895 (set_attr "mode" "XF")]) 9896 9897(define_insn "*abssf2_1" 9898 [(set (match_operand:SF 0 "register_operand" "=f") 9899 (abs:SF (match_operand:SF 1 "register_operand" "0")))] 9900 "TARGET_80387 && reload_completed" 9901 "fabs" 9902 [(set_attr "type" "fsgn") 9903 (set_attr "mode" "SF")]) 9904 9905(define_insn "*absdf2_1" 9906 [(set (match_operand:DF 0 "register_operand" "=f") 9907 (abs:DF (match_operand:DF 1 "register_operand" "0")))] 9908 "TARGET_80387 && reload_completed" 9909 "fabs" 9910 [(set_attr "type" "fsgn") 9911 (set_attr "mode" "DF")]) 9912 9913(define_insn "*absxf2_1" 9914 [(set (match_operand:XF 0 "register_operand" "=f") 9915 (abs:XF (match_operand:XF 1 "register_operand" "0")))] 9916 "TARGET_80387 && reload_completed" 9917 "fabs" 9918 [(set_attr "type" "fsgn") 9919 (set_attr "mode" "DF")]) 9920 9921(define_insn "*negextendsfdf2" 9922 [(set (match_operand:DF 0 "register_operand" "=f") 9923 (neg:DF (float_extend:DF 9924 (match_operand:SF 1 "register_operand" "0"))))] 9925 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 9926 "fchs" 9927 [(set_attr "type" "fsgn") 9928 (set_attr "mode" "DF")]) 9929 9930(define_insn "*negextenddfxf2" 9931 [(set (match_operand:XF 0 "register_operand" "=f") 9932 (neg:XF (float_extend:XF 9933 (match_operand:DF 1 "register_operand" "0"))))] 9934 "TARGET_80387" 9935 "fchs" 9936 [(set_attr "type" "fsgn") 9937 (set_attr "mode" "XF")]) 9938 9939(define_insn "*negextendsfxf2" 9940 [(set (match_operand:XF 0 "register_operand" "=f") 9941 (neg:XF (float_extend:XF 9942 (match_operand:SF 1 "register_operand" "0"))))] 9943 "TARGET_80387" 9944 "fchs" 9945 [(set_attr "type" "fsgn") 9946 (set_attr "mode" "XF")]) 9947 9948(define_insn "*absextendsfdf2" 9949 [(set (match_operand:DF 0 "register_operand" "=f") 9950 (abs:DF (float_extend:DF 9951 (match_operand:SF 1 "register_operand" "0"))))] 9952 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 9953 "fabs" 9954 [(set_attr "type" "fsgn") 9955 (set_attr "mode" "DF")]) 9956 9957(define_insn "*absextenddfxf2" 9958 [(set (match_operand:XF 0 "register_operand" "=f") 9959 (abs:XF (float_extend:XF 9960 (match_operand:DF 1 "register_operand" "0"))))] 9961 "TARGET_80387" 9962 "fabs" 9963 [(set_attr "type" "fsgn") 9964 (set_attr "mode" "XF")]) 9965 9966(define_insn "*absextendsfxf2" 9967 [(set (match_operand:XF 0 "register_operand" "=f") 9968 (abs:XF (float_extend:XF 9969 (match_operand:SF 1 "register_operand" "0"))))] 9970 "TARGET_80387" 9971 "fabs" 9972 [(set_attr "type" "fsgn") 9973 (set_attr "mode" "XF")]) 9974 9975;; One complement instructions 9976 9977(define_expand "one_cmpldi2" 9978 [(set (match_operand:DI 0 "nonimmediate_operand" "") 9979 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))] 9980 "TARGET_64BIT" 9981 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;") 9982 9983(define_insn "*one_cmpldi2_1_rex64" 9984 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9985 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))] 9986 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)" 9987 "not{q}\t%0" 9988 [(set_attr "type" "negnot") 9989 (set_attr "mode" "DI")]) 9990 9991(define_insn "*one_cmpldi2_2_rex64" 9992 [(set (reg FLAGS_REG) 9993 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")) 9994 (const_int 0))) 9995 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9996 (not:DI (match_dup 1)))] 9997 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9998 && ix86_unary_operator_ok (NOT, DImode, operands)" 9999 "#" 10000 [(set_attr "type" "alu1") 10001 (set_attr "mode" "DI")]) 10002 10003(define_split 10004 [(set (match_operand 0 "flags_reg_operand" "") 10005 (match_operator 2 "compare_operator" 10006 [(not:DI (match_operand:DI 3 "nonimmediate_operand" "")) 10007 (const_int 0)])) 10008 (set (match_operand:DI 1 "nonimmediate_operand" "") 10009 (not:DI (match_dup 3)))] 10010 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 10011 [(parallel [(set (match_dup 0) 10012 (match_op_dup 2 10013 [(xor:DI (match_dup 3) (const_int -1)) 10014 (const_int 0)])) 10015 (set (match_dup 1) 10016 (xor:DI (match_dup 3) (const_int -1)))])] 10017 "") 10018 10019(define_expand "one_cmplsi2" 10020 [(set (match_operand:SI 0 "nonimmediate_operand" "") 10021 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))] 10022 "" 10023 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;") 10024 10025(define_insn "*one_cmplsi2_1" 10026 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 10027 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))] 10028 "ix86_unary_operator_ok (NOT, SImode, operands)" 10029 "not{l}\t%0" 10030 [(set_attr "type" "negnot") 10031 (set_attr "mode" "SI")]) 10032 10033;; ??? Currently never generated - xor is used instead. 10034(define_insn "*one_cmplsi2_1_zext" 10035 [(set (match_operand:DI 0 "register_operand" "=r") 10036 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))] 10037 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)" 10038 "not{l}\t%k0" 10039 [(set_attr "type" "negnot") 10040 (set_attr "mode" "SI")]) 10041 10042(define_insn "*one_cmplsi2_2" 10043 [(set (reg FLAGS_REG) 10044 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")) 10045 (const_int 0))) 10046 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 10047 (not:SI (match_dup 1)))] 10048 "ix86_match_ccmode (insn, CCNOmode) 10049 && ix86_unary_operator_ok (NOT, SImode, operands)" 10050 "#" 10051 [(set_attr "type" "alu1") 10052 (set_attr "mode" "SI")]) 10053 10054(define_split 10055 [(set (match_operand 0 "flags_reg_operand" "") 10056 (match_operator 2 "compare_operator" 10057 [(not:SI (match_operand:SI 3 "nonimmediate_operand" "")) 10058 (const_int 0)])) 10059 (set (match_operand:SI 1 "nonimmediate_operand" "") 10060 (not:SI (match_dup 3)))] 10061 "ix86_match_ccmode (insn, CCNOmode)" 10062 [(parallel [(set (match_dup 0) 10063 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 10064 (const_int 0)])) 10065 (set (match_dup 1) 10066 (xor:SI (match_dup 3) (const_int -1)))])] 10067 "") 10068 10069;; ??? Currently never generated - xor is used instead. 10070(define_insn "*one_cmplsi2_2_zext" 10071 [(set (reg FLAGS_REG) 10072 (compare (not:SI (match_operand:SI 1 "register_operand" "0")) 10073 (const_int 0))) 10074 (set (match_operand:DI 0 "register_operand" "=r") 10075 (zero_extend:DI (not:SI (match_dup 1))))] 10076 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 10077 && ix86_unary_operator_ok (NOT, SImode, operands)" 10078 "#" 10079 [(set_attr "type" "alu1") 10080 (set_attr "mode" "SI")]) 10081 10082(define_split 10083 [(set (match_operand 0 "flags_reg_operand" "") 10084 (match_operator 2 "compare_operator" 10085 [(not:SI (match_operand:SI 3 "register_operand" "")) 10086 (const_int 0)])) 10087 (set (match_operand:DI 1 "register_operand" "") 10088 (zero_extend:DI (not:SI (match_dup 3))))] 10089 "ix86_match_ccmode (insn, CCNOmode)" 10090 [(parallel [(set (match_dup 0) 10091 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 10092 (const_int 0)])) 10093 (set (match_dup 1) 10094 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])] 10095 "") 10096 10097(define_expand "one_cmplhi2" 10098 [(set (match_operand:HI 0 "nonimmediate_operand" "") 10099 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))] 10100 "TARGET_HIMODE_MATH" 10101 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;") 10102 10103(define_insn "*one_cmplhi2_1" 10104 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10105 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] 10106 "ix86_unary_operator_ok (NOT, HImode, operands)" 10107 "not{w}\t%0" 10108 [(set_attr "type" "negnot") 10109 (set_attr "mode" "HI")]) 10110 10111(define_insn "*one_cmplhi2_2" 10112 [(set (reg FLAGS_REG) 10113 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")) 10114 (const_int 0))) 10115 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10116 (not:HI (match_dup 1)))] 10117 "ix86_match_ccmode (insn, CCNOmode) 10118 && ix86_unary_operator_ok (NEG, HImode, operands)" 10119 "#" 10120 [(set_attr "type" "alu1") 10121 (set_attr "mode" "HI")]) 10122 10123(define_split 10124 [(set (match_operand 0 "flags_reg_operand" "") 10125 (match_operator 2 "compare_operator" 10126 [(not:HI (match_operand:HI 3 "nonimmediate_operand" "")) 10127 (const_int 0)])) 10128 (set (match_operand:HI 1 "nonimmediate_operand" "") 10129 (not:HI (match_dup 3)))] 10130 "ix86_match_ccmode (insn, CCNOmode)" 10131 [(parallel [(set (match_dup 0) 10132 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1)) 10133 (const_int 0)])) 10134 (set (match_dup 1) 10135 (xor:HI (match_dup 3) (const_int -1)))])] 10136 "") 10137 10138;; %%% Potential partial reg stall on alternative 1. What to do? 10139(define_expand "one_cmplqi2" 10140 [(set (match_operand:QI 0 "nonimmediate_operand" "") 10141 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))] 10142 "TARGET_QIMODE_MATH" 10143 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;") 10144 10145(define_insn "*one_cmplqi2_1" 10146 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") 10147 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] 10148 "ix86_unary_operator_ok (NOT, QImode, operands)" 10149 "@ 10150 not{b}\t%0 10151 not{l}\t%k0" 10152 [(set_attr "type" "negnot") 10153 (set_attr "mode" "QI,SI")]) 10154 10155(define_insn "*one_cmplqi2_2" 10156 [(set (reg FLAGS_REG) 10157 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")) 10158 (const_int 0))) 10159 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 10160 (not:QI (match_dup 1)))] 10161 "ix86_match_ccmode (insn, CCNOmode) 10162 && ix86_unary_operator_ok (NOT, QImode, operands)" 10163 "#" 10164 [(set_attr "type" "alu1") 10165 (set_attr "mode" "QI")]) 10166 10167(define_split 10168 [(set (match_operand 0 "flags_reg_operand" "") 10169 (match_operator 2 "compare_operator" 10170 [(not:QI (match_operand:QI 3 "nonimmediate_operand" "")) 10171 (const_int 0)])) 10172 (set (match_operand:QI 1 "nonimmediate_operand" "") 10173 (not:QI (match_dup 3)))] 10174 "ix86_match_ccmode (insn, CCNOmode)" 10175 [(parallel [(set (match_dup 0) 10176 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1)) 10177 (const_int 0)])) 10178 (set (match_dup 1) 10179 (xor:QI (match_dup 3) (const_int -1)))])] 10180 "") 10181 10182;; Arithmetic shift instructions 10183 10184;; DImode shifts are implemented using the i386 "shift double" opcode, 10185;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count 10186;; is variable, then the count is in %cl and the "imm" operand is dropped 10187;; from the assembler input. 10188;; 10189;; This instruction shifts the target reg/mem as usual, but instead of 10190;; shifting in zeros, bits are shifted in from reg operand. If the insn 10191;; is a left shift double, bits are taken from the high order bits of 10192;; reg, else if the insn is a shift right double, bits are taken from the 10193;; low order bits of reg. So if %eax is "1234" and %edx is "5678", 10194;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". 10195;; 10196;; Since sh[lr]d does not change the `reg' operand, that is done 10197;; separately, making all shifts emit pairs of shift double and normal 10198;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to 10199;; support a 63 bit shift, each shift where the count is in a reg expands 10200;; to a pair of shifts, a branch, a shift by 32 and a label. 10201;; 10202;; If the shift count is a constant, we need never emit more than one 10203;; shift pair, instead using moves and sign extension for counts greater 10204;; than 31. 10205 10206(define_expand "ashlti3" 10207 [(parallel [(set (match_operand:TI 0 "register_operand" "") 10208 (ashift:TI (match_operand:TI 1 "register_operand" "") 10209 (match_operand:QI 2 "nonmemory_operand" ""))) 10210 (clobber (reg:CC FLAGS_REG))])] 10211 "TARGET_64BIT" 10212{ 10213 if (! immediate_operand (operands[2], QImode)) 10214 { 10215 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2])); 10216 DONE; 10217 } 10218 ix86_expand_binary_operator (ASHIFT, TImode, operands); 10219 DONE; 10220}) 10221 10222(define_insn "ashlti3_1" 10223 [(set (match_operand:TI 0 "register_operand" "=r") 10224 (ashift:TI (match_operand:TI 1 "register_operand" "0") 10225 (match_operand:QI 2 "register_operand" "c"))) 10226 (clobber (match_scratch:DI 3 "=&r")) 10227 (clobber (reg:CC FLAGS_REG))] 10228 "TARGET_64BIT" 10229 "#" 10230 [(set_attr "type" "multi")]) 10231 10232(define_insn "*ashlti3_2" 10233 [(set (match_operand:TI 0 "register_operand" "=r") 10234 (ashift:TI (match_operand:TI 1 "register_operand" "0") 10235 (match_operand:QI 2 "immediate_operand" "O"))) 10236 (clobber (reg:CC FLAGS_REG))] 10237 "TARGET_64BIT" 10238 "#" 10239 [(set_attr "type" "multi")]) 10240 10241(define_split 10242 [(set (match_operand:TI 0 "register_operand" "") 10243 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "") 10244 (match_operand:QI 2 "register_operand" ""))) 10245 (clobber (match_scratch:DI 3 "")) 10246 (clobber (reg:CC FLAGS_REG))] 10247 "TARGET_64BIT && reload_completed" 10248 [(const_int 0)] 10249 "ix86_split_ashl (operands, operands[3], TImode); DONE;") 10250 10251(define_split 10252 [(set (match_operand:TI 0 "register_operand" "") 10253 (ashift:TI (match_operand:TI 1 "register_operand" "") 10254 (match_operand:QI 2 "immediate_operand" ""))) 10255 (clobber (reg:CC FLAGS_REG))] 10256 "TARGET_64BIT && reload_completed" 10257 [(const_int 0)] 10258 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;") 10259 10260(define_insn "x86_64_shld" 10261 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m") 10262 (ior:DI (ashift:DI (match_dup 0) 10263 (match_operand:QI 2 "nonmemory_operand" "J,c")) 10264 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r") 10265 (minus:QI (const_int 64) (match_dup 2))))) 10266 (clobber (reg:CC FLAGS_REG))] 10267 "TARGET_64BIT" 10268 "@ 10269 shld{q}\t{%2, %1, %0|%0, %1, %2} 10270 shld{q}\t{%s2%1, %0|%0, %1, %2}" 10271 [(set_attr "type" "ishift") 10272 (set_attr "prefix_0f" "1") 10273 (set_attr "mode" "DI") 10274 (set_attr "athlon_decode" "vector")]) 10275 10276(define_expand "x86_64_shift_adj" 10277 [(set (reg:CCZ FLAGS_REG) 10278 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "") 10279 (const_int 64)) 10280 (const_int 0))) 10281 (set (match_operand:DI 0 "register_operand" "") 10282 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10283 (match_operand:DI 1 "register_operand" "") 10284 (match_dup 0))) 10285 (set (match_dup 1) 10286 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10287 (match_operand:DI 3 "register_operand" "r") 10288 (match_dup 1)))] 10289 "TARGET_64BIT" 10290 "") 10291 10292(define_expand "ashldi3" 10293 [(set (match_operand:DI 0 "shiftdi_operand" "") 10294 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "") 10295 (match_operand:QI 2 "nonmemory_operand" "")))] 10296 "" 10297 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;") 10298 10299(define_insn "*ashldi3_1_rex64" 10300 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 10301 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l") 10302 (match_operand:QI 2 "nonmemory_operand" "cJ,M"))) 10303 (clobber (reg:CC FLAGS_REG))] 10304 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)" 10305{ 10306 switch (get_attr_type (insn)) 10307 { 10308 case TYPE_ALU: 10309 gcc_assert (operands[2] == const1_rtx); 10310 gcc_assert (rtx_equal_p (operands[0], operands[1])); 10311 return "add{q}\t{%0, %0|%0, %0}"; 10312 10313 case TYPE_LEA: 10314 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 10315 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3); 10316 operands[1] = gen_rtx_MULT (DImode, operands[1], 10317 GEN_INT (1 << INTVAL (operands[2]))); 10318 return "lea{q}\t{%a1, %0|%0, %a1}"; 10319 10320 default: 10321 if (REG_P (operands[2])) 10322 return "sal{q}\t{%b2, %0|%0, %b2}"; 10323 else if (operands[2] == const1_rtx 10324 && (TARGET_SHIFT1 || optimize_size)) 10325 return "sal{q}\t%0"; 10326 else 10327 return "sal{q}\t{%2, %0|%0, %2}"; 10328 } 10329} 10330 [(set (attr "type") 10331 (cond [(eq_attr "alternative" "1") 10332 (const_string "lea") 10333 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10334 (const_int 0)) 10335 (match_operand 0 "register_operand" "")) 10336 (match_operand 2 "const1_operand" "")) 10337 (const_string "alu") 10338 ] 10339 (const_string "ishift"))) 10340 (set_attr "mode" "DI")]) 10341 10342;; Convert lea to the lea pattern to avoid flags dependency. 10343(define_split 10344 [(set (match_operand:DI 0 "register_operand" "") 10345 (ashift:DI (match_operand:DI 1 "index_register_operand" "") 10346 (match_operand:QI 2 "immediate_operand" ""))) 10347 (clobber (reg:CC FLAGS_REG))] 10348 "TARGET_64BIT && reload_completed 10349 && true_regnum (operands[0]) != true_regnum (operands[1])" 10350 [(set (match_dup 0) 10351 (mult:DI (match_dup 1) 10352 (match_dup 2)))] 10353 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);") 10354 10355;; This pattern can't accept a variable shift count, since shifts by 10356;; zero don't affect the flags. We assume that shifts by constant 10357;; zero are optimized away. 10358(define_insn "*ashldi3_cmp_rex64" 10359 [(set (reg FLAGS_REG) 10360 (compare 10361 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0") 10362 (match_operand:QI 2 "immediate_operand" "e")) 10363 (const_int 0))) 10364 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 10365 (ashift:DI (match_dup 1) (match_dup 2)))] 10366 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 10367 && ix86_binary_operator_ok (ASHIFT, DImode, operands)" 10368{ 10369 switch (get_attr_type (insn)) 10370 { 10371 case TYPE_ALU: 10372 gcc_assert (operands[2] == const1_rtx); 10373 return "add{q}\t{%0, %0|%0, %0}"; 10374 10375 default: 10376 if (REG_P (operands[2])) 10377 return "sal{q}\t{%b2, %0|%0, %b2}"; 10378 else if (operands[2] == const1_rtx 10379 && (TARGET_SHIFT1 || optimize_size)) 10380 return "sal{q}\t%0"; 10381 else 10382 return "sal{q}\t{%2, %0|%0, %2}"; 10383 } 10384} 10385 [(set (attr "type") 10386 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10387 (const_int 0)) 10388 (match_operand 0 "register_operand" "")) 10389 (match_operand 2 "const1_operand" "")) 10390 (const_string "alu") 10391 ] 10392 (const_string "ishift"))) 10393 (set_attr "mode" "DI")]) 10394 10395(define_insn "*ashldi3_cconly_rex64" 10396 [(set (reg FLAGS_REG) 10397 (compare 10398 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0") 10399 (match_operand:QI 2 "immediate_operand" "e")) 10400 (const_int 0))) 10401 (clobber (match_scratch:DI 0 "=r"))] 10402 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 10403 && ix86_binary_operator_ok (ASHIFT, DImode, operands)" 10404{ 10405 switch (get_attr_type (insn)) 10406 { 10407 case TYPE_ALU: 10408 gcc_assert (operands[2] == const1_rtx); 10409 return "add{q}\t{%0, %0|%0, %0}"; 10410 10411 default: 10412 if (REG_P (operands[2])) 10413 return "sal{q}\t{%b2, %0|%0, %b2}"; 10414 else if (operands[2] == const1_rtx 10415 && (TARGET_SHIFT1 || optimize_size)) 10416 return "sal{q}\t%0"; 10417 else 10418 return "sal{q}\t{%2, %0|%0, %2}"; 10419 } 10420} 10421 [(set (attr "type") 10422 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10423 (const_int 0)) 10424 (match_operand 0 "register_operand" "")) 10425 (match_operand 2 "const1_operand" "")) 10426 (const_string "alu") 10427 ] 10428 (const_string "ishift"))) 10429 (set_attr "mode" "DI")]) 10430 10431(define_insn "*ashldi3_1" 10432 [(set (match_operand:DI 0 "register_operand" "=&r,r") 10433 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0") 10434 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc"))) 10435 (clobber (reg:CC FLAGS_REG))] 10436 "!TARGET_64BIT" 10437 "#" 10438 [(set_attr "type" "multi")]) 10439 10440;; By default we don't ask for a scratch register, because when DImode 10441;; values are manipulated, registers are already at a premium. But if 10442;; we have one handy, we won't turn it away. 10443(define_peephole2 10444 [(match_scratch:SI 3 "r") 10445 (parallel [(set (match_operand:DI 0 "register_operand" "") 10446 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "") 10447 (match_operand:QI 2 "nonmemory_operand" ""))) 10448 (clobber (reg:CC FLAGS_REG))]) 10449 (match_dup 3)] 10450 "!TARGET_64BIT && TARGET_CMOVE" 10451 [(const_int 0)] 10452 "ix86_split_ashl (operands, operands[3], DImode); DONE;") 10453 10454(define_split 10455 [(set (match_operand:DI 0 "register_operand" "") 10456 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "") 10457 (match_operand:QI 2 "nonmemory_operand" ""))) 10458 (clobber (reg:CC FLAGS_REG))] 10459 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) 10460 ? flow2_completed : reload_completed)" 10461 [(const_int 0)] 10462 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;") 10463 10464(define_insn "x86_shld_1" 10465 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m") 10466 (ior:SI (ashift:SI (match_dup 0) 10467 (match_operand:QI 2 "nonmemory_operand" "I,c")) 10468 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") 10469 (minus:QI (const_int 32) (match_dup 2))))) 10470 (clobber (reg:CC FLAGS_REG))] 10471 "" 10472 "@ 10473 shld{l}\t{%2, %1, %0|%0, %1, %2} 10474 shld{l}\t{%s2%1, %0|%0, %1, %2}" 10475 [(set_attr "type" "ishift") 10476 (set_attr "prefix_0f" "1") 10477 (set_attr "mode" "SI") 10478 (set_attr "pent_pair" "np") 10479 (set_attr "athlon_decode" "vector")]) 10480 10481(define_expand "x86_shift_adj_1" 10482 [(set (reg:CCZ FLAGS_REG) 10483 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "") 10484 (const_int 32)) 10485 (const_int 0))) 10486 (set (match_operand:SI 0 "register_operand" "") 10487 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10488 (match_operand:SI 1 "register_operand" "") 10489 (match_dup 0))) 10490 (set (match_dup 1) 10491 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10492 (match_operand:SI 3 "register_operand" "r") 10493 (match_dup 1)))] 10494 "TARGET_CMOVE" 10495 "") 10496 10497(define_expand "x86_shift_adj_2" 10498 [(use (match_operand:SI 0 "register_operand" "")) 10499 (use (match_operand:SI 1 "register_operand" "")) 10500 (use (match_operand:QI 2 "register_operand" ""))] 10501 "" 10502{ 10503 rtx label = gen_label_rtx (); 10504 rtx tmp; 10505 10506 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32))); 10507 10508 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 10509 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 10510 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 10511 gen_rtx_LABEL_REF (VOIDmode, label), 10512 pc_rtx); 10513 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 10514 JUMP_LABEL (tmp) = label; 10515 10516 emit_move_insn (operands[0], operands[1]); 10517 ix86_expand_clear (operands[1]); 10518 10519 emit_label (label); 10520 LABEL_NUSES (label) = 1; 10521 10522 DONE; 10523}) 10524 10525(define_expand "ashlsi3" 10526 [(set (match_operand:SI 0 "nonimmediate_operand" "") 10527 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "") 10528 (match_operand:QI 2 "nonmemory_operand" ""))) 10529 (clobber (reg:CC FLAGS_REG))] 10530 "" 10531 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;") 10532 10533(define_insn "*ashlsi3_1" 10534 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 10535 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l") 10536 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 10537 (clobber (reg:CC FLAGS_REG))] 10538 "ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10539{ 10540 switch (get_attr_type (insn)) 10541 { 10542 case TYPE_ALU: 10543 gcc_assert (operands[2] == const1_rtx); 10544 gcc_assert (rtx_equal_p (operands[0], operands[1])); 10545 return "add{l}\t{%0, %0|%0, %0}"; 10546 10547 case TYPE_LEA: 10548 return "#"; 10549 10550 default: 10551 if (REG_P (operands[2])) 10552 return "sal{l}\t{%b2, %0|%0, %b2}"; 10553 else if (operands[2] == const1_rtx 10554 && (TARGET_SHIFT1 || optimize_size)) 10555 return "sal{l}\t%0"; 10556 else 10557 return "sal{l}\t{%2, %0|%0, %2}"; 10558 } 10559} 10560 [(set (attr "type") 10561 (cond [(eq_attr "alternative" "1") 10562 (const_string "lea") 10563 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10564 (const_int 0)) 10565 (match_operand 0 "register_operand" "")) 10566 (match_operand 2 "const1_operand" "")) 10567 (const_string "alu") 10568 ] 10569 (const_string "ishift"))) 10570 (set_attr "mode" "SI")]) 10571 10572;; Convert lea to the lea pattern to avoid flags dependency. 10573(define_split 10574 [(set (match_operand 0 "register_operand" "") 10575 (ashift (match_operand 1 "index_register_operand" "") 10576 (match_operand:QI 2 "const_int_operand" ""))) 10577 (clobber (reg:CC FLAGS_REG))] 10578 "reload_completed 10579 && true_regnum (operands[0]) != true_regnum (operands[1]) 10580 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4" 10581 [(const_int 0)] 10582{ 10583 rtx pat; 10584 enum machine_mode mode = GET_MODE (operands[0]); 10585 10586 if (GET_MODE_SIZE (mode) < 4) 10587 operands[0] = gen_lowpart (SImode, operands[0]); 10588 if (mode != Pmode) 10589 operands[1] = gen_lowpart (Pmode, operands[1]); 10590 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode); 10591 10592 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]); 10593 if (Pmode != SImode) 10594 pat = gen_rtx_SUBREG (SImode, pat, 0); 10595 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 10596 DONE; 10597}) 10598 10599;; Rare case of shifting RSP is handled by generating move and shift 10600(define_split 10601 [(set (match_operand 0 "register_operand" "") 10602 (ashift (match_operand 1 "register_operand" "") 10603 (match_operand:QI 2 "const_int_operand" ""))) 10604 (clobber (reg:CC FLAGS_REG))] 10605 "reload_completed 10606 && true_regnum (operands[0]) != true_regnum (operands[1])" 10607 [(const_int 0)] 10608{ 10609 rtx pat, clob; 10610 emit_move_insn (operands[1], operands[0]); 10611 pat = gen_rtx_SET (VOIDmode, operands[0], 10612 gen_rtx_ASHIFT (GET_MODE (operands[0]), 10613 operands[0], operands[2])); 10614 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); 10615 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob))); 10616 DONE; 10617}) 10618 10619(define_insn "*ashlsi3_1_zext" 10620 [(set (match_operand:DI 0 "register_operand" "=r,r") 10621 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l") 10622 (match_operand:QI 2 "nonmemory_operand" "cI,M")))) 10623 (clobber (reg:CC FLAGS_REG))] 10624 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10625{ 10626 switch (get_attr_type (insn)) 10627 { 10628 case TYPE_ALU: 10629 gcc_assert (operands[2] == const1_rtx); 10630 return "add{l}\t{%k0, %k0|%k0, %k0}"; 10631 10632 case TYPE_LEA: 10633 return "#"; 10634 10635 default: 10636 if (REG_P (operands[2])) 10637 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 10638 else if (operands[2] == const1_rtx 10639 && (TARGET_SHIFT1 || optimize_size)) 10640 return "sal{l}\t%k0"; 10641 else 10642 return "sal{l}\t{%2, %k0|%k0, %2}"; 10643 } 10644} 10645 [(set (attr "type") 10646 (cond [(eq_attr "alternative" "1") 10647 (const_string "lea") 10648 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10649 (const_int 0)) 10650 (match_operand 2 "const1_operand" "")) 10651 (const_string "alu") 10652 ] 10653 (const_string "ishift"))) 10654 (set_attr "mode" "SI")]) 10655 10656;; Convert lea to the lea pattern to avoid flags dependency. 10657(define_split 10658 [(set (match_operand:DI 0 "register_operand" "") 10659 (zero_extend:DI (ashift (match_operand 1 "register_operand" "") 10660 (match_operand:QI 2 "const_int_operand" "")))) 10661 (clobber (reg:CC FLAGS_REG))] 10662 "TARGET_64BIT && reload_completed 10663 && true_regnum (operands[0]) != true_regnum (operands[1])" 10664 [(set (match_dup 0) (zero_extend:DI 10665 (subreg:SI (mult:SI (match_dup 1) 10666 (match_dup 2)) 0)))] 10667{ 10668 operands[1] = gen_lowpart (Pmode, operands[1]); 10669 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode); 10670}) 10671 10672;; This pattern can't accept a variable shift count, since shifts by 10673;; zero don't affect the flags. We assume that shifts by constant 10674;; zero are optimized away. 10675(define_insn "*ashlsi3_cmp" 10676 [(set (reg FLAGS_REG) 10677 (compare 10678 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0") 10679 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10680 (const_int 0))) 10681 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 10682 (ashift:SI (match_dup 1) (match_dup 2)))] 10683 "ix86_match_ccmode (insn, CCGOCmode) 10684 && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10685{ 10686 switch (get_attr_type (insn)) 10687 { 10688 case TYPE_ALU: 10689 gcc_assert (operands[2] == const1_rtx); 10690 return "add{l}\t{%0, %0|%0, %0}"; 10691 10692 default: 10693 if (REG_P (operands[2])) 10694 return "sal{l}\t{%b2, %0|%0, %b2}"; 10695 else if (operands[2] == const1_rtx 10696 && (TARGET_SHIFT1 || optimize_size)) 10697 return "sal{l}\t%0"; 10698 else 10699 return "sal{l}\t{%2, %0|%0, %2}"; 10700 } 10701} 10702 [(set (attr "type") 10703 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10704 (const_int 0)) 10705 (match_operand 0 "register_operand" "")) 10706 (match_operand 2 "const1_operand" "")) 10707 (const_string "alu") 10708 ] 10709 (const_string "ishift"))) 10710 (set_attr "mode" "SI")]) 10711 10712(define_insn "*ashlsi3_cconly" 10713 [(set (reg FLAGS_REG) 10714 (compare 10715 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0") 10716 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10717 (const_int 0))) 10718 (clobber (match_scratch:SI 0 "=r"))] 10719 "ix86_match_ccmode (insn, CCGOCmode) 10720 && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10721{ 10722 switch (get_attr_type (insn)) 10723 { 10724 case TYPE_ALU: 10725 gcc_assert (operands[2] == const1_rtx); 10726 return "add{l}\t{%0, %0|%0, %0}"; 10727 10728 default: 10729 if (REG_P (operands[2])) 10730 return "sal{l}\t{%b2, %0|%0, %b2}"; 10731 else if (operands[2] == const1_rtx 10732 && (TARGET_SHIFT1 || optimize_size)) 10733 return "sal{l}\t%0"; 10734 else 10735 return "sal{l}\t{%2, %0|%0, %2}"; 10736 } 10737} 10738 [(set (attr "type") 10739 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10740 (const_int 0)) 10741 (match_operand 0 "register_operand" "")) 10742 (match_operand 2 "const1_operand" "")) 10743 (const_string "alu") 10744 ] 10745 (const_string "ishift"))) 10746 (set_attr "mode" "SI")]) 10747 10748(define_insn "*ashlsi3_cmp_zext" 10749 [(set (reg FLAGS_REG) 10750 (compare 10751 (ashift:SI (match_operand:SI 1 "register_operand" "0") 10752 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10753 (const_int 0))) 10754 (set (match_operand:DI 0 "register_operand" "=r") 10755 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 10756 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 10757 && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10758{ 10759 switch (get_attr_type (insn)) 10760 { 10761 case TYPE_ALU: 10762 gcc_assert (operands[2] == const1_rtx); 10763 return "add{l}\t{%k0, %k0|%k0, %k0}"; 10764 10765 default: 10766 if (REG_P (operands[2])) 10767 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 10768 else if (operands[2] == const1_rtx 10769 && (TARGET_SHIFT1 || optimize_size)) 10770 return "sal{l}\t%k0"; 10771 else 10772 return "sal{l}\t{%2, %k0|%k0, %2}"; 10773 } 10774} 10775 [(set (attr "type") 10776 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10777 (const_int 0)) 10778 (match_operand 2 "const1_operand" "")) 10779 (const_string "alu") 10780 ] 10781 (const_string "ishift"))) 10782 (set_attr "mode" "SI")]) 10783 10784(define_expand "ashlhi3" 10785 [(set (match_operand:HI 0 "nonimmediate_operand" "") 10786 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "") 10787 (match_operand:QI 2 "nonmemory_operand" ""))) 10788 (clobber (reg:CC FLAGS_REG))] 10789 "TARGET_HIMODE_MATH" 10790 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;") 10791 10792(define_insn "*ashlhi3_1_lea" 10793 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 10794 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l") 10795 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 10796 (clobber (reg:CC FLAGS_REG))] 10797 "!TARGET_PARTIAL_REG_STALL 10798 && ix86_binary_operator_ok (ASHIFT, HImode, operands)" 10799{ 10800 switch (get_attr_type (insn)) 10801 { 10802 case TYPE_LEA: 10803 return "#"; 10804 case TYPE_ALU: 10805 gcc_assert (operands[2] == const1_rtx); 10806 return "add{w}\t{%0, %0|%0, %0}"; 10807 10808 default: 10809 if (REG_P (operands[2])) 10810 return "sal{w}\t{%b2, %0|%0, %b2}"; 10811 else if (operands[2] == const1_rtx 10812 && (TARGET_SHIFT1 || optimize_size)) 10813 return "sal{w}\t%0"; 10814 else 10815 return "sal{w}\t{%2, %0|%0, %2}"; 10816 } 10817} 10818 [(set (attr "type") 10819 (cond [(eq_attr "alternative" "1") 10820 (const_string "lea") 10821 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10822 (const_int 0)) 10823 (match_operand 0 "register_operand" "")) 10824 (match_operand 2 "const1_operand" "")) 10825 (const_string "alu") 10826 ] 10827 (const_string "ishift"))) 10828 (set_attr "mode" "HI,SI")]) 10829 10830(define_insn "*ashlhi3_1" 10831 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10832 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") 10833 (match_operand:QI 2 "nonmemory_operand" "cI"))) 10834 (clobber (reg:CC FLAGS_REG))] 10835 "TARGET_PARTIAL_REG_STALL 10836 && ix86_binary_operator_ok (ASHIFT, HImode, operands)" 10837{ 10838 switch (get_attr_type (insn)) 10839 { 10840 case TYPE_ALU: 10841 gcc_assert (operands[2] == const1_rtx); 10842 return "add{w}\t{%0, %0|%0, %0}"; 10843 10844 default: 10845 if (REG_P (operands[2])) 10846 return "sal{w}\t{%b2, %0|%0, %b2}"; 10847 else if (operands[2] == const1_rtx 10848 && (TARGET_SHIFT1 || optimize_size)) 10849 return "sal{w}\t%0"; 10850 else 10851 return "sal{w}\t{%2, %0|%0, %2}"; 10852 } 10853} 10854 [(set (attr "type") 10855 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10856 (const_int 0)) 10857 (match_operand 0 "register_operand" "")) 10858 (match_operand 2 "const1_operand" "")) 10859 (const_string "alu") 10860 ] 10861 (const_string "ishift"))) 10862 (set_attr "mode" "HI")]) 10863 10864;; This pattern can't accept a variable shift count, since shifts by 10865;; zero don't affect the flags. We assume that shifts by constant 10866;; zero are optimized away. 10867(define_insn "*ashlhi3_cmp" 10868 [(set (reg FLAGS_REG) 10869 (compare 10870 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") 10871 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10872 (const_int 0))) 10873 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10874 (ashift:HI (match_dup 1) (match_dup 2)))] 10875 "ix86_match_ccmode (insn, CCGOCmode) 10876 && ix86_binary_operator_ok (ASHIFT, HImode, operands)" 10877{ 10878 switch (get_attr_type (insn)) 10879 { 10880 case TYPE_ALU: 10881 gcc_assert (operands[2] == const1_rtx); 10882 return "add{w}\t{%0, %0|%0, %0}"; 10883 10884 default: 10885 if (REG_P (operands[2])) 10886 return "sal{w}\t{%b2, %0|%0, %b2}"; 10887 else if (operands[2] == const1_rtx 10888 && (TARGET_SHIFT1 || optimize_size)) 10889 return "sal{w}\t%0"; 10890 else 10891 return "sal{w}\t{%2, %0|%0, %2}"; 10892 } 10893} 10894 [(set (attr "type") 10895 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10896 (const_int 0)) 10897 (match_operand 0 "register_operand" "")) 10898 (match_operand 2 "const1_operand" "")) 10899 (const_string "alu") 10900 ] 10901 (const_string "ishift"))) 10902 (set_attr "mode" "HI")]) 10903 10904(define_insn "*ashlhi3_cconly" 10905 [(set (reg FLAGS_REG) 10906 (compare 10907 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") 10908 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10909 (const_int 0))) 10910 (clobber (match_scratch:HI 0 "=r"))] 10911 "ix86_match_ccmode (insn, CCGOCmode) 10912 && ix86_binary_operator_ok (ASHIFT, HImode, operands)" 10913{ 10914 switch (get_attr_type (insn)) 10915 { 10916 case TYPE_ALU: 10917 gcc_assert (operands[2] == const1_rtx); 10918 return "add{w}\t{%0, %0|%0, %0}"; 10919 10920 default: 10921 if (REG_P (operands[2])) 10922 return "sal{w}\t{%b2, %0|%0, %b2}"; 10923 else if (operands[2] == const1_rtx 10924 && (TARGET_SHIFT1 || optimize_size)) 10925 return "sal{w}\t%0"; 10926 else 10927 return "sal{w}\t{%2, %0|%0, %2}"; 10928 } 10929} 10930 [(set (attr "type") 10931 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10932 (const_int 0)) 10933 (match_operand 0 "register_operand" "")) 10934 (match_operand 2 "const1_operand" "")) 10935 (const_string "alu") 10936 ] 10937 (const_string "ishift"))) 10938 (set_attr "mode" "HI")]) 10939 10940(define_expand "ashlqi3" 10941 [(set (match_operand:QI 0 "nonimmediate_operand" "") 10942 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "") 10943 (match_operand:QI 2 "nonmemory_operand" ""))) 10944 (clobber (reg:CC FLAGS_REG))] 10945 "TARGET_QIMODE_MATH" 10946 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;") 10947 10948;; %%% Potential partial reg stall on alternative 2. What to do? 10949 10950(define_insn "*ashlqi3_1_lea" 10951 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r") 10952 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l") 10953 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M"))) 10954 (clobber (reg:CC FLAGS_REG))] 10955 "!TARGET_PARTIAL_REG_STALL 10956 && ix86_binary_operator_ok (ASHIFT, QImode, operands)" 10957{ 10958 switch (get_attr_type (insn)) 10959 { 10960 case TYPE_LEA: 10961 return "#"; 10962 case TYPE_ALU: 10963 gcc_assert (operands[2] == const1_rtx); 10964 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) 10965 return "add{l}\t{%k0, %k0|%k0, %k0}"; 10966 else 10967 return "add{b}\t{%0, %0|%0, %0}"; 10968 10969 default: 10970 if (REG_P (operands[2])) 10971 { 10972 if (get_attr_mode (insn) == MODE_SI) 10973 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 10974 else 10975 return "sal{b}\t{%b2, %0|%0, %b2}"; 10976 } 10977 else if (operands[2] == const1_rtx 10978 && (TARGET_SHIFT1 || optimize_size)) 10979 { 10980 if (get_attr_mode (insn) == MODE_SI) 10981 return "sal{l}\t%0"; 10982 else 10983 return "sal{b}\t%0"; 10984 } 10985 else 10986 { 10987 if (get_attr_mode (insn) == MODE_SI) 10988 return "sal{l}\t{%2, %k0|%k0, %2}"; 10989 else 10990 return "sal{b}\t{%2, %0|%0, %2}"; 10991 } 10992 } 10993} 10994 [(set (attr "type") 10995 (cond [(eq_attr "alternative" "2") 10996 (const_string "lea") 10997 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10998 (const_int 0)) 10999 (match_operand 0 "register_operand" "")) 11000 (match_operand 2 "const1_operand" "")) 11001 (const_string "alu") 11002 ] 11003 (const_string "ishift"))) 11004 (set_attr "mode" "QI,SI,SI")]) 11005 11006(define_insn "*ashlqi3_1" 11007 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") 11008 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 11009 (match_operand:QI 2 "nonmemory_operand" "cI,cI"))) 11010 (clobber (reg:CC FLAGS_REG))] 11011 "TARGET_PARTIAL_REG_STALL 11012 && ix86_binary_operator_ok (ASHIFT, QImode, operands)" 11013{ 11014 switch (get_attr_type (insn)) 11015 { 11016 case TYPE_ALU: 11017 gcc_assert (operands[2] == const1_rtx); 11018 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) 11019 return "add{l}\t{%k0, %k0|%k0, %k0}"; 11020 else 11021 return "add{b}\t{%0, %0|%0, %0}"; 11022 11023 default: 11024 if (REG_P (operands[2])) 11025 { 11026 if (get_attr_mode (insn) == MODE_SI) 11027 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 11028 else 11029 return "sal{b}\t{%b2, %0|%0, %b2}"; 11030 } 11031 else if (operands[2] == const1_rtx 11032 && (TARGET_SHIFT1 || optimize_size)) 11033 { 11034 if (get_attr_mode (insn) == MODE_SI) 11035 return "sal{l}\t%0"; 11036 else 11037 return "sal{b}\t%0"; 11038 } 11039 else 11040 { 11041 if (get_attr_mode (insn) == MODE_SI) 11042 return "sal{l}\t{%2, %k0|%k0, %2}"; 11043 else 11044 return "sal{b}\t{%2, %0|%0, %2}"; 11045 } 11046 } 11047} 11048 [(set (attr "type") 11049 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11050 (const_int 0)) 11051 (match_operand 0 "register_operand" "")) 11052 (match_operand 2 "const1_operand" "")) 11053 (const_string "alu") 11054 ] 11055 (const_string "ishift"))) 11056 (set_attr "mode" "QI,SI")]) 11057 11058;; This pattern can't accept a variable shift count, since shifts by 11059;; zero don't affect the flags. We assume that shifts by constant 11060;; zero are optimized away. 11061(define_insn "*ashlqi3_cmp" 11062 [(set (reg FLAGS_REG) 11063 (compare 11064 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11065 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11066 (const_int 0))) 11067 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11068 (ashift:QI (match_dup 1) (match_dup 2)))] 11069 "ix86_match_ccmode (insn, CCGOCmode) 11070 && ix86_binary_operator_ok (ASHIFT, QImode, operands)" 11071{ 11072 switch (get_attr_type (insn)) 11073 { 11074 case TYPE_ALU: 11075 gcc_assert (operands[2] == const1_rtx); 11076 return "add{b}\t{%0, %0|%0, %0}"; 11077 11078 default: 11079 if (REG_P (operands[2])) 11080 return "sal{b}\t{%b2, %0|%0, %b2}"; 11081 else if (operands[2] == const1_rtx 11082 && (TARGET_SHIFT1 || optimize_size)) 11083 return "sal{b}\t%0"; 11084 else 11085 return "sal{b}\t{%2, %0|%0, %2}"; 11086 } 11087} 11088 [(set (attr "type") 11089 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11090 (const_int 0)) 11091 (match_operand 0 "register_operand" "")) 11092 (match_operand 2 "const1_operand" "")) 11093 (const_string "alu") 11094 ] 11095 (const_string "ishift"))) 11096 (set_attr "mode" "QI")]) 11097 11098(define_insn "*ashlqi3_cconly" 11099 [(set (reg FLAGS_REG) 11100 (compare 11101 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11102 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11103 (const_int 0))) 11104 (clobber (match_scratch:QI 0 "=q"))] 11105 "ix86_match_ccmode (insn, CCGOCmode) 11106 && ix86_binary_operator_ok (ASHIFT, QImode, operands)" 11107{ 11108 switch (get_attr_type (insn)) 11109 { 11110 case TYPE_ALU: 11111 gcc_assert (operands[2] == const1_rtx); 11112 return "add{b}\t{%0, %0|%0, %0}"; 11113 11114 default: 11115 if (REG_P (operands[2])) 11116 return "sal{b}\t{%b2, %0|%0, %b2}"; 11117 else if (operands[2] == const1_rtx 11118 && (TARGET_SHIFT1 || optimize_size)) 11119 return "sal{b}\t%0"; 11120 else 11121 return "sal{b}\t{%2, %0|%0, %2}"; 11122 } 11123} 11124 [(set (attr "type") 11125 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11126 (const_int 0)) 11127 (match_operand 0 "register_operand" "")) 11128 (match_operand 2 "const1_operand" "")) 11129 (const_string "alu") 11130 ] 11131 (const_string "ishift"))) 11132 (set_attr "mode" "QI")]) 11133 11134;; See comment above `ashldi3' about how this works. 11135 11136(define_expand "ashrti3" 11137 [(parallel [(set (match_operand:TI 0 "register_operand" "") 11138 (ashiftrt:TI (match_operand:TI 1 "register_operand" "") 11139 (match_operand:QI 2 "nonmemory_operand" ""))) 11140 (clobber (reg:CC FLAGS_REG))])] 11141 "TARGET_64BIT" 11142{ 11143 if (! immediate_operand (operands[2], QImode)) 11144 { 11145 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2])); 11146 DONE; 11147 } 11148 ix86_expand_binary_operator (ASHIFTRT, TImode, operands); 11149 DONE; 11150}) 11151 11152(define_insn "ashrti3_1" 11153 [(set (match_operand:TI 0 "register_operand" "=r") 11154 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0") 11155 (match_operand:QI 2 "register_operand" "c"))) 11156 (clobber (match_scratch:DI 3 "=&r")) 11157 (clobber (reg:CC FLAGS_REG))] 11158 "TARGET_64BIT" 11159 "#" 11160 [(set_attr "type" "multi")]) 11161 11162(define_insn "*ashrti3_2" 11163 [(set (match_operand:TI 0 "register_operand" "=r") 11164 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0") 11165 (match_operand:QI 2 "immediate_operand" "O"))) 11166 (clobber (reg:CC FLAGS_REG))] 11167 "TARGET_64BIT" 11168 "#" 11169 [(set_attr "type" "multi")]) 11170 11171(define_split 11172 [(set (match_operand:TI 0 "register_operand" "") 11173 (ashiftrt:TI (match_operand:TI 1 "register_operand" "") 11174 (match_operand:QI 2 "register_operand" ""))) 11175 (clobber (match_scratch:DI 3 "")) 11176 (clobber (reg:CC FLAGS_REG))] 11177 "TARGET_64BIT && reload_completed" 11178 [(const_int 0)] 11179 "ix86_split_ashr (operands, operands[3], TImode); DONE;") 11180 11181(define_split 11182 [(set (match_operand:TI 0 "register_operand" "") 11183 (ashiftrt:TI (match_operand:TI 1 "register_operand" "") 11184 (match_operand:QI 2 "immediate_operand" ""))) 11185 (clobber (reg:CC FLAGS_REG))] 11186 "TARGET_64BIT && reload_completed" 11187 [(const_int 0)] 11188 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;") 11189 11190(define_insn "x86_64_shrd" 11191 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m") 11192 (ior:DI (ashiftrt:DI (match_dup 0) 11193 (match_operand:QI 2 "nonmemory_operand" "J,c")) 11194 (ashift:DI (match_operand:DI 1 "register_operand" "r,r") 11195 (minus:QI (const_int 64) (match_dup 2))))) 11196 (clobber (reg:CC FLAGS_REG))] 11197 "TARGET_64BIT" 11198 "@ 11199 shrd{q}\t{%2, %1, %0|%0, %1, %2} 11200 shrd{q}\t{%s2%1, %0|%0, %1, %2}" 11201 [(set_attr "type" "ishift") 11202 (set_attr "prefix_0f" "1") 11203 (set_attr "mode" "DI") 11204 (set_attr "athlon_decode" "vector")]) 11205 11206(define_expand "ashrdi3" 11207 [(set (match_operand:DI 0 "shiftdi_operand" "") 11208 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") 11209 (match_operand:QI 2 "nonmemory_operand" "")))] 11210 "" 11211 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;") 11212 11213(define_insn "*ashrdi3_63_rex64" 11214 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm") 11215 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0") 11216 (match_operand:DI 2 "const_int_operand" "i,i"))) 11217 (clobber (reg:CC FLAGS_REG))] 11218 "TARGET_64BIT && INTVAL (operands[2]) == 63 11219 && (TARGET_USE_CLTD || optimize_size) 11220 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11221 "@ 11222 {cqto|cqo} 11223 sar{q}\t{%2, %0|%0, %2}" 11224 [(set_attr "type" "imovx,ishift") 11225 (set_attr "prefix_0f" "0,*") 11226 (set_attr "length_immediate" "0,*") 11227 (set_attr "modrm" "0,1") 11228 (set_attr "mode" "DI")]) 11229 11230(define_insn "*ashrdi3_1_one_bit_rex64" 11231 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11232 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11233 (match_operand:QI 2 "const1_operand" ""))) 11234 (clobber (reg:CC FLAGS_REG))] 11235 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands) 11236 && (TARGET_SHIFT1 || optimize_size)" 11237 "sar{q}\t%0" 11238 [(set_attr "type" "ishift") 11239 (set (attr "length") 11240 (if_then_else (match_operand:DI 0 "register_operand" "") 11241 (const_string "2") 11242 (const_string "*")))]) 11243 11244(define_insn "*ashrdi3_1_rex64" 11245 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 11246 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 11247 (match_operand:QI 2 "nonmemory_operand" "J,c"))) 11248 (clobber (reg:CC FLAGS_REG))] 11249 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11250 "@ 11251 sar{q}\t{%2, %0|%0, %2} 11252 sar{q}\t{%b2, %0|%0, %b2}" 11253 [(set_attr "type" "ishift") 11254 (set_attr "mode" "DI")]) 11255 11256;; This pattern can't accept a variable shift count, since shifts by 11257;; zero don't affect the flags. We assume that shifts by constant 11258;; zero are optimized away. 11259(define_insn "*ashrdi3_one_bit_cmp_rex64" 11260 [(set (reg FLAGS_REG) 11261 (compare 11262 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11263 (match_operand:QI 2 "const1_operand" "")) 11264 (const_int 0))) 11265 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11266 (ashiftrt:DI (match_dup 1) (match_dup 2)))] 11267 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11268 && (TARGET_SHIFT1 || optimize_size) 11269 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11270 "sar{q}\t%0" 11271 [(set_attr "type" "ishift") 11272 (set (attr "length") 11273 (if_then_else (match_operand:DI 0 "register_operand" "") 11274 (const_string "2") 11275 (const_string "*")))]) 11276 11277(define_insn "*ashrdi3_one_bit_cconly_rex64" 11278 [(set (reg FLAGS_REG) 11279 (compare 11280 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11281 (match_operand:QI 2 "const1_operand" "")) 11282 (const_int 0))) 11283 (clobber (match_scratch:DI 0 "=r"))] 11284 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11285 && (TARGET_SHIFT1 || optimize_size) 11286 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11287 "sar{q}\t%0" 11288 [(set_attr "type" "ishift") 11289 (set_attr "length" "2")]) 11290 11291;; This pattern can't accept a variable shift count, since shifts by 11292;; zero don't affect the flags. We assume that shifts by constant 11293;; zero are optimized away. 11294(define_insn "*ashrdi3_cmp_rex64" 11295 [(set (reg FLAGS_REG) 11296 (compare 11297 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11298 (match_operand:QI 2 "const_int_operand" "n")) 11299 (const_int 0))) 11300 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11301 (ashiftrt:DI (match_dup 1) (match_dup 2)))] 11302 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11303 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11304 "sar{q}\t{%2, %0|%0, %2}" 11305 [(set_attr "type" "ishift") 11306 (set_attr "mode" "DI")]) 11307 11308(define_insn "*ashrdi3_cconly_rex64" 11309 [(set (reg FLAGS_REG) 11310 (compare 11311 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11312 (match_operand:QI 2 "const_int_operand" "n")) 11313 (const_int 0))) 11314 (clobber (match_scratch:DI 0 "=r"))] 11315 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11316 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11317 "sar{q}\t{%2, %0|%0, %2}" 11318 [(set_attr "type" "ishift") 11319 (set_attr "mode" "DI")]) 11320 11321(define_insn "*ashrdi3_1" 11322 [(set (match_operand:DI 0 "register_operand" "=r") 11323 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") 11324 (match_operand:QI 2 "nonmemory_operand" "Jc"))) 11325 (clobber (reg:CC FLAGS_REG))] 11326 "!TARGET_64BIT" 11327 "#" 11328 [(set_attr "type" "multi")]) 11329 11330;; By default we don't ask for a scratch register, because when DImode 11331;; values are manipulated, registers are already at a premium. But if 11332;; we have one handy, we won't turn it away. 11333(define_peephole2 11334 [(match_scratch:SI 3 "r") 11335 (parallel [(set (match_operand:DI 0 "register_operand" "") 11336 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 11337 (match_operand:QI 2 "nonmemory_operand" ""))) 11338 (clobber (reg:CC FLAGS_REG))]) 11339 (match_dup 3)] 11340 "!TARGET_64BIT && TARGET_CMOVE" 11341 [(const_int 0)] 11342 "ix86_split_ashr (operands, operands[3], DImode); DONE;") 11343 11344(define_split 11345 [(set (match_operand:DI 0 "register_operand" "") 11346 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 11347 (match_operand:QI 2 "nonmemory_operand" ""))) 11348 (clobber (reg:CC FLAGS_REG))] 11349 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) 11350 ? flow2_completed : reload_completed)" 11351 [(const_int 0)] 11352 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;") 11353 11354(define_insn "x86_shrd_1" 11355 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m") 11356 (ior:SI (ashiftrt:SI (match_dup 0) 11357 (match_operand:QI 2 "nonmemory_operand" "I,c")) 11358 (ashift:SI (match_operand:SI 1 "register_operand" "r,r") 11359 (minus:QI (const_int 32) (match_dup 2))))) 11360 (clobber (reg:CC FLAGS_REG))] 11361 "" 11362 "@ 11363 shrd{l}\t{%2, %1, %0|%0, %1, %2} 11364 shrd{l}\t{%s2%1, %0|%0, %1, %2}" 11365 [(set_attr "type" "ishift") 11366 (set_attr "prefix_0f" "1") 11367 (set_attr "pent_pair" "np") 11368 (set_attr "mode" "SI")]) 11369 11370(define_expand "x86_shift_adj_3" 11371 [(use (match_operand:SI 0 "register_operand" "")) 11372 (use (match_operand:SI 1 "register_operand" "")) 11373 (use (match_operand:QI 2 "register_operand" ""))] 11374 "" 11375{ 11376 rtx label = gen_label_rtx (); 11377 rtx tmp; 11378 11379 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32))); 11380 11381 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 11382 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 11383 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 11384 gen_rtx_LABEL_REF (VOIDmode, label), 11385 pc_rtx); 11386 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 11387 JUMP_LABEL (tmp) = label; 11388 11389 emit_move_insn (operands[0], operands[1]); 11390 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31))); 11391 11392 emit_label (label); 11393 LABEL_NUSES (label) = 1; 11394 11395 DONE; 11396}) 11397 11398(define_insn "ashrsi3_31" 11399 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm") 11400 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0") 11401 (match_operand:SI 2 "const_int_operand" "i,i"))) 11402 (clobber (reg:CC FLAGS_REG))] 11403 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size) 11404 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11405 "@ 11406 {cltd|cdq} 11407 sar{l}\t{%2, %0|%0, %2}" 11408 [(set_attr "type" "imovx,ishift") 11409 (set_attr "prefix_0f" "0,*") 11410 (set_attr "length_immediate" "0,*") 11411 (set_attr "modrm" "0,1") 11412 (set_attr "mode" "SI")]) 11413 11414(define_insn "*ashrsi3_31_zext" 11415 [(set (match_operand:DI 0 "register_operand" "=*d,r") 11416 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0") 11417 (match_operand:SI 2 "const_int_operand" "i,i")))) 11418 (clobber (reg:CC FLAGS_REG))] 11419 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size) 11420 && INTVAL (operands[2]) == 31 11421 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11422 "@ 11423 {cltd|cdq} 11424 sar{l}\t{%2, %k0|%k0, %2}" 11425 [(set_attr "type" "imovx,ishift") 11426 (set_attr "prefix_0f" "0,*") 11427 (set_attr "length_immediate" "0,*") 11428 (set_attr "modrm" "0,1") 11429 (set_attr "mode" "SI")]) 11430 11431(define_expand "ashrsi3" 11432 [(set (match_operand:SI 0 "nonimmediate_operand" "") 11433 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") 11434 (match_operand:QI 2 "nonmemory_operand" ""))) 11435 (clobber (reg:CC FLAGS_REG))] 11436 "" 11437 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;") 11438 11439(define_insn "*ashrsi3_1_one_bit" 11440 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 11441 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11442 (match_operand:QI 2 "const1_operand" ""))) 11443 (clobber (reg:CC FLAGS_REG))] 11444 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11445 && (TARGET_SHIFT1 || optimize_size)" 11446 "sar{l}\t%0" 11447 [(set_attr "type" "ishift") 11448 (set (attr "length") 11449 (if_then_else (match_operand:SI 0 "register_operand" "") 11450 (const_string "2") 11451 (const_string "*")))]) 11452 11453(define_insn "*ashrsi3_1_one_bit_zext" 11454 [(set (match_operand:DI 0 "register_operand" "=r") 11455 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 11456 (match_operand:QI 2 "const1_operand" "")))) 11457 (clobber (reg:CC FLAGS_REG))] 11458 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11459 && (TARGET_SHIFT1 || optimize_size)" 11460 "sar{l}\t%k0" 11461 [(set_attr "type" "ishift") 11462 (set_attr "length" "2")]) 11463 11464(define_insn "*ashrsi3_1" 11465 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 11466 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 11467 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 11468 (clobber (reg:CC FLAGS_REG))] 11469 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11470 "@ 11471 sar{l}\t{%2, %0|%0, %2} 11472 sar{l}\t{%b2, %0|%0, %b2}" 11473 [(set_attr "type" "ishift") 11474 (set_attr "mode" "SI")]) 11475 11476(define_insn "*ashrsi3_1_zext" 11477 [(set (match_operand:DI 0 "register_operand" "=r,r") 11478 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0") 11479 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 11480 (clobber (reg:CC FLAGS_REG))] 11481 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11482 "@ 11483 sar{l}\t{%2, %k0|%k0, %2} 11484 sar{l}\t{%b2, %k0|%k0, %b2}" 11485 [(set_attr "type" "ishift") 11486 (set_attr "mode" "SI")]) 11487 11488;; This pattern can't accept a variable shift count, since shifts by 11489;; zero don't affect the flags. We assume that shifts by constant 11490;; zero are optimized away. 11491(define_insn "*ashrsi3_one_bit_cmp" 11492 [(set (reg FLAGS_REG) 11493 (compare 11494 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11495 (match_operand:QI 2 "const1_operand" "")) 11496 (const_int 0))) 11497 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 11498 (ashiftrt:SI (match_dup 1) (match_dup 2)))] 11499 "ix86_match_ccmode (insn, CCGOCmode) 11500 && (TARGET_SHIFT1 || optimize_size) 11501 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11502 "sar{l}\t%0" 11503 [(set_attr "type" "ishift") 11504 (set (attr "length") 11505 (if_then_else (match_operand:SI 0 "register_operand" "") 11506 (const_string "2") 11507 (const_string "*")))]) 11508 11509(define_insn "*ashrsi3_one_bit_cconly" 11510 [(set (reg FLAGS_REG) 11511 (compare 11512 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11513 (match_operand:QI 2 "const1_operand" "")) 11514 (const_int 0))) 11515 (clobber (match_scratch:SI 0 "=r"))] 11516 "ix86_match_ccmode (insn, CCGOCmode) 11517 && (TARGET_SHIFT1 || optimize_size) 11518 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11519 "sar{l}\t%0" 11520 [(set_attr "type" "ishift") 11521 (set_attr "length" "2")]) 11522 11523(define_insn "*ashrsi3_one_bit_cmp_zext" 11524 [(set (reg FLAGS_REG) 11525 (compare 11526 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 11527 (match_operand:QI 2 "const1_operand" "")) 11528 (const_int 0))) 11529 (set (match_operand:DI 0 "register_operand" "=r") 11530 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))] 11531 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 11532 && (TARGET_SHIFT1 || optimize_size) 11533 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11534 "sar{l}\t%k0" 11535 [(set_attr "type" "ishift") 11536 (set_attr "length" "2")]) 11537 11538;; This pattern can't accept a variable shift count, since shifts by 11539;; zero don't affect the flags. We assume that shifts by constant 11540;; zero are optimized away. 11541(define_insn "*ashrsi3_cmp" 11542 [(set (reg FLAGS_REG) 11543 (compare 11544 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11545 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11546 (const_int 0))) 11547 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 11548 (ashiftrt:SI (match_dup 1) (match_dup 2)))] 11549 "ix86_match_ccmode (insn, CCGOCmode) 11550 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11551 "sar{l}\t{%2, %0|%0, %2}" 11552 [(set_attr "type" "ishift") 11553 (set_attr "mode" "SI")]) 11554 11555(define_insn "*ashrsi3_cconly" 11556 [(set (reg FLAGS_REG) 11557 (compare 11558 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11559 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11560 (const_int 0))) 11561 (clobber (match_scratch:SI 0 "=r"))] 11562 "ix86_match_ccmode (insn, CCGOCmode) 11563 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11564 "sar{l}\t{%2, %0|%0, %2}" 11565 [(set_attr "type" "ishift") 11566 (set_attr "mode" "SI")]) 11567 11568(define_insn "*ashrsi3_cmp_zext" 11569 [(set (reg FLAGS_REG) 11570 (compare 11571 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 11572 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11573 (const_int 0))) 11574 (set (match_operand:DI 0 "register_operand" "=r") 11575 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))] 11576 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11577 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11578 "sar{l}\t{%2, %k0|%k0, %2}" 11579 [(set_attr "type" "ishift") 11580 (set_attr "mode" "SI")]) 11581 11582(define_expand "ashrhi3" 11583 [(set (match_operand:HI 0 "nonimmediate_operand" "") 11584 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") 11585 (match_operand:QI 2 "nonmemory_operand" ""))) 11586 (clobber (reg:CC FLAGS_REG))] 11587 "TARGET_HIMODE_MATH" 11588 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;") 11589 11590(define_insn "*ashrhi3_1_one_bit" 11591 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 11592 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11593 (match_operand:QI 2 "const1_operand" ""))) 11594 (clobber (reg:CC FLAGS_REG))] 11595 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands) 11596 && (TARGET_SHIFT1 || optimize_size)" 11597 "sar{w}\t%0" 11598 [(set_attr "type" "ishift") 11599 (set (attr "length") 11600 (if_then_else (match_operand 0 "register_operand" "") 11601 (const_string "2") 11602 (const_string "*")))]) 11603 11604(define_insn "*ashrhi3_1" 11605 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 11606 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 11607 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 11608 (clobber (reg:CC FLAGS_REG))] 11609 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" 11610 "@ 11611 sar{w}\t{%2, %0|%0, %2} 11612 sar{w}\t{%b2, %0|%0, %b2}" 11613 [(set_attr "type" "ishift") 11614 (set_attr "mode" "HI")]) 11615 11616;; This pattern can't accept a variable shift count, since shifts by 11617;; zero don't affect the flags. We assume that shifts by constant 11618;; zero are optimized away. 11619(define_insn "*ashrhi3_one_bit_cmp" 11620 [(set (reg FLAGS_REG) 11621 (compare 11622 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11623 (match_operand:QI 2 "const1_operand" "")) 11624 (const_int 0))) 11625 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 11626 (ashiftrt:HI (match_dup 1) (match_dup 2)))] 11627 "ix86_match_ccmode (insn, CCGOCmode) 11628 && (TARGET_SHIFT1 || optimize_size) 11629 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" 11630 "sar{w}\t%0" 11631 [(set_attr "type" "ishift") 11632 (set (attr "length") 11633 (if_then_else (match_operand 0 "register_operand" "") 11634 (const_string "2") 11635 (const_string "*")))]) 11636 11637(define_insn "*ashrhi3_one_bit_cconly" 11638 [(set (reg FLAGS_REG) 11639 (compare 11640 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11641 (match_operand:QI 2 "const1_operand" "")) 11642 (const_int 0))) 11643 (clobber (match_scratch:HI 0 "=r"))] 11644 "ix86_match_ccmode (insn, CCGOCmode) 11645 && (TARGET_SHIFT1 || optimize_size) 11646 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" 11647 "sar{w}\t%0" 11648 [(set_attr "type" "ishift") 11649 (set_attr "length" "2")]) 11650 11651;; This pattern can't accept a variable shift count, since shifts by 11652;; zero don't affect the flags. We assume that shifts by constant 11653;; zero are optimized away. 11654(define_insn "*ashrhi3_cmp" 11655 [(set (reg FLAGS_REG) 11656 (compare 11657 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11658 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11659 (const_int 0))) 11660 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 11661 (ashiftrt:HI (match_dup 1) (match_dup 2)))] 11662 "ix86_match_ccmode (insn, CCGOCmode) 11663 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" 11664 "sar{w}\t{%2, %0|%0, %2}" 11665 [(set_attr "type" "ishift") 11666 (set_attr "mode" "HI")]) 11667 11668(define_insn "*ashrhi3_cconly" 11669 [(set (reg FLAGS_REG) 11670 (compare 11671 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11672 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11673 (const_int 0))) 11674 (clobber (match_scratch:HI 0 "=r"))] 11675 "ix86_match_ccmode (insn, CCGOCmode) 11676 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" 11677 "sar{w}\t{%2, %0|%0, %2}" 11678 [(set_attr "type" "ishift") 11679 (set_attr "mode" "HI")]) 11680 11681(define_expand "ashrqi3" 11682 [(set (match_operand:QI 0 "nonimmediate_operand" "") 11683 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "") 11684 (match_operand:QI 2 "nonmemory_operand" ""))) 11685 (clobber (reg:CC FLAGS_REG))] 11686 "TARGET_QIMODE_MATH" 11687 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;") 11688 11689(define_insn "*ashrqi3_1_one_bit" 11690 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11691 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11692 (match_operand:QI 2 "const1_operand" ""))) 11693 (clobber (reg:CC FLAGS_REG))] 11694 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 11695 && (TARGET_SHIFT1 || optimize_size)" 11696 "sar{b}\t%0" 11697 [(set_attr "type" "ishift") 11698 (set (attr "length") 11699 (if_then_else (match_operand 0 "register_operand" "") 11700 (const_string "2") 11701 (const_string "*")))]) 11702 11703(define_insn "*ashrqi3_1_one_bit_slp" 11704 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 11705 (ashiftrt:QI (match_dup 0) 11706 (match_operand:QI 1 "const1_operand" ""))) 11707 (clobber (reg:CC FLAGS_REG))] 11708 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 11709 && (! TARGET_PARTIAL_REG_STALL || optimize_size) 11710 && (TARGET_SHIFT1 || optimize_size)" 11711 "sar{b}\t%0" 11712 [(set_attr "type" "ishift1") 11713 (set (attr "length") 11714 (if_then_else (match_operand 0 "register_operand" "") 11715 (const_string "2") 11716 (const_string "*")))]) 11717 11718(define_insn "*ashrqi3_1" 11719 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 11720 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 11721 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 11722 (clobber (reg:CC FLAGS_REG))] 11723 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" 11724 "@ 11725 sar{b}\t{%2, %0|%0, %2} 11726 sar{b}\t{%b2, %0|%0, %b2}" 11727 [(set_attr "type" "ishift") 11728 (set_attr "mode" "QI")]) 11729 11730(define_insn "*ashrqi3_1_slp" 11731 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 11732 (ashiftrt:QI (match_dup 0) 11733 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 11734 (clobber (reg:CC FLAGS_REG))] 11735 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 11736 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 11737 "@ 11738 sar{b}\t{%1, %0|%0, %1} 11739 sar{b}\t{%b1, %0|%0, %b1}" 11740 [(set_attr "type" "ishift1") 11741 (set_attr "mode" "QI")]) 11742 11743;; This pattern can't accept a variable shift count, since shifts by 11744;; zero don't affect the flags. We assume that shifts by constant 11745;; zero are optimized away. 11746(define_insn "*ashrqi3_one_bit_cmp" 11747 [(set (reg FLAGS_REG) 11748 (compare 11749 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11750 (match_operand:QI 2 "const1_operand" "I")) 11751 (const_int 0))) 11752 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11753 (ashiftrt:QI (match_dup 1) (match_dup 2)))] 11754 "ix86_match_ccmode (insn, CCGOCmode) 11755 && (TARGET_SHIFT1 || optimize_size) 11756 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" 11757 "sar{b}\t%0" 11758 [(set_attr "type" "ishift") 11759 (set (attr "length") 11760 (if_then_else (match_operand 0 "register_operand" "") 11761 (const_string "2") 11762 (const_string "*")))]) 11763 11764(define_insn "*ashrqi3_one_bit_cconly" 11765 [(set (reg FLAGS_REG) 11766 (compare 11767 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11768 (match_operand:QI 2 "const1_operand" "I")) 11769 (const_int 0))) 11770 (clobber (match_scratch:QI 0 "=q"))] 11771 "ix86_match_ccmode (insn, CCGOCmode) 11772 && (TARGET_SHIFT1 || optimize_size) 11773 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" 11774 "sar{b}\t%0" 11775 [(set_attr "type" "ishift") 11776 (set_attr "length" "2")]) 11777 11778;; This pattern can't accept a variable shift count, since shifts by 11779;; zero don't affect the flags. We assume that shifts by constant 11780;; zero are optimized away. 11781(define_insn "*ashrqi3_cmp" 11782 [(set (reg FLAGS_REG) 11783 (compare 11784 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11785 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11786 (const_int 0))) 11787 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11788 (ashiftrt:QI (match_dup 1) (match_dup 2)))] 11789 "ix86_match_ccmode (insn, CCGOCmode) 11790 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" 11791 "sar{b}\t{%2, %0|%0, %2}" 11792 [(set_attr "type" "ishift") 11793 (set_attr "mode" "QI")]) 11794 11795(define_insn "*ashrqi3_cconly" 11796 [(set (reg FLAGS_REG) 11797 (compare 11798 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11799 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11800 (const_int 0))) 11801 (clobber (match_scratch:QI 0 "=q"))] 11802 "ix86_match_ccmode (insn, CCGOCmode) 11803 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" 11804 "sar{b}\t{%2, %0|%0, %2}" 11805 [(set_attr "type" "ishift") 11806 (set_attr "mode" "QI")]) 11807 11808 11809;; Logical shift instructions 11810 11811;; See comment above `ashldi3' about how this works. 11812 11813(define_expand "lshrti3" 11814 [(parallel [(set (match_operand:TI 0 "register_operand" "") 11815 (lshiftrt:TI (match_operand:TI 1 "register_operand" "") 11816 (match_operand:QI 2 "nonmemory_operand" ""))) 11817 (clobber (reg:CC FLAGS_REG))])] 11818 "TARGET_64BIT" 11819{ 11820 if (! immediate_operand (operands[2], QImode)) 11821 { 11822 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2])); 11823 DONE; 11824 } 11825 ix86_expand_binary_operator (LSHIFTRT, TImode, operands); 11826 DONE; 11827}) 11828 11829(define_insn "lshrti3_1" 11830 [(set (match_operand:TI 0 "register_operand" "=r") 11831 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0") 11832 (match_operand:QI 2 "register_operand" "c"))) 11833 (clobber (match_scratch:DI 3 "=&r")) 11834 (clobber (reg:CC FLAGS_REG))] 11835 "TARGET_64BIT" 11836 "#" 11837 [(set_attr "type" "multi")]) 11838 11839(define_insn "*lshrti3_2" 11840 [(set (match_operand:TI 0 "register_operand" "=r") 11841 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0") 11842 (match_operand:QI 2 "immediate_operand" "O"))) 11843 (clobber (reg:CC FLAGS_REG))] 11844 "TARGET_64BIT" 11845 "#" 11846 [(set_attr "type" "multi")]) 11847 11848(define_split 11849 [(set (match_operand:TI 0 "register_operand" "") 11850 (lshiftrt:TI (match_operand:TI 1 "register_operand" "") 11851 (match_operand:QI 2 "register_operand" ""))) 11852 (clobber (match_scratch:DI 3 "")) 11853 (clobber (reg:CC FLAGS_REG))] 11854 "TARGET_64BIT && reload_completed" 11855 [(const_int 0)] 11856 "ix86_split_lshr (operands, operands[3], TImode); DONE;") 11857 11858(define_split 11859 [(set (match_operand:TI 0 "register_operand" "") 11860 (lshiftrt:TI (match_operand:TI 1 "register_operand" "") 11861 (match_operand:QI 2 "immediate_operand" ""))) 11862 (clobber (reg:CC FLAGS_REG))] 11863 "TARGET_64BIT && reload_completed" 11864 [(const_int 0)] 11865 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;") 11866 11867(define_expand "lshrdi3" 11868 [(set (match_operand:DI 0 "shiftdi_operand" "") 11869 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") 11870 (match_operand:QI 2 "nonmemory_operand" "")))] 11871 "" 11872 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;") 11873 11874(define_insn "*lshrdi3_1_one_bit_rex64" 11875 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11876 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11877 (match_operand:QI 2 "const1_operand" ""))) 11878 (clobber (reg:CC FLAGS_REG))] 11879 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 11880 && (TARGET_SHIFT1 || optimize_size)" 11881 "shr{q}\t%0" 11882 [(set_attr "type" "ishift") 11883 (set (attr "length") 11884 (if_then_else (match_operand:DI 0 "register_operand" "") 11885 (const_string "2") 11886 (const_string "*")))]) 11887 11888(define_insn "*lshrdi3_1_rex64" 11889 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 11890 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 11891 (match_operand:QI 2 "nonmemory_operand" "J,c"))) 11892 (clobber (reg:CC FLAGS_REG))] 11893 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 11894 "@ 11895 shr{q}\t{%2, %0|%0, %2} 11896 shr{q}\t{%b2, %0|%0, %b2}" 11897 [(set_attr "type" "ishift") 11898 (set_attr "mode" "DI")]) 11899 11900;; This pattern can't accept a variable shift count, since shifts by 11901;; zero don't affect the flags. We assume that shifts by constant 11902;; zero are optimized away. 11903(define_insn "*lshrdi3_cmp_one_bit_rex64" 11904 [(set (reg FLAGS_REG) 11905 (compare 11906 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11907 (match_operand:QI 2 "const1_operand" "")) 11908 (const_int 0))) 11909 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11910 (lshiftrt:DI (match_dup 1) (match_dup 2)))] 11911 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11912 && (TARGET_SHIFT1 || optimize_size) 11913 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 11914 "shr{q}\t%0" 11915 [(set_attr "type" "ishift") 11916 (set (attr "length") 11917 (if_then_else (match_operand:DI 0 "register_operand" "") 11918 (const_string "2") 11919 (const_string "*")))]) 11920 11921(define_insn "*lshrdi3_cconly_one_bit_rex64" 11922 [(set (reg FLAGS_REG) 11923 (compare 11924 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11925 (match_operand:QI 2 "const1_operand" "")) 11926 (const_int 0))) 11927 (clobber (match_scratch:DI 0 "=r"))] 11928 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11929 && (TARGET_SHIFT1 || optimize_size) 11930 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 11931 "shr{q}\t%0" 11932 [(set_attr "type" "ishift") 11933 (set_attr "length" "2")]) 11934 11935;; This pattern can't accept a variable shift count, since shifts by 11936;; zero don't affect the flags. We assume that shifts by constant 11937;; zero are optimized away. 11938(define_insn "*lshrdi3_cmp_rex64" 11939 [(set (reg FLAGS_REG) 11940 (compare 11941 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11942 (match_operand:QI 2 "const_int_operand" "e")) 11943 (const_int 0))) 11944 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11945 (lshiftrt:DI (match_dup 1) (match_dup 2)))] 11946 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11947 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 11948 "shr{q}\t{%2, %0|%0, %2}" 11949 [(set_attr "type" "ishift") 11950 (set_attr "mode" "DI")]) 11951 11952(define_insn "*lshrdi3_cconly_rex64" 11953 [(set (reg FLAGS_REG) 11954 (compare 11955 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11956 (match_operand:QI 2 "const_int_operand" "e")) 11957 (const_int 0))) 11958 (clobber (match_scratch:DI 0 "=r"))] 11959 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11960 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 11961 "shr{q}\t{%2, %0|%0, %2}" 11962 [(set_attr "type" "ishift") 11963 (set_attr "mode" "DI")]) 11964 11965(define_insn "*lshrdi3_1" 11966 [(set (match_operand:DI 0 "register_operand" "=r") 11967 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") 11968 (match_operand:QI 2 "nonmemory_operand" "Jc"))) 11969 (clobber (reg:CC FLAGS_REG))] 11970 "!TARGET_64BIT" 11971 "#" 11972 [(set_attr "type" "multi")]) 11973 11974;; By default we don't ask for a scratch register, because when DImode 11975;; values are manipulated, registers are already at a premium. But if 11976;; we have one handy, we won't turn it away. 11977(define_peephole2 11978 [(match_scratch:SI 3 "r") 11979 (parallel [(set (match_operand:DI 0 "register_operand" "") 11980 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 11981 (match_operand:QI 2 "nonmemory_operand" ""))) 11982 (clobber (reg:CC FLAGS_REG))]) 11983 (match_dup 3)] 11984 "!TARGET_64BIT && TARGET_CMOVE" 11985 [(const_int 0)] 11986 "ix86_split_lshr (operands, operands[3], DImode); DONE;") 11987 11988(define_split 11989 [(set (match_operand:DI 0 "register_operand" "") 11990 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 11991 (match_operand:QI 2 "nonmemory_operand" ""))) 11992 (clobber (reg:CC FLAGS_REG))] 11993 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) 11994 ? flow2_completed : reload_completed)" 11995 [(const_int 0)] 11996 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;") 11997 11998(define_expand "lshrsi3" 11999 [(set (match_operand:SI 0 "nonimmediate_operand" "") 12000 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") 12001 (match_operand:QI 2 "nonmemory_operand" ""))) 12002 (clobber (reg:CC FLAGS_REG))] 12003 "" 12004 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;") 12005 12006(define_insn "*lshrsi3_1_one_bit" 12007 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12008 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12009 (match_operand:QI 2 "const1_operand" ""))) 12010 (clobber (reg:CC FLAGS_REG))] 12011 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12012 && (TARGET_SHIFT1 || optimize_size)" 12013 "shr{l}\t%0" 12014 [(set_attr "type" "ishift") 12015 (set (attr "length") 12016 (if_then_else (match_operand:SI 0 "register_operand" "") 12017 (const_string "2") 12018 (const_string "*")))]) 12019 12020(define_insn "*lshrsi3_1_one_bit_zext" 12021 [(set (match_operand:DI 0 "register_operand" "=r") 12022 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0")) 12023 (match_operand:QI 2 "const1_operand" ""))) 12024 (clobber (reg:CC FLAGS_REG))] 12025 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12026 && (TARGET_SHIFT1 || optimize_size)" 12027 "shr{l}\t%k0" 12028 [(set_attr "type" "ishift") 12029 (set_attr "length" "2")]) 12030 12031(define_insn "*lshrsi3_1" 12032 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 12033 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12034 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12035 (clobber (reg:CC FLAGS_REG))] 12036 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12037 "@ 12038 shr{l}\t{%2, %0|%0, %2} 12039 shr{l}\t{%b2, %0|%0, %b2}" 12040 [(set_attr "type" "ishift") 12041 (set_attr "mode" "SI")]) 12042 12043(define_insn "*lshrsi3_1_zext" 12044 [(set (match_operand:DI 0 "register_operand" "=r,r") 12045 (zero_extend:DI 12046 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12047 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 12048 (clobber (reg:CC FLAGS_REG))] 12049 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12050 "@ 12051 shr{l}\t{%2, %k0|%k0, %2} 12052 shr{l}\t{%b2, %k0|%k0, %b2}" 12053 [(set_attr "type" "ishift") 12054 (set_attr "mode" "SI")]) 12055 12056;; This pattern can't accept a variable shift count, since shifts by 12057;; zero don't affect the flags. We assume that shifts by constant 12058;; zero are optimized away. 12059(define_insn "*lshrsi3_one_bit_cmp" 12060 [(set (reg FLAGS_REG) 12061 (compare 12062 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12063 (match_operand:QI 2 "const1_operand" "")) 12064 (const_int 0))) 12065 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12066 (lshiftrt:SI (match_dup 1) (match_dup 2)))] 12067 "ix86_match_ccmode (insn, CCGOCmode) 12068 && (TARGET_SHIFT1 || optimize_size) 12069 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12070 "shr{l}\t%0" 12071 [(set_attr "type" "ishift") 12072 (set (attr "length") 12073 (if_then_else (match_operand:SI 0 "register_operand" "") 12074 (const_string "2") 12075 (const_string "*")))]) 12076 12077(define_insn "*lshrsi3_one_bit_cconly" 12078 [(set (reg FLAGS_REG) 12079 (compare 12080 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12081 (match_operand:QI 2 "const1_operand" "")) 12082 (const_int 0))) 12083 (clobber (match_scratch:SI 0 "=r"))] 12084 "ix86_match_ccmode (insn, CCGOCmode) 12085 && (TARGET_SHIFT1 || optimize_size) 12086 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12087 "shr{l}\t%0" 12088 [(set_attr "type" "ishift") 12089 (set_attr "length" "2")]) 12090 12091(define_insn "*lshrsi3_cmp_one_bit_zext" 12092 [(set (reg FLAGS_REG) 12093 (compare 12094 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 12095 (match_operand:QI 2 "const1_operand" "")) 12096 (const_int 0))) 12097 (set (match_operand:DI 0 "register_operand" "=r") 12098 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 12099 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12100 && (TARGET_SHIFT1 || optimize_size) 12101 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12102 "shr{l}\t%k0" 12103 [(set_attr "type" "ishift") 12104 (set_attr "length" "2")]) 12105 12106;; This pattern can't accept a variable shift count, since shifts by 12107;; zero don't affect the flags. We assume that shifts by constant 12108;; zero are optimized away. 12109(define_insn "*lshrsi3_cmp" 12110 [(set (reg FLAGS_REG) 12111 (compare 12112 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12113 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12114 (const_int 0))) 12115 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12116 (lshiftrt:SI (match_dup 1) (match_dup 2)))] 12117 "ix86_match_ccmode (insn, CCGOCmode) 12118 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12119 "shr{l}\t{%2, %0|%0, %2}" 12120 [(set_attr "type" "ishift") 12121 (set_attr "mode" "SI")]) 12122 12123(define_insn "*lshrsi3_cconly" 12124 [(set (reg FLAGS_REG) 12125 (compare 12126 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12127 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12128 (const_int 0))) 12129 (clobber (match_scratch:SI 0 "=r"))] 12130 "ix86_match_ccmode (insn, CCGOCmode) 12131 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12132 "shr{l}\t{%2, %0|%0, %2}" 12133 [(set_attr "type" "ishift") 12134 (set_attr "mode" "SI")]) 12135 12136(define_insn "*lshrsi3_cmp_zext" 12137 [(set (reg FLAGS_REG) 12138 (compare 12139 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 12140 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12141 (const_int 0))) 12142 (set (match_operand:DI 0 "register_operand" "=r") 12143 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 12144 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12145 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12146 "shr{l}\t{%2, %k0|%k0, %2}" 12147 [(set_attr "type" "ishift") 12148 (set_attr "mode" "SI")]) 12149 12150(define_expand "lshrhi3" 12151 [(set (match_operand:HI 0 "nonimmediate_operand" "") 12152 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") 12153 (match_operand:QI 2 "nonmemory_operand" ""))) 12154 (clobber (reg:CC FLAGS_REG))] 12155 "TARGET_HIMODE_MATH" 12156 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;") 12157 12158(define_insn "*lshrhi3_1_one_bit" 12159 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12160 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12161 (match_operand:QI 2 "const1_operand" ""))) 12162 (clobber (reg:CC FLAGS_REG))] 12163 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12164 && (TARGET_SHIFT1 || optimize_size)" 12165 "shr{w}\t%0" 12166 [(set_attr "type" "ishift") 12167 (set (attr "length") 12168 (if_then_else (match_operand 0 "register_operand" "") 12169 (const_string "2") 12170 (const_string "*")))]) 12171 12172(define_insn "*lshrhi3_1" 12173 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 12174 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 12175 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12176 (clobber (reg:CC FLAGS_REG))] 12177 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12178 "@ 12179 shr{w}\t{%2, %0|%0, %2} 12180 shr{w}\t{%b2, %0|%0, %b2}" 12181 [(set_attr "type" "ishift") 12182 (set_attr "mode" "HI")]) 12183 12184;; This pattern can't accept a variable shift count, since shifts by 12185;; zero don't affect the flags. We assume that shifts by constant 12186;; zero are optimized away. 12187(define_insn "*lshrhi3_one_bit_cmp" 12188 [(set (reg FLAGS_REG) 12189 (compare 12190 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12191 (match_operand:QI 2 "const1_operand" "")) 12192 (const_int 0))) 12193 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12194 (lshiftrt:HI (match_dup 1) (match_dup 2)))] 12195 "ix86_match_ccmode (insn, CCGOCmode) 12196 && (TARGET_SHIFT1 || optimize_size) 12197 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12198 "shr{w}\t%0" 12199 [(set_attr "type" "ishift") 12200 (set (attr "length") 12201 (if_then_else (match_operand:SI 0 "register_operand" "") 12202 (const_string "2") 12203 (const_string "*")))]) 12204 12205(define_insn "*lshrhi3_one_bit_cconly" 12206 [(set (reg FLAGS_REG) 12207 (compare 12208 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12209 (match_operand:QI 2 "const1_operand" "")) 12210 (const_int 0))) 12211 (clobber (match_scratch:HI 0 "=r"))] 12212 "ix86_match_ccmode (insn, CCGOCmode) 12213 && (TARGET_SHIFT1 || optimize_size) 12214 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12215 "shr{w}\t%0" 12216 [(set_attr "type" "ishift") 12217 (set_attr "length" "2")]) 12218 12219;; This pattern can't accept a variable shift count, since shifts by 12220;; zero don't affect the flags. We assume that shifts by constant 12221;; zero are optimized away. 12222(define_insn "*lshrhi3_cmp" 12223 [(set (reg FLAGS_REG) 12224 (compare 12225 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12226 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12227 (const_int 0))) 12228 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12229 (lshiftrt:HI (match_dup 1) (match_dup 2)))] 12230 "ix86_match_ccmode (insn, CCGOCmode) 12231 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12232 "shr{w}\t{%2, %0|%0, %2}" 12233 [(set_attr "type" "ishift") 12234 (set_attr "mode" "HI")]) 12235 12236(define_insn "*lshrhi3_cconly" 12237 [(set (reg FLAGS_REG) 12238 (compare 12239 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12240 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12241 (const_int 0))) 12242 (clobber (match_scratch:HI 0 "=r"))] 12243 "ix86_match_ccmode (insn, CCGOCmode) 12244 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12245 "shr{w}\t{%2, %0|%0, %2}" 12246 [(set_attr "type" "ishift") 12247 (set_attr "mode" "HI")]) 12248 12249(define_expand "lshrqi3" 12250 [(set (match_operand:QI 0 "nonimmediate_operand" "") 12251 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "") 12252 (match_operand:QI 2 "nonmemory_operand" ""))) 12253 (clobber (reg:CC FLAGS_REG))] 12254 "TARGET_QIMODE_MATH" 12255 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;") 12256 12257(define_insn "*lshrqi3_1_one_bit" 12258 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12259 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12260 (match_operand:QI 2 "const1_operand" ""))) 12261 (clobber (reg:CC FLAGS_REG))] 12262 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands) 12263 && (TARGET_SHIFT1 || optimize_size)" 12264 "shr{b}\t%0" 12265 [(set_attr "type" "ishift") 12266 (set (attr "length") 12267 (if_then_else (match_operand 0 "register_operand" "") 12268 (const_string "2") 12269 (const_string "*")))]) 12270 12271(define_insn "*lshrqi3_1_one_bit_slp" 12272 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 12273 (lshiftrt:QI (match_dup 0) 12274 (match_operand:QI 1 "const1_operand" ""))) 12275 (clobber (reg:CC FLAGS_REG))] 12276 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12277 && (TARGET_SHIFT1 || optimize_size)" 12278 "shr{b}\t%0" 12279 [(set_attr "type" "ishift1") 12280 (set (attr "length") 12281 (if_then_else (match_operand 0 "register_operand" "") 12282 (const_string "2") 12283 (const_string "*")))]) 12284 12285(define_insn "*lshrqi3_1" 12286 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 12287 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 12288 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12289 (clobber (reg:CC FLAGS_REG))] 12290 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" 12291 "@ 12292 shr{b}\t{%2, %0|%0, %2} 12293 shr{b}\t{%b2, %0|%0, %b2}" 12294 [(set_attr "type" "ishift") 12295 (set_attr "mode" "QI")]) 12296 12297(define_insn "*lshrqi3_1_slp" 12298 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 12299 (lshiftrt:QI (match_dup 0) 12300 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 12301 (clobber (reg:CC FLAGS_REG))] 12302 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12303 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 12304 "@ 12305 shr{b}\t{%1, %0|%0, %1} 12306 shr{b}\t{%b1, %0|%0, %b1}" 12307 [(set_attr "type" "ishift1") 12308 (set_attr "mode" "QI")]) 12309 12310;; This pattern can't accept a variable shift count, since shifts by 12311;; zero don't affect the flags. We assume that shifts by constant 12312;; zero are optimized away. 12313(define_insn "*lshrqi2_one_bit_cmp" 12314 [(set (reg FLAGS_REG) 12315 (compare 12316 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12317 (match_operand:QI 2 "const1_operand" "")) 12318 (const_int 0))) 12319 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12320 (lshiftrt:QI (match_dup 1) (match_dup 2)))] 12321 "ix86_match_ccmode (insn, CCGOCmode) 12322 && (TARGET_SHIFT1 || optimize_size) 12323 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" 12324 "shr{b}\t%0" 12325 [(set_attr "type" "ishift") 12326 (set (attr "length") 12327 (if_then_else (match_operand:SI 0 "register_operand" "") 12328 (const_string "2") 12329 (const_string "*")))]) 12330 12331(define_insn "*lshrqi2_one_bit_cconly" 12332 [(set (reg FLAGS_REG) 12333 (compare 12334 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12335 (match_operand:QI 2 "const1_operand" "")) 12336 (const_int 0))) 12337 (clobber (match_scratch:QI 0 "=q"))] 12338 "ix86_match_ccmode (insn, CCGOCmode) 12339 && (TARGET_SHIFT1 || optimize_size) 12340 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" 12341 "shr{b}\t%0" 12342 [(set_attr "type" "ishift") 12343 (set_attr "length" "2")]) 12344 12345;; This pattern can't accept a variable shift count, since shifts by 12346;; zero don't affect the flags. We assume that shifts by constant 12347;; zero are optimized away. 12348(define_insn "*lshrqi2_cmp" 12349 [(set (reg FLAGS_REG) 12350 (compare 12351 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12352 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12353 (const_int 0))) 12354 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12355 (lshiftrt:QI (match_dup 1) (match_dup 2)))] 12356 "ix86_match_ccmode (insn, CCGOCmode) 12357 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" 12358 "shr{b}\t{%2, %0|%0, %2}" 12359 [(set_attr "type" "ishift") 12360 (set_attr "mode" "QI")]) 12361 12362(define_insn "*lshrqi2_cconly" 12363 [(set (reg FLAGS_REG) 12364 (compare 12365 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12366 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12367 (const_int 0))) 12368 (clobber (match_scratch:QI 0 "=q"))] 12369 "ix86_match_ccmode (insn, CCGOCmode) 12370 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" 12371 "shr{b}\t{%2, %0|%0, %2}" 12372 [(set_attr "type" "ishift") 12373 (set_attr "mode" "QI")]) 12374 12375;; Rotate instructions 12376 12377(define_expand "rotldi3" 12378 [(set (match_operand:DI 0 "shiftdi_operand" "") 12379 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "") 12380 (match_operand:QI 2 "nonmemory_operand" ""))) 12381 (clobber (reg:CC FLAGS_REG))] 12382 "" 12383{ 12384 if (TARGET_64BIT) 12385 { 12386 ix86_expand_binary_operator (ROTATE, DImode, operands); 12387 DONE; 12388 } 12389 if (!const_1_to_31_operand (operands[2], VOIDmode)) 12390 FAIL; 12391 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2])); 12392 DONE; 12393}) 12394 12395;; Implement rotation using two double-precision shift instructions 12396;; and a scratch register. 12397(define_insn_and_split "ix86_rotldi3" 12398 [(set (match_operand:DI 0 "register_operand" "=r") 12399 (rotate:DI (match_operand:DI 1 "register_operand" "0") 12400 (match_operand:QI 2 "const_1_to_31_operand" "I"))) 12401 (clobber (reg:CC FLAGS_REG)) 12402 (clobber (match_scratch:SI 3 "=&r"))] 12403 "!TARGET_64BIT" 12404 "" 12405 "&& reload_completed" 12406 [(set (match_dup 3) (match_dup 4)) 12407 (parallel 12408 [(set (match_dup 4) 12409 (ior:SI (ashift:SI (match_dup 4) (match_dup 2)) 12410 (lshiftrt:SI (match_dup 5) 12411 (minus:QI (const_int 32) (match_dup 2))))) 12412 (clobber (reg:CC FLAGS_REG))]) 12413 (parallel 12414 [(set (match_dup 5) 12415 (ior:SI (ashift:SI (match_dup 5) (match_dup 2)) 12416 (lshiftrt:SI (match_dup 3) 12417 (minus:QI (const_int 32) (match_dup 2))))) 12418 (clobber (reg:CC FLAGS_REG))])] 12419 "split_di (operands, 1, operands + 4, operands + 5);") 12420 12421(define_insn "*rotlsi3_1_one_bit_rex64" 12422 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12423 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12424 (match_operand:QI 2 "const1_operand" ""))) 12425 (clobber (reg:CC FLAGS_REG))] 12426 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands) 12427 && (TARGET_SHIFT1 || optimize_size)" 12428 "rol{q}\t%0" 12429 [(set_attr "type" "rotate") 12430 (set (attr "length") 12431 (if_then_else (match_operand:DI 0 "register_operand" "") 12432 (const_string "2") 12433 (const_string "*")))]) 12434 12435(define_insn "*rotldi3_1_rex64" 12436 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 12437 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 12438 (match_operand:QI 2 "nonmemory_operand" "e,c"))) 12439 (clobber (reg:CC FLAGS_REG))] 12440 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)" 12441 "@ 12442 rol{q}\t{%2, %0|%0, %2} 12443 rol{q}\t{%b2, %0|%0, %b2}" 12444 [(set_attr "type" "rotate") 12445 (set_attr "mode" "DI")]) 12446 12447(define_expand "rotlsi3" 12448 [(set (match_operand:SI 0 "nonimmediate_operand" "") 12449 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "") 12450 (match_operand:QI 2 "nonmemory_operand" ""))) 12451 (clobber (reg:CC FLAGS_REG))] 12452 "" 12453 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;") 12454 12455(define_insn "*rotlsi3_1_one_bit" 12456 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12457 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12458 (match_operand:QI 2 "const1_operand" ""))) 12459 (clobber (reg:CC FLAGS_REG))] 12460 "ix86_binary_operator_ok (ROTATE, SImode, operands) 12461 && (TARGET_SHIFT1 || optimize_size)" 12462 "rol{l}\t%0" 12463 [(set_attr "type" "rotate") 12464 (set (attr "length") 12465 (if_then_else (match_operand:SI 0 "register_operand" "") 12466 (const_string "2") 12467 (const_string "*")))]) 12468 12469(define_insn "*rotlsi3_1_one_bit_zext" 12470 [(set (match_operand:DI 0 "register_operand" "=r") 12471 (zero_extend:DI 12472 (rotate:SI (match_operand:SI 1 "register_operand" "0") 12473 (match_operand:QI 2 "const1_operand" "")))) 12474 (clobber (reg:CC FLAGS_REG))] 12475 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands) 12476 && (TARGET_SHIFT1 || optimize_size)" 12477 "rol{l}\t%k0" 12478 [(set_attr "type" "rotate") 12479 (set_attr "length" "2")]) 12480 12481(define_insn "*rotlsi3_1" 12482 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 12483 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12484 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12485 (clobber (reg:CC FLAGS_REG))] 12486 "ix86_binary_operator_ok (ROTATE, SImode, operands)" 12487 "@ 12488 rol{l}\t{%2, %0|%0, %2} 12489 rol{l}\t{%b2, %0|%0, %b2}" 12490 [(set_attr "type" "rotate") 12491 (set_attr "mode" "SI")]) 12492 12493(define_insn "*rotlsi3_1_zext" 12494 [(set (match_operand:DI 0 "register_operand" "=r,r") 12495 (zero_extend:DI 12496 (rotate:SI (match_operand:SI 1 "register_operand" "0,0") 12497 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 12498 (clobber (reg:CC FLAGS_REG))] 12499 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)" 12500 "@ 12501 rol{l}\t{%2, %k0|%k0, %2} 12502 rol{l}\t{%b2, %k0|%k0, %b2}" 12503 [(set_attr "type" "rotate") 12504 (set_attr "mode" "SI")]) 12505 12506(define_expand "rotlhi3" 12507 [(set (match_operand:HI 0 "nonimmediate_operand" "") 12508 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "") 12509 (match_operand:QI 2 "nonmemory_operand" ""))) 12510 (clobber (reg:CC FLAGS_REG))] 12511 "TARGET_HIMODE_MATH" 12512 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;") 12513 12514(define_insn "*rotlhi3_1_one_bit" 12515 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12516 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12517 (match_operand:QI 2 "const1_operand" ""))) 12518 (clobber (reg:CC FLAGS_REG))] 12519 "ix86_binary_operator_ok (ROTATE, HImode, operands) 12520 && (TARGET_SHIFT1 || optimize_size)" 12521 "rol{w}\t%0" 12522 [(set_attr "type" "rotate") 12523 (set (attr "length") 12524 (if_then_else (match_operand 0 "register_operand" "") 12525 (const_string "2") 12526 (const_string "*")))]) 12527 12528(define_insn "*rotlhi3_1" 12529 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 12530 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 12531 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12532 (clobber (reg:CC FLAGS_REG))] 12533 "ix86_binary_operator_ok (ROTATE, HImode, operands)" 12534 "@ 12535 rol{w}\t{%2, %0|%0, %2} 12536 rol{w}\t{%b2, %0|%0, %b2}" 12537 [(set_attr "type" "rotate") 12538 (set_attr "mode" "HI")]) 12539 12540(define_expand "rotlqi3" 12541 [(set (match_operand:QI 0 "nonimmediate_operand" "") 12542 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "") 12543 (match_operand:QI 2 "nonmemory_operand" ""))) 12544 (clobber (reg:CC FLAGS_REG))] 12545 "TARGET_QIMODE_MATH" 12546 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;") 12547 12548(define_insn "*rotlqi3_1_one_bit_slp" 12549 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 12550 (rotate:QI (match_dup 0) 12551 (match_operand:QI 1 "const1_operand" ""))) 12552 (clobber (reg:CC FLAGS_REG))] 12553 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12554 && (TARGET_SHIFT1 || optimize_size)" 12555 "rol{b}\t%0" 12556 [(set_attr "type" "rotate1") 12557 (set (attr "length") 12558 (if_then_else (match_operand 0 "register_operand" "") 12559 (const_string "2") 12560 (const_string "*")))]) 12561 12562(define_insn "*rotlqi3_1_one_bit" 12563 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12564 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12565 (match_operand:QI 2 "const1_operand" ""))) 12566 (clobber (reg:CC FLAGS_REG))] 12567 "ix86_binary_operator_ok (ROTATE, QImode, operands) 12568 && (TARGET_SHIFT1 || optimize_size)" 12569 "rol{b}\t%0" 12570 [(set_attr "type" "rotate") 12571 (set (attr "length") 12572 (if_then_else (match_operand 0 "register_operand" "") 12573 (const_string "2") 12574 (const_string "*")))]) 12575 12576(define_insn "*rotlqi3_1_slp" 12577 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 12578 (rotate:QI (match_dup 0) 12579 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 12580 (clobber (reg:CC FLAGS_REG))] 12581 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12582 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 12583 "@ 12584 rol{b}\t{%1, %0|%0, %1} 12585 rol{b}\t{%b1, %0|%0, %b1}" 12586 [(set_attr "type" "rotate1") 12587 (set_attr "mode" "QI")]) 12588 12589(define_insn "*rotlqi3_1" 12590 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 12591 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 12592 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12593 (clobber (reg:CC FLAGS_REG))] 12594 "ix86_binary_operator_ok (ROTATE, QImode, operands)" 12595 "@ 12596 rol{b}\t{%2, %0|%0, %2} 12597 rol{b}\t{%b2, %0|%0, %b2}" 12598 [(set_attr "type" "rotate") 12599 (set_attr "mode" "QI")]) 12600 12601(define_expand "rotrdi3" 12602 [(set (match_operand:DI 0 "shiftdi_operand" "") 12603 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "") 12604 (match_operand:QI 2 "nonmemory_operand" ""))) 12605 (clobber (reg:CC FLAGS_REG))] 12606 "" 12607{ 12608 if (TARGET_64BIT) 12609 { 12610 ix86_expand_binary_operator (ROTATERT, DImode, operands); 12611 DONE; 12612 } 12613 if (!const_1_to_31_operand (operands[2], VOIDmode)) 12614 FAIL; 12615 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2])); 12616 DONE; 12617}) 12618 12619;; Implement rotation using two double-precision shift instructions 12620;; and a scratch register. 12621(define_insn_and_split "ix86_rotrdi3" 12622 [(set (match_operand:DI 0 "register_operand" "=r") 12623 (rotatert:DI (match_operand:DI 1 "register_operand" "0") 12624 (match_operand:QI 2 "const_1_to_31_operand" "I"))) 12625 (clobber (reg:CC FLAGS_REG)) 12626 (clobber (match_scratch:SI 3 "=&r"))] 12627 "!TARGET_64BIT" 12628 "" 12629 "&& reload_completed" 12630 [(set (match_dup 3) (match_dup 4)) 12631 (parallel 12632 [(set (match_dup 4) 12633 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2)) 12634 (ashift:SI (match_dup 5) 12635 (minus:QI (const_int 32) (match_dup 2))))) 12636 (clobber (reg:CC FLAGS_REG))]) 12637 (parallel 12638 [(set (match_dup 5) 12639 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2)) 12640 (ashift:SI (match_dup 3) 12641 (minus:QI (const_int 32) (match_dup 2))))) 12642 (clobber (reg:CC FLAGS_REG))])] 12643 "split_di (operands, 1, operands + 4, operands + 5);") 12644 12645(define_insn "*rotrdi3_1_one_bit_rex64" 12646 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12647 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12648 (match_operand:QI 2 "const1_operand" ""))) 12649 (clobber (reg:CC FLAGS_REG))] 12650 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands) 12651 && (TARGET_SHIFT1 || optimize_size)" 12652 "ror{q}\t%0" 12653 [(set_attr "type" "rotate") 12654 (set (attr "length") 12655 (if_then_else (match_operand:DI 0 "register_operand" "") 12656 (const_string "2") 12657 (const_string "*")))]) 12658 12659(define_insn "*rotrdi3_1_rex64" 12660 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 12661 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 12662 (match_operand:QI 2 "nonmemory_operand" "J,c"))) 12663 (clobber (reg:CC FLAGS_REG))] 12664 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)" 12665 "@ 12666 ror{q}\t{%2, %0|%0, %2} 12667 ror{q}\t{%b2, %0|%0, %b2}" 12668 [(set_attr "type" "rotate") 12669 (set_attr "mode" "DI")]) 12670 12671(define_expand "rotrsi3" 12672 [(set (match_operand:SI 0 "nonimmediate_operand" "") 12673 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "") 12674 (match_operand:QI 2 "nonmemory_operand" ""))) 12675 (clobber (reg:CC FLAGS_REG))] 12676 "" 12677 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;") 12678 12679(define_insn "*rotrsi3_1_one_bit" 12680 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12681 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12682 (match_operand:QI 2 "const1_operand" ""))) 12683 (clobber (reg:CC FLAGS_REG))] 12684 "ix86_binary_operator_ok (ROTATERT, SImode, operands) 12685 && (TARGET_SHIFT1 || optimize_size)" 12686 "ror{l}\t%0" 12687 [(set_attr "type" "rotate") 12688 (set (attr "length") 12689 (if_then_else (match_operand:SI 0 "register_operand" "") 12690 (const_string "2") 12691 (const_string "*")))]) 12692 12693(define_insn "*rotrsi3_1_one_bit_zext" 12694 [(set (match_operand:DI 0 "register_operand" "=r") 12695 (zero_extend:DI 12696 (rotatert:SI (match_operand:SI 1 "register_operand" "0") 12697 (match_operand:QI 2 "const1_operand" "")))) 12698 (clobber (reg:CC FLAGS_REG))] 12699 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands) 12700 && (TARGET_SHIFT1 || optimize_size)" 12701 "ror{l}\t%k0" 12702 [(set_attr "type" "rotate") 12703 (set (attr "length") 12704 (if_then_else (match_operand:SI 0 "register_operand" "") 12705 (const_string "2") 12706 (const_string "*")))]) 12707 12708(define_insn "*rotrsi3_1" 12709 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 12710 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12711 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12712 (clobber (reg:CC FLAGS_REG))] 12713 "ix86_binary_operator_ok (ROTATERT, SImode, operands)" 12714 "@ 12715 ror{l}\t{%2, %0|%0, %2} 12716 ror{l}\t{%b2, %0|%0, %b2}" 12717 [(set_attr "type" "rotate") 12718 (set_attr "mode" "SI")]) 12719 12720(define_insn "*rotrsi3_1_zext" 12721 [(set (match_operand:DI 0 "register_operand" "=r,r") 12722 (zero_extend:DI 12723 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0") 12724 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 12725 (clobber (reg:CC FLAGS_REG))] 12726 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)" 12727 "@ 12728 ror{l}\t{%2, %k0|%k0, %2} 12729 ror{l}\t{%b2, %k0|%k0, %b2}" 12730 [(set_attr "type" "rotate") 12731 (set_attr "mode" "SI")]) 12732 12733(define_expand "rotrhi3" 12734 [(set (match_operand:HI 0 "nonimmediate_operand" "") 12735 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "") 12736 (match_operand:QI 2 "nonmemory_operand" ""))) 12737 (clobber (reg:CC FLAGS_REG))] 12738 "TARGET_HIMODE_MATH" 12739 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;") 12740 12741(define_insn "*rotrhi3_one_bit" 12742 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12743 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12744 (match_operand:QI 2 "const1_operand" ""))) 12745 (clobber (reg:CC FLAGS_REG))] 12746 "ix86_binary_operator_ok (ROTATERT, HImode, operands) 12747 && (TARGET_SHIFT1 || optimize_size)" 12748 "ror{w}\t%0" 12749 [(set_attr "type" "rotate") 12750 (set (attr "length") 12751 (if_then_else (match_operand 0 "register_operand" "") 12752 (const_string "2") 12753 (const_string "*")))]) 12754 12755(define_insn "*rotrhi3" 12756 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 12757 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 12758 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12759 (clobber (reg:CC FLAGS_REG))] 12760 "ix86_binary_operator_ok (ROTATERT, HImode, operands)" 12761 "@ 12762 ror{w}\t{%2, %0|%0, %2} 12763 ror{w}\t{%b2, %0|%0, %b2}" 12764 [(set_attr "type" "rotate") 12765 (set_attr "mode" "HI")]) 12766 12767(define_expand "rotrqi3" 12768 [(set (match_operand:QI 0 "nonimmediate_operand" "") 12769 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "") 12770 (match_operand:QI 2 "nonmemory_operand" ""))) 12771 (clobber (reg:CC FLAGS_REG))] 12772 "TARGET_QIMODE_MATH" 12773 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;") 12774 12775(define_insn "*rotrqi3_1_one_bit" 12776 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12777 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12778 (match_operand:QI 2 "const1_operand" ""))) 12779 (clobber (reg:CC FLAGS_REG))] 12780 "ix86_binary_operator_ok (ROTATERT, QImode, operands) 12781 && (TARGET_SHIFT1 || optimize_size)" 12782 "ror{b}\t%0" 12783 [(set_attr "type" "rotate") 12784 (set (attr "length") 12785 (if_then_else (match_operand 0 "register_operand" "") 12786 (const_string "2") 12787 (const_string "*")))]) 12788 12789(define_insn "*rotrqi3_1_one_bit_slp" 12790 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 12791 (rotatert:QI (match_dup 0) 12792 (match_operand:QI 1 "const1_operand" ""))) 12793 (clobber (reg:CC FLAGS_REG))] 12794 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12795 && (TARGET_SHIFT1 || optimize_size)" 12796 "ror{b}\t%0" 12797 [(set_attr "type" "rotate1") 12798 (set (attr "length") 12799 (if_then_else (match_operand 0 "register_operand" "") 12800 (const_string "2") 12801 (const_string "*")))]) 12802 12803(define_insn "*rotrqi3_1" 12804 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 12805 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 12806 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12807 (clobber (reg:CC FLAGS_REG))] 12808 "ix86_binary_operator_ok (ROTATERT, QImode, operands)" 12809 "@ 12810 ror{b}\t{%2, %0|%0, %2} 12811 ror{b}\t{%b2, %0|%0, %b2}" 12812 [(set_attr "type" "rotate") 12813 (set_attr "mode" "QI")]) 12814 12815(define_insn "*rotrqi3_1_slp" 12816 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 12817 (rotatert:QI (match_dup 0) 12818 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 12819 (clobber (reg:CC FLAGS_REG))] 12820 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12821 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 12822 "@ 12823 ror{b}\t{%1, %0|%0, %1} 12824 ror{b}\t{%b1, %0|%0, %b1}" 12825 [(set_attr "type" "rotate1") 12826 (set_attr "mode" "QI")]) 12827 12828;; Bit set / bit test instructions 12829 12830(define_expand "extv" 12831 [(set (match_operand:SI 0 "register_operand" "") 12832 (sign_extract:SI (match_operand:SI 1 "register_operand" "") 12833 (match_operand:SI 2 "const8_operand" "") 12834 (match_operand:SI 3 "const8_operand" "")))] 12835 "" 12836{ 12837 /* Handle extractions from %ah et al. */ 12838 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 12839 FAIL; 12840 12841 /* From mips.md: extract_bit_field doesn't verify that our source 12842 matches the predicate, so check it again here. */ 12843 if (! ext_register_operand (operands[1], VOIDmode)) 12844 FAIL; 12845}) 12846 12847(define_expand "extzv" 12848 [(set (match_operand:SI 0 "register_operand" "") 12849 (zero_extract:SI (match_operand 1 "ext_register_operand" "") 12850 (match_operand:SI 2 "const8_operand" "") 12851 (match_operand:SI 3 "const8_operand" "")))] 12852 "" 12853{ 12854 /* Handle extractions from %ah et al. */ 12855 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 12856 FAIL; 12857 12858 /* From mips.md: extract_bit_field doesn't verify that our source 12859 matches the predicate, so check it again here. */ 12860 if (! ext_register_operand (operands[1], VOIDmode)) 12861 FAIL; 12862}) 12863 12864(define_expand "insv" 12865 [(set (zero_extract (match_operand 0 "ext_register_operand" "") 12866 (match_operand 1 "const8_operand" "") 12867 (match_operand 2 "const8_operand" "")) 12868 (match_operand 3 "register_operand" ""))] 12869 "" 12870{ 12871 /* Handle insertions to %ah et al. */ 12872 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8) 12873 FAIL; 12874 12875 /* From mips.md: insert_bit_field doesn't verify that our source 12876 matches the predicate, so check it again here. */ 12877 if (! ext_register_operand (operands[0], VOIDmode)) 12878 FAIL; 12879 12880 if (TARGET_64BIT) 12881 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3])); 12882 else 12883 emit_insn (gen_movsi_insv_1 (operands[0], operands[3])); 12884 12885 DONE; 12886}) 12887 12888;; %%% bts, btr, btc, bt. 12889;; In general these instructions are *slow* when applied to memory, 12890;; since they enforce atomic operation. When applied to registers, 12891;; it depends on the cpu implementation. They're never faster than 12892;; the corresponding and/ior/xor operations, so with 32-bit there's 12893;; no point. But in 64-bit, we can't hold the relevant immediates 12894;; within the instruction itself, so operating on bits in the high 12895;; 32-bits of a register becomes easier. 12896;; 12897;; These are slow on Nocona, but fast on Athlon64. We do require the use 12898;; of btrq and btcq for corner cases of post-reload expansion of absdf and 12899;; negdf respectively, so they can never be disabled entirely. 12900 12901(define_insn "*btsq" 12902 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 12903 (const_int 1) 12904 (match_operand:DI 1 "const_0_to_63_operand" "")) 12905 (const_int 1)) 12906 (clobber (reg:CC FLAGS_REG))] 12907 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 12908 "bts{q} %1,%0" 12909 [(set_attr "type" "alu1")]) 12910 12911(define_insn "*btrq" 12912 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 12913 (const_int 1) 12914 (match_operand:DI 1 "const_0_to_63_operand" "")) 12915 (const_int 0)) 12916 (clobber (reg:CC FLAGS_REG))] 12917 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 12918 "btr{q} %1,%0" 12919 [(set_attr "type" "alu1")]) 12920 12921(define_insn "*btcq" 12922 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 12923 (const_int 1) 12924 (match_operand:DI 1 "const_0_to_63_operand" "")) 12925 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) 12926 (clobber (reg:CC FLAGS_REG))] 12927 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 12928 "btc{q} %1,%0" 12929 [(set_attr "type" "alu1")]) 12930 12931;; Allow Nocona to avoid these instructions if a register is available. 12932 12933(define_peephole2 12934 [(match_scratch:DI 2 "r") 12935 (parallel [(set (zero_extract:DI 12936 (match_operand:DI 0 "register_operand" "") 12937 (const_int 1) 12938 (match_operand:DI 1 "const_0_to_63_operand" "")) 12939 (const_int 1)) 12940 (clobber (reg:CC FLAGS_REG))])] 12941 "TARGET_64BIT && !TARGET_USE_BT" 12942 [(const_int 0)] 12943{ 12944 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 12945 rtx op1; 12946 12947 if (HOST_BITS_PER_WIDE_INT >= 64) 12948 lo = (HOST_WIDE_INT)1 << i, hi = 0; 12949 else if (i < HOST_BITS_PER_WIDE_INT) 12950 lo = (HOST_WIDE_INT)1 << i, hi = 0; 12951 else 12952 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 12953 12954 op1 = immed_double_const (lo, hi, DImode); 12955 if (i >= 31) 12956 { 12957 emit_move_insn (operands[2], op1); 12958 op1 = operands[2]; 12959 } 12960 12961 emit_insn (gen_iordi3 (operands[0], operands[0], op1)); 12962 DONE; 12963}) 12964 12965(define_peephole2 12966 [(match_scratch:DI 2 "r") 12967 (parallel [(set (zero_extract:DI 12968 (match_operand:DI 0 "register_operand" "") 12969 (const_int 1) 12970 (match_operand:DI 1 "const_0_to_63_operand" "")) 12971 (const_int 0)) 12972 (clobber (reg:CC FLAGS_REG))])] 12973 "TARGET_64BIT && !TARGET_USE_BT" 12974 [(const_int 0)] 12975{ 12976 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 12977 rtx op1; 12978 12979 if (HOST_BITS_PER_WIDE_INT >= 64) 12980 lo = (HOST_WIDE_INT)1 << i, hi = 0; 12981 else if (i < HOST_BITS_PER_WIDE_INT) 12982 lo = (HOST_WIDE_INT)1 << i, hi = 0; 12983 else 12984 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 12985 12986 op1 = immed_double_const (~lo, ~hi, DImode); 12987 if (i >= 32) 12988 { 12989 emit_move_insn (operands[2], op1); 12990 op1 = operands[2]; 12991 } 12992 12993 emit_insn (gen_anddi3 (operands[0], operands[0], op1)); 12994 DONE; 12995}) 12996 12997(define_peephole2 12998 [(match_scratch:DI 2 "r") 12999 (parallel [(set (zero_extract:DI 13000 (match_operand:DI 0 "register_operand" "") 13001 (const_int 1) 13002 (match_operand:DI 1 "const_0_to_63_operand" "")) 13003 (not:DI (zero_extract:DI 13004 (match_dup 0) (const_int 1) (match_dup 1)))) 13005 (clobber (reg:CC FLAGS_REG))])] 13006 "TARGET_64BIT && !TARGET_USE_BT" 13007 [(const_int 0)] 13008{ 13009 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 13010 rtx op1; 13011 13012 if (HOST_BITS_PER_WIDE_INT >= 64) 13013 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13014 else if (i < HOST_BITS_PER_WIDE_INT) 13015 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13016 else 13017 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 13018 13019 op1 = immed_double_const (lo, hi, DImode); 13020 if (i >= 31) 13021 { 13022 emit_move_insn (operands[2], op1); 13023 op1 = operands[2]; 13024 } 13025 13026 emit_insn (gen_xordi3 (operands[0], operands[0], op1)); 13027 DONE; 13028}) 13029 13030;; Store-flag instructions. 13031 13032;; For all sCOND expanders, also expand the compare or test insn that 13033;; generates cc0. Generate an equality comparison if `seq' or `sne'. 13034 13035;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way 13036;; to avoid partial register stalls. Otherwise do things the setcc+movzx 13037;; way, which can later delete the movzx if only QImode is needed. 13038 13039(define_expand "seq" 13040 [(set (match_operand:QI 0 "register_operand" "") 13041 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))] 13042 "" 13043 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;") 13044 13045(define_expand "sne" 13046 [(set (match_operand:QI 0 "register_operand" "") 13047 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))] 13048 "" 13049 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;") 13050 13051(define_expand "sgt" 13052 [(set (match_operand:QI 0 "register_operand" "") 13053 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13054 "" 13055 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;") 13056 13057(define_expand "sgtu" 13058 [(set (match_operand:QI 0 "register_operand" "") 13059 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13060 "" 13061 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;") 13062 13063(define_expand "slt" 13064 [(set (match_operand:QI 0 "register_operand" "") 13065 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13066 "" 13067 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;") 13068 13069(define_expand "sltu" 13070 [(set (match_operand:QI 0 "register_operand" "") 13071 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13072 "" 13073 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;") 13074 13075(define_expand "sge" 13076 [(set (match_operand:QI 0 "register_operand" "") 13077 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))] 13078 "" 13079 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;") 13080 13081(define_expand "sgeu" 13082 [(set (match_operand:QI 0 "register_operand" "") 13083 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13084 "" 13085 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;") 13086 13087(define_expand "sle" 13088 [(set (match_operand:QI 0 "register_operand" "") 13089 (le:QI (reg:CC FLAGS_REG) (const_int 0)))] 13090 "" 13091 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;") 13092 13093(define_expand "sleu" 13094 [(set (match_operand:QI 0 "register_operand" "") 13095 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13096 "" 13097 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;") 13098 13099(define_expand "sunordered" 13100 [(set (match_operand:QI 0 "register_operand" "") 13101 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))] 13102 "TARGET_80387 || TARGET_SSE" 13103 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;") 13104 13105(define_expand "sordered" 13106 [(set (match_operand:QI 0 "register_operand" "") 13107 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))] 13108 "TARGET_80387" 13109 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;") 13110 13111(define_expand "suneq" 13112 [(set (match_operand:QI 0 "register_operand" "") 13113 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))] 13114 "TARGET_80387 || TARGET_SSE" 13115 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;") 13116 13117(define_expand "sunge" 13118 [(set (match_operand:QI 0 "register_operand" "") 13119 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))] 13120 "TARGET_80387 || TARGET_SSE" 13121 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;") 13122 13123(define_expand "sungt" 13124 [(set (match_operand:QI 0 "register_operand" "") 13125 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13126 "TARGET_80387 || TARGET_SSE" 13127 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;") 13128 13129(define_expand "sunle" 13130 [(set (match_operand:QI 0 "register_operand" "") 13131 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))] 13132 "TARGET_80387 || TARGET_SSE" 13133 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;") 13134 13135(define_expand "sunlt" 13136 [(set (match_operand:QI 0 "register_operand" "") 13137 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13138 "TARGET_80387 || TARGET_SSE" 13139 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;") 13140 13141(define_expand "sltgt" 13142 [(set (match_operand:QI 0 "register_operand" "") 13143 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13144 "TARGET_80387 || TARGET_SSE" 13145 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;") 13146 13147(define_insn "*setcc_1" 13148 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 13149 (match_operator:QI 1 "ix86_comparison_operator" 13150 [(reg FLAGS_REG) (const_int 0)]))] 13151 "" 13152 "set%C1\t%0" 13153 [(set_attr "type" "setcc") 13154 (set_attr "mode" "QI")]) 13155 13156(define_insn "*setcc_2" 13157 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 13158 (match_operator:QI 1 "ix86_comparison_operator" 13159 [(reg FLAGS_REG) (const_int 0)]))] 13160 "" 13161 "set%C1\t%0" 13162 [(set_attr "type" "setcc") 13163 (set_attr "mode" "QI")]) 13164 13165;; In general it is not safe to assume too much about CCmode registers, 13166;; so simplify-rtx stops when it sees a second one. Under certain 13167;; conditions this is safe on x86, so help combine not create 13168;; 13169;; seta %al 13170;; testb %al, %al 13171;; sete %al 13172 13173(define_split 13174 [(set (match_operand:QI 0 "nonimmediate_operand" "") 13175 (ne:QI (match_operator 1 "ix86_comparison_operator" 13176 [(reg FLAGS_REG) (const_int 0)]) 13177 (const_int 0)))] 13178 "" 13179 [(set (match_dup 0) (match_dup 1))] 13180{ 13181 PUT_MODE (operands[1], QImode); 13182}) 13183 13184(define_split 13185 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 13186 (ne:QI (match_operator 1 "ix86_comparison_operator" 13187 [(reg FLAGS_REG) (const_int 0)]) 13188 (const_int 0)))] 13189 "" 13190 [(set (match_dup 0) (match_dup 1))] 13191{ 13192 PUT_MODE (operands[1], QImode); 13193}) 13194 13195(define_split 13196 [(set (match_operand:QI 0 "nonimmediate_operand" "") 13197 (eq:QI (match_operator 1 "ix86_comparison_operator" 13198 [(reg FLAGS_REG) (const_int 0)]) 13199 (const_int 0)))] 13200 "" 13201 [(set (match_dup 0) (match_dup 1))] 13202{ 13203 rtx new_op1 = copy_rtx (operands[1]); 13204 operands[1] = new_op1; 13205 PUT_MODE (new_op1, QImode); 13206 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), 13207 GET_MODE (XEXP (new_op1, 0)))); 13208 13209 /* Make sure that (a) the CCmode we have for the flags is strong 13210 enough for the reversed compare or (b) we have a valid FP compare. */ 13211 if (! ix86_comparison_operator (new_op1, VOIDmode)) 13212 FAIL; 13213}) 13214 13215(define_split 13216 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 13217 (eq:QI (match_operator 1 "ix86_comparison_operator" 13218 [(reg FLAGS_REG) (const_int 0)]) 13219 (const_int 0)))] 13220 "" 13221 [(set (match_dup 0) (match_dup 1))] 13222{ 13223 rtx new_op1 = copy_rtx (operands[1]); 13224 operands[1] = new_op1; 13225 PUT_MODE (new_op1, QImode); 13226 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), 13227 GET_MODE (XEXP (new_op1, 0)))); 13228 13229 /* Make sure that (a) the CCmode we have for the flags is strong 13230 enough for the reversed compare or (b) we have a valid FP compare. */ 13231 if (! ix86_comparison_operator (new_op1, VOIDmode)) 13232 FAIL; 13233}) 13234 13235;; The SSE store flag instructions saves 0 or 0xffffffff to the result. 13236;; subsequent logical operations are used to imitate conditional moves. 13237;; 0xffffffff is NaN, but not in normalized form, so we can't represent 13238;; it directly. 13239 13240(define_insn "*sse_setccsf" 13241 [(set (match_operand:SF 0 "register_operand" "=x") 13242 (match_operator:SF 1 "sse_comparison_operator" 13243 [(match_operand:SF 2 "register_operand" "0") 13244 (match_operand:SF 3 "nonimmediate_operand" "xm")]))] 13245 "TARGET_SSE" 13246 "cmp%D1ss\t{%3, %0|%0, %3}" 13247 [(set_attr "type" "ssecmp") 13248 (set_attr "mode" "SF")]) 13249 13250(define_insn "*sse_setccdf" 13251 [(set (match_operand:DF 0 "register_operand" "=Y") 13252 (match_operator:DF 1 "sse_comparison_operator" 13253 [(match_operand:DF 2 "register_operand" "0") 13254 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))] 13255 "TARGET_SSE2" 13256 "cmp%D1sd\t{%3, %0|%0, %3}" 13257 [(set_attr "type" "ssecmp") 13258 (set_attr "mode" "DF")]) 13259 13260;; Basic conditional jump instructions. 13261;; We ignore the overflow flag for signed branch instructions. 13262 13263;; For all bCOND expanders, also expand the compare or test insn that 13264;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'. 13265 13266(define_expand "beq" 13267 [(set (pc) 13268 (if_then_else (match_dup 1) 13269 (label_ref (match_operand 0 "" "")) 13270 (pc)))] 13271 "" 13272 "ix86_expand_branch (EQ, operands[0]); DONE;") 13273 13274(define_expand "bne" 13275 [(set (pc) 13276 (if_then_else (match_dup 1) 13277 (label_ref (match_operand 0 "" "")) 13278 (pc)))] 13279 "" 13280 "ix86_expand_branch (NE, operands[0]); DONE;") 13281 13282(define_expand "bgt" 13283 [(set (pc) 13284 (if_then_else (match_dup 1) 13285 (label_ref (match_operand 0 "" "")) 13286 (pc)))] 13287 "" 13288 "ix86_expand_branch (GT, operands[0]); DONE;") 13289 13290(define_expand "bgtu" 13291 [(set (pc) 13292 (if_then_else (match_dup 1) 13293 (label_ref (match_operand 0 "" "")) 13294 (pc)))] 13295 "" 13296 "ix86_expand_branch (GTU, operands[0]); DONE;") 13297 13298(define_expand "blt" 13299 [(set (pc) 13300 (if_then_else (match_dup 1) 13301 (label_ref (match_operand 0 "" "")) 13302 (pc)))] 13303 "" 13304 "ix86_expand_branch (LT, operands[0]); DONE;") 13305 13306(define_expand "bltu" 13307 [(set (pc) 13308 (if_then_else (match_dup 1) 13309 (label_ref (match_operand 0 "" "")) 13310 (pc)))] 13311 "" 13312 "ix86_expand_branch (LTU, operands[0]); DONE;") 13313 13314(define_expand "bge" 13315 [(set (pc) 13316 (if_then_else (match_dup 1) 13317 (label_ref (match_operand 0 "" "")) 13318 (pc)))] 13319 "" 13320 "ix86_expand_branch (GE, operands[0]); DONE;") 13321 13322(define_expand "bgeu" 13323 [(set (pc) 13324 (if_then_else (match_dup 1) 13325 (label_ref (match_operand 0 "" "")) 13326 (pc)))] 13327 "" 13328 "ix86_expand_branch (GEU, operands[0]); DONE;") 13329 13330(define_expand "ble" 13331 [(set (pc) 13332 (if_then_else (match_dup 1) 13333 (label_ref (match_operand 0 "" "")) 13334 (pc)))] 13335 "" 13336 "ix86_expand_branch (LE, operands[0]); DONE;") 13337 13338(define_expand "bleu" 13339 [(set (pc) 13340 (if_then_else (match_dup 1) 13341 (label_ref (match_operand 0 "" "")) 13342 (pc)))] 13343 "" 13344 "ix86_expand_branch (LEU, operands[0]); DONE;") 13345 13346(define_expand "bunordered" 13347 [(set (pc) 13348 (if_then_else (match_dup 1) 13349 (label_ref (match_operand 0 "" "")) 13350 (pc)))] 13351 "TARGET_80387 || TARGET_SSE_MATH" 13352 "ix86_expand_branch (UNORDERED, operands[0]); DONE;") 13353 13354(define_expand "bordered" 13355 [(set (pc) 13356 (if_then_else (match_dup 1) 13357 (label_ref (match_operand 0 "" "")) 13358 (pc)))] 13359 "TARGET_80387 || TARGET_SSE_MATH" 13360 "ix86_expand_branch (ORDERED, operands[0]); DONE;") 13361 13362(define_expand "buneq" 13363 [(set (pc) 13364 (if_then_else (match_dup 1) 13365 (label_ref (match_operand 0 "" "")) 13366 (pc)))] 13367 "TARGET_80387 || TARGET_SSE_MATH" 13368 "ix86_expand_branch (UNEQ, operands[0]); DONE;") 13369 13370(define_expand "bunge" 13371 [(set (pc) 13372 (if_then_else (match_dup 1) 13373 (label_ref (match_operand 0 "" "")) 13374 (pc)))] 13375 "TARGET_80387 || TARGET_SSE_MATH" 13376 "ix86_expand_branch (UNGE, operands[0]); DONE;") 13377 13378(define_expand "bungt" 13379 [(set (pc) 13380 (if_then_else (match_dup 1) 13381 (label_ref (match_operand 0 "" "")) 13382 (pc)))] 13383 "TARGET_80387 || TARGET_SSE_MATH" 13384 "ix86_expand_branch (UNGT, operands[0]); DONE;") 13385 13386(define_expand "bunle" 13387 [(set (pc) 13388 (if_then_else (match_dup 1) 13389 (label_ref (match_operand 0 "" "")) 13390 (pc)))] 13391 "TARGET_80387 || TARGET_SSE_MATH" 13392 "ix86_expand_branch (UNLE, operands[0]); DONE;") 13393 13394(define_expand "bunlt" 13395 [(set (pc) 13396 (if_then_else (match_dup 1) 13397 (label_ref (match_operand 0 "" "")) 13398 (pc)))] 13399 "TARGET_80387 || TARGET_SSE_MATH" 13400 "ix86_expand_branch (UNLT, operands[0]); DONE;") 13401 13402(define_expand "bltgt" 13403 [(set (pc) 13404 (if_then_else (match_dup 1) 13405 (label_ref (match_operand 0 "" "")) 13406 (pc)))] 13407 "TARGET_80387 || TARGET_SSE_MATH" 13408 "ix86_expand_branch (LTGT, operands[0]); DONE;") 13409 13410(define_insn "*jcc_1" 13411 [(set (pc) 13412 (if_then_else (match_operator 1 "ix86_comparison_operator" 13413 [(reg FLAGS_REG) (const_int 0)]) 13414 (label_ref (match_operand 0 "" "")) 13415 (pc)))] 13416 "" 13417 "%+j%C1\t%l0" 13418 [(set_attr "type" "ibr") 13419 (set_attr "modrm" "0") 13420 (set (attr "length") 13421 (if_then_else (and (ge (minus (match_dup 0) (pc)) 13422 (const_int -126)) 13423 (lt (minus (match_dup 0) (pc)) 13424 (const_int 128))) 13425 (const_int 2) 13426 (const_int 6)))]) 13427 13428(define_insn "*jcc_2" 13429 [(set (pc) 13430 (if_then_else (match_operator 1 "ix86_comparison_operator" 13431 [(reg FLAGS_REG) (const_int 0)]) 13432 (pc) 13433 (label_ref (match_operand 0 "" ""))))] 13434 "" 13435 "%+j%c1\t%l0" 13436 [(set_attr "type" "ibr") 13437 (set_attr "modrm" "0") 13438 (set (attr "length") 13439 (if_then_else (and (ge (minus (match_dup 0) (pc)) 13440 (const_int -126)) 13441 (lt (minus (match_dup 0) (pc)) 13442 (const_int 128))) 13443 (const_int 2) 13444 (const_int 6)))]) 13445 13446;; In general it is not safe to assume too much about CCmode registers, 13447;; so simplify-rtx stops when it sees a second one. Under certain 13448;; conditions this is safe on x86, so help combine not create 13449;; 13450;; seta %al 13451;; testb %al, %al 13452;; je Lfoo 13453 13454(define_split 13455 [(set (pc) 13456 (if_then_else (ne (match_operator 0 "ix86_comparison_operator" 13457 [(reg FLAGS_REG) (const_int 0)]) 13458 (const_int 0)) 13459 (label_ref (match_operand 1 "" "")) 13460 (pc)))] 13461 "" 13462 [(set (pc) 13463 (if_then_else (match_dup 0) 13464 (label_ref (match_dup 1)) 13465 (pc)))] 13466{ 13467 PUT_MODE (operands[0], VOIDmode); 13468}) 13469 13470(define_split 13471 [(set (pc) 13472 (if_then_else (eq (match_operator 0 "ix86_comparison_operator" 13473 [(reg FLAGS_REG) (const_int 0)]) 13474 (const_int 0)) 13475 (label_ref (match_operand 1 "" "")) 13476 (pc)))] 13477 "" 13478 [(set (pc) 13479 (if_then_else (match_dup 0) 13480 (label_ref (match_dup 1)) 13481 (pc)))] 13482{ 13483 rtx new_op0 = copy_rtx (operands[0]); 13484 operands[0] = new_op0; 13485 PUT_MODE (new_op0, VOIDmode); 13486 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0), 13487 GET_MODE (XEXP (new_op0, 0)))); 13488 13489 /* Make sure that (a) the CCmode we have for the flags is strong 13490 enough for the reversed compare or (b) we have a valid FP compare. */ 13491 if (! ix86_comparison_operator (new_op0, VOIDmode)) 13492 FAIL; 13493}) 13494 13495;; Define combination compare-and-branch fp compare instructions to use 13496;; during early optimization. Splitting the operation apart early makes 13497;; for bad code when we want to reverse the operation. 13498 13499(define_insn "*fp_jcc_1_mixed" 13500 [(set (pc) 13501 (if_then_else (match_operator 0 "comparison_operator" 13502 [(match_operand 1 "register_operand" "f#x,x#f") 13503 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")]) 13504 (label_ref (match_operand 3 "" "")) 13505 (pc))) 13506 (clobber (reg:CCFP FPSR_REG)) 13507 (clobber (reg:CCFP FLAGS_REG))] 13508 "TARGET_MIX_SSE_I387 13509 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13510 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13511 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13512 "#") 13513 13514(define_insn "*fp_jcc_1_sse" 13515 [(set (pc) 13516 (if_then_else (match_operator 0 "comparison_operator" 13517 [(match_operand 1 "register_operand" "x") 13518 (match_operand 2 "nonimmediate_operand" "xm")]) 13519 (label_ref (match_operand 3 "" "")) 13520 (pc))) 13521 (clobber (reg:CCFP FPSR_REG)) 13522 (clobber (reg:CCFP FLAGS_REG))] 13523 "TARGET_SSE_MATH 13524 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13525 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13526 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13527 "#") 13528 13529(define_insn "*fp_jcc_1_387" 13530 [(set (pc) 13531 (if_then_else (match_operator 0 "comparison_operator" 13532 [(match_operand 1 "register_operand" "f") 13533 (match_operand 2 "register_operand" "f")]) 13534 (label_ref (match_operand 3 "" "")) 13535 (pc))) 13536 (clobber (reg:CCFP FPSR_REG)) 13537 (clobber (reg:CCFP FLAGS_REG))] 13538 "TARGET_CMOVE && TARGET_80387 13539 && FLOAT_MODE_P (GET_MODE (operands[1])) 13540 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13541 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13542 "#") 13543 13544(define_insn "*fp_jcc_2_mixed" 13545 [(set (pc) 13546 (if_then_else (match_operator 0 "comparison_operator" 13547 [(match_operand 1 "register_operand" "f#x,x#f") 13548 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")]) 13549 (pc) 13550 (label_ref (match_operand 3 "" "")))) 13551 (clobber (reg:CCFP FPSR_REG)) 13552 (clobber (reg:CCFP FLAGS_REG))] 13553 "TARGET_MIX_SSE_I387 13554 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13555 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13556 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13557 "#") 13558 13559(define_insn "*fp_jcc_2_sse" 13560 [(set (pc) 13561 (if_then_else (match_operator 0 "comparison_operator" 13562 [(match_operand 1 "register_operand" "x") 13563 (match_operand 2 "nonimmediate_operand" "xm")]) 13564 (pc) 13565 (label_ref (match_operand 3 "" "")))) 13566 (clobber (reg:CCFP FPSR_REG)) 13567 (clobber (reg:CCFP FLAGS_REG))] 13568 "TARGET_SSE_MATH 13569 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13570 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13571 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13572 "#") 13573 13574(define_insn "*fp_jcc_2_387" 13575 [(set (pc) 13576 (if_then_else (match_operator 0 "comparison_operator" 13577 [(match_operand 1 "register_operand" "f") 13578 (match_operand 2 "register_operand" "f")]) 13579 (pc) 13580 (label_ref (match_operand 3 "" "")))) 13581 (clobber (reg:CCFP FPSR_REG)) 13582 (clobber (reg:CCFP FLAGS_REG))] 13583 "TARGET_CMOVE && TARGET_80387 13584 && FLOAT_MODE_P (GET_MODE (operands[1])) 13585 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13586 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13587 "#") 13588 13589(define_insn "*fp_jcc_3_387" 13590 [(set (pc) 13591 (if_then_else (match_operator 0 "comparison_operator" 13592 [(match_operand 1 "register_operand" "f") 13593 (match_operand 2 "nonimmediate_operand" "fm")]) 13594 (label_ref (match_operand 3 "" "")) 13595 (pc))) 13596 (clobber (reg:CCFP FPSR_REG)) 13597 (clobber (reg:CCFP FLAGS_REG)) 13598 (clobber (match_scratch:HI 4 "=a"))] 13599 "TARGET_80387 13600 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) 13601 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13602 && !ix86_use_fcomi_compare (GET_CODE (operands[0])) 13603 && SELECT_CC_MODE (GET_CODE (operands[0]), 13604 operands[1], operands[2]) == CCFPmode 13605 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13606 "#") 13607 13608(define_insn "*fp_jcc_4_387" 13609 [(set (pc) 13610 (if_then_else (match_operator 0 "comparison_operator" 13611 [(match_operand 1 "register_operand" "f") 13612 (match_operand 2 "nonimmediate_operand" "fm")]) 13613 (pc) 13614 (label_ref (match_operand 3 "" "")))) 13615 (clobber (reg:CCFP FPSR_REG)) 13616 (clobber (reg:CCFP FLAGS_REG)) 13617 (clobber (match_scratch:HI 4 "=a"))] 13618 "TARGET_80387 13619 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) 13620 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13621 && !ix86_use_fcomi_compare (GET_CODE (operands[0])) 13622 && SELECT_CC_MODE (GET_CODE (operands[0]), 13623 operands[1], operands[2]) == CCFPmode 13624 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13625 "#") 13626 13627(define_insn "*fp_jcc_5_387" 13628 [(set (pc) 13629 (if_then_else (match_operator 0 "comparison_operator" 13630 [(match_operand 1 "register_operand" "f") 13631 (match_operand 2 "register_operand" "f")]) 13632 (label_ref (match_operand 3 "" "")) 13633 (pc))) 13634 (clobber (reg:CCFP FPSR_REG)) 13635 (clobber (reg:CCFP FLAGS_REG)) 13636 (clobber (match_scratch:HI 4 "=a"))] 13637 "TARGET_80387 13638 && FLOAT_MODE_P (GET_MODE (operands[1])) 13639 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13640 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13641 "#") 13642 13643(define_insn "*fp_jcc_6_387" 13644 [(set (pc) 13645 (if_then_else (match_operator 0 "comparison_operator" 13646 [(match_operand 1 "register_operand" "f") 13647 (match_operand 2 "register_operand" "f")]) 13648 (pc) 13649 (label_ref (match_operand 3 "" "")))) 13650 (clobber (reg:CCFP FPSR_REG)) 13651 (clobber (reg:CCFP FLAGS_REG)) 13652 (clobber (match_scratch:HI 4 "=a"))] 13653 "TARGET_80387 13654 && FLOAT_MODE_P (GET_MODE (operands[1])) 13655 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13656 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13657 "#") 13658 13659(define_insn "*fp_jcc_7_387" 13660 [(set (pc) 13661 (if_then_else (match_operator 0 "comparison_operator" 13662 [(match_operand 1 "register_operand" "f") 13663 (match_operand 2 "const0_operand" "X")]) 13664 (label_ref (match_operand 3 "" "")) 13665 (pc))) 13666 (clobber (reg:CCFP FPSR_REG)) 13667 (clobber (reg:CCFP FLAGS_REG)) 13668 (clobber (match_scratch:HI 4 "=a"))] 13669 "TARGET_80387 13670 && FLOAT_MODE_P (GET_MODE (operands[1])) 13671 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13672 && !ix86_use_fcomi_compare (GET_CODE (operands[0])) 13673 && SELECT_CC_MODE (GET_CODE (operands[0]), 13674 operands[1], operands[2]) == CCFPmode 13675 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13676 "#") 13677 13678;; The order of operands in *fp_jcc_8_387 is forced by combine in 13679;; simplify_comparison () function. Float operator is treated as RTX_OBJ 13680;; with a precedence over other operators and is always put in the first 13681;; place. Swap condition and operands to match ficom instruction. 13682 13683(define_insn "*fp_jcc_8<mode>_387" 13684 [(set (pc) 13685 (if_then_else (match_operator 0 "comparison_operator" 13686 [(match_operator 1 "float_operator" 13687 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")]) 13688 (match_operand 3 "register_operand" "f,f")]) 13689 (label_ref (match_operand 4 "" "")) 13690 (pc))) 13691 (clobber (reg:CCFP FPSR_REG)) 13692 (clobber (reg:CCFP FLAGS_REG)) 13693 (clobber (match_scratch:HI 5 "=a,a"))] 13694 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 13695 && FLOAT_MODE_P (GET_MODE (operands[3])) 13696 && GET_MODE (operands[1]) == GET_MODE (operands[3]) 13697 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0]))) 13698 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode 13699 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))" 13700 "#") 13701 13702(define_split 13703 [(set (pc) 13704 (if_then_else (match_operator 0 "comparison_operator" 13705 [(match_operand 1 "register_operand" "") 13706 (match_operand 2 "nonimmediate_operand" "")]) 13707 (match_operand 3 "" "") 13708 (match_operand 4 "" ""))) 13709 (clobber (reg:CCFP FPSR_REG)) 13710 (clobber (reg:CCFP FLAGS_REG))] 13711 "reload_completed" 13712 [(const_int 0)] 13713{ 13714 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 13715 operands[3], operands[4], NULL_RTX, NULL_RTX); 13716 DONE; 13717}) 13718 13719(define_split 13720 [(set (pc) 13721 (if_then_else (match_operator 0 "comparison_operator" 13722 [(match_operand 1 "register_operand" "") 13723 (match_operand 2 "general_operand" "")]) 13724 (match_operand 3 "" "") 13725 (match_operand 4 "" ""))) 13726 (clobber (reg:CCFP FPSR_REG)) 13727 (clobber (reg:CCFP FLAGS_REG)) 13728 (clobber (match_scratch:HI 5 "=a"))] 13729 "reload_completed" 13730 [(const_int 0)] 13731{ 13732 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 13733 operands[3], operands[4], operands[5], NULL_RTX); 13734 DONE; 13735}) 13736 13737(define_split 13738 [(set (pc) 13739 (if_then_else (match_operator 0 "comparison_operator" 13740 [(match_operator 1 "float_operator" 13741 [(match_operand:X87MODEI12 2 "memory_operand" "")]) 13742 (match_operand 3 "register_operand" "")]) 13743 (match_operand 4 "" "") 13744 (match_operand 5 "" ""))) 13745 (clobber (reg:CCFP FPSR_REG)) 13746 (clobber (reg:CCFP FLAGS_REG)) 13747 (clobber (match_scratch:HI 6 "=a"))] 13748 "reload_completed" 13749 [(const_int 0)] 13750{ 13751 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]); 13752 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), 13753 operands[3], operands[7], 13754 operands[4], operands[5], operands[6], NULL_RTX); 13755 DONE; 13756}) 13757 13758;; %%% Kill this when reload knows how to do it. 13759(define_split 13760 [(set (pc) 13761 (if_then_else (match_operator 0 "comparison_operator" 13762 [(match_operator 1 "float_operator" 13763 [(match_operand:X87MODEI12 2 "register_operand" "")]) 13764 (match_operand 3 "register_operand" "")]) 13765 (match_operand 4 "" "") 13766 (match_operand 5 "" ""))) 13767 (clobber (reg:CCFP FPSR_REG)) 13768 (clobber (reg:CCFP FLAGS_REG)) 13769 (clobber (match_scratch:HI 6 "=a"))] 13770 "reload_completed" 13771 [(const_int 0)] 13772{ 13773 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); 13774 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]); 13775 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), 13776 operands[3], operands[7], 13777 operands[4], operands[5], operands[6], operands[2]); 13778 DONE; 13779}) 13780 13781;; Unconditional and other jump instructions 13782 13783(define_insn "jump" 13784 [(set (pc) 13785 (label_ref (match_operand 0 "" "")))] 13786 "" 13787 "jmp\t%l0" 13788 [(set_attr "type" "ibr") 13789 (set (attr "length") 13790 (if_then_else (and (ge (minus (match_dup 0) (pc)) 13791 (const_int -126)) 13792 (lt (minus (match_dup 0) (pc)) 13793 (const_int 128))) 13794 (const_int 2) 13795 (const_int 5))) 13796 (set_attr "modrm" "0")]) 13797 13798(define_expand "indirect_jump" 13799 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))] 13800 "" 13801 "") 13802 13803(define_insn "*indirect_jump" 13804 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))] 13805 "!TARGET_64BIT" 13806 "jmp\t%A0" 13807 [(set_attr "type" "ibr") 13808 (set_attr "length_immediate" "0")]) 13809 13810(define_insn "*indirect_jump_rtx64" 13811 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))] 13812 "TARGET_64BIT" 13813 "jmp\t%A0" 13814 [(set_attr "type" "ibr") 13815 (set_attr "length_immediate" "0")]) 13816 13817(define_expand "tablejump" 13818 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm")) 13819 (use (label_ref (match_operand 1 "" "")))])] 13820 "" 13821{ 13822 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit) 13823 relative. Convert the relative address to an absolute address. */ 13824 if (flag_pic) 13825 { 13826 rtx op0, op1; 13827 enum rtx_code code; 13828 13829 if (TARGET_64BIT) 13830 { 13831 code = PLUS; 13832 op0 = operands[0]; 13833 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]); 13834 } 13835 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA) 13836 { 13837 code = PLUS; 13838 op0 = operands[0]; 13839 op1 = pic_offset_table_rtx; 13840 } 13841 else 13842 { 13843 code = MINUS; 13844 op0 = pic_offset_table_rtx; 13845 op1 = operands[0]; 13846 } 13847 13848 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0, 13849 OPTAB_DIRECT); 13850 } 13851}) 13852 13853(define_insn "*tablejump_1" 13854 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm")) 13855 (use (label_ref (match_operand 1 "" "")))] 13856 "!TARGET_64BIT" 13857 "jmp\t%A0" 13858 [(set_attr "type" "ibr") 13859 (set_attr "length_immediate" "0")]) 13860 13861(define_insn "*tablejump_1_rtx64" 13862 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm")) 13863 (use (label_ref (match_operand 1 "" "")))] 13864 "TARGET_64BIT" 13865 "jmp\t%A0" 13866 [(set_attr "type" "ibr") 13867 (set_attr "length_immediate" "0")]) 13868 13869;; Convert setcc + movzbl to xor + setcc if operands don't overlap. 13870 13871(define_peephole2 13872 [(set (reg FLAGS_REG) (match_operand 0 "" "")) 13873 (set (match_operand:QI 1 "register_operand" "") 13874 (match_operator:QI 2 "ix86_comparison_operator" 13875 [(reg FLAGS_REG) (const_int 0)])) 13876 (set (match_operand 3 "q_regs_operand" "") 13877 (zero_extend (match_dup 1)))] 13878 "(peep2_reg_dead_p (3, operands[1]) 13879 || operands_match_p (operands[1], operands[3])) 13880 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 13881 [(set (match_dup 4) (match_dup 0)) 13882 (set (strict_low_part (match_dup 5)) 13883 (match_dup 2))] 13884{ 13885 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 13886 operands[5] = gen_lowpart (QImode, operands[3]); 13887 ix86_expand_clear (operands[3]); 13888}) 13889 13890;; Similar, but match zero_extendhisi2_and, which adds a clobber. 13891 13892(define_peephole2 13893 [(set (reg FLAGS_REG) (match_operand 0 "" "")) 13894 (set (match_operand:QI 1 "register_operand" "") 13895 (match_operator:QI 2 "ix86_comparison_operator" 13896 [(reg FLAGS_REG) (const_int 0)])) 13897 (parallel [(set (match_operand 3 "q_regs_operand" "") 13898 (zero_extend (match_dup 1))) 13899 (clobber (reg:CC FLAGS_REG))])] 13900 "(peep2_reg_dead_p (3, operands[1]) 13901 || operands_match_p (operands[1], operands[3])) 13902 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 13903 [(set (match_dup 4) (match_dup 0)) 13904 (set (strict_low_part (match_dup 5)) 13905 (match_dup 2))] 13906{ 13907 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 13908 operands[5] = gen_lowpart (QImode, operands[3]); 13909 ix86_expand_clear (operands[3]); 13910}) 13911 13912;; Call instructions. 13913 13914;; The predicates normally associated with named expanders are not properly 13915;; checked for calls. This is a bug in the generic code, but it isn't that 13916;; easy to fix. Ignore it for now and be prepared to fix things up. 13917 13918;; Call subroutine returning no value. 13919 13920(define_expand "call_pop" 13921 [(parallel [(call (match_operand:QI 0 "" "") 13922 (match_operand:SI 1 "" "")) 13923 (set (reg:SI SP_REG) 13924 (plus:SI (reg:SI SP_REG) 13925 (match_operand:SI 3 "" "")))])] 13926 "!TARGET_64BIT" 13927{ 13928 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0); 13929 DONE; 13930}) 13931 13932(define_insn "*call_pop_0" 13933 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" "")) 13934 (match_operand:SI 1 "" "")) 13935 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 13936 (match_operand:SI 2 "immediate_operand" "")))] 13937 "!TARGET_64BIT" 13938{ 13939 if (SIBLING_CALL_P (insn)) 13940 return "jmp\t%P0"; 13941 else 13942 return "call\t%P0"; 13943} 13944 [(set_attr "type" "call")]) 13945 13946(define_insn "*call_pop_1" 13947 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm")) 13948 (match_operand:SI 1 "" "")) 13949 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 13950 (match_operand:SI 2 "immediate_operand" "i")))] 13951 "!TARGET_64BIT" 13952{ 13953 if (constant_call_address_operand (operands[0], Pmode)) 13954 { 13955 if (SIBLING_CALL_P (insn)) 13956 return "jmp\t%P0"; 13957 else 13958 return "call\t%P0"; 13959 } 13960 if (SIBLING_CALL_P (insn)) 13961 return "jmp\t%A0"; 13962 else 13963 return "call\t%A0"; 13964} 13965 [(set_attr "type" "call")]) 13966 13967(define_expand "call" 13968 [(call (match_operand:QI 0 "" "") 13969 (match_operand 1 "" "")) 13970 (use (match_operand 2 "" ""))] 13971 "" 13972{ 13973 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0); 13974 DONE; 13975}) 13976 13977(define_expand "sibcall" 13978 [(call (match_operand:QI 0 "" "") 13979 (match_operand 1 "" "")) 13980 (use (match_operand 2 "" ""))] 13981 "" 13982{ 13983 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1); 13984 DONE; 13985}) 13986 13987(define_insn "*call_0" 13988 [(call (mem:QI (match_operand 0 "constant_call_address_operand" "")) 13989 (match_operand 1 "" ""))] 13990 "" 13991{ 13992 if (SIBLING_CALL_P (insn)) 13993 return "jmp\t%P0"; 13994 else 13995 return "call\t%P0"; 13996} 13997 [(set_attr "type" "call")]) 13998 13999(define_insn "*call_1" 14000 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm")) 14001 (match_operand 1 "" ""))] 14002 "!SIBLING_CALL_P (insn) && !TARGET_64BIT" 14003{ 14004 if (constant_call_address_operand (operands[0], Pmode)) 14005 return "call\t%P0"; 14006 return "call\t%A0"; 14007} 14008 [(set_attr "type" "call")]) 14009 14010(define_insn "*sibcall_1" 14011 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a")) 14012 (match_operand 1 "" ""))] 14013 "SIBLING_CALL_P (insn) && !TARGET_64BIT" 14014{ 14015 if (constant_call_address_operand (operands[0], Pmode)) 14016 return "jmp\t%P0"; 14017 return "jmp\t%A0"; 14018} 14019 [(set_attr "type" "call")]) 14020 14021(define_insn "*call_1_rex64" 14022 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm")) 14023 (match_operand 1 "" ""))] 14024 "!SIBLING_CALL_P (insn) && TARGET_64BIT" 14025{ 14026 if (constant_call_address_operand (operands[0], Pmode)) 14027 return "call\t%P0"; 14028 return "call\t%A0"; 14029} 14030 [(set_attr "type" "call")]) 14031 14032(define_insn "*sibcall_1_rex64" 14033 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" "")) 14034 (match_operand 1 "" ""))] 14035 "SIBLING_CALL_P (insn) && TARGET_64BIT" 14036 "jmp\t%P0" 14037 [(set_attr "type" "call")]) 14038 14039(define_insn "*sibcall_1_rex64_v" 14040 [(call (mem:QI (reg:DI 40)) 14041 (match_operand 0 "" ""))] 14042 "SIBLING_CALL_P (insn) && TARGET_64BIT" 14043 "jmp\t*%%r11" 14044 [(set_attr "type" "call")]) 14045 14046 14047;; Call subroutine, returning value in operand 0 14048 14049(define_expand "call_value_pop" 14050 [(parallel [(set (match_operand 0 "" "") 14051 (call (match_operand:QI 1 "" "") 14052 (match_operand:SI 2 "" ""))) 14053 (set (reg:SI SP_REG) 14054 (plus:SI (reg:SI SP_REG) 14055 (match_operand:SI 4 "" "")))])] 14056 "!TARGET_64BIT" 14057{ 14058 ix86_expand_call (operands[0], operands[1], operands[2], 14059 operands[3], operands[4], 0); 14060 DONE; 14061}) 14062 14063(define_expand "call_value" 14064 [(set (match_operand 0 "" "") 14065 (call (match_operand:QI 1 "" "") 14066 (match_operand:SI 2 "" ""))) 14067 (use (match_operand:SI 3 "" ""))] 14068 ;; Operand 2 not used on the i386. 14069 "" 14070{ 14071 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0); 14072 DONE; 14073}) 14074 14075(define_expand "sibcall_value" 14076 [(set (match_operand 0 "" "") 14077 (call (match_operand:QI 1 "" "") 14078 (match_operand:SI 2 "" ""))) 14079 (use (match_operand:SI 3 "" ""))] 14080 ;; Operand 2 not used on the i386. 14081 "" 14082{ 14083 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1); 14084 DONE; 14085}) 14086 14087;; Call subroutine returning any type. 14088 14089(define_expand "untyped_call" 14090 [(parallel [(call (match_operand 0 "" "") 14091 (const_int 0)) 14092 (match_operand 1 "" "") 14093 (match_operand 2 "" "")])] 14094 "" 14095{ 14096 int i; 14097 14098 /* In order to give reg-stack an easier job in validating two 14099 coprocessor registers as containing a possible return value, 14100 simply pretend the untyped call returns a complex long double 14101 value. */ 14102 14103 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387 14104 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL), 14105 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1), 14106 NULL, 0); 14107 14108 for (i = 0; i < XVECLEN (operands[2], 0); i++) 14109 { 14110 rtx set = XVECEXP (operands[2], 0, i); 14111 emit_move_insn (SET_DEST (set), SET_SRC (set)); 14112 } 14113 14114 /* The optimizer does not know that the call sets the function value 14115 registers we stored in the result block. We avoid problems by 14116 claiming that all hard registers are used and clobbered at this 14117 point. */ 14118 emit_insn (gen_blockage (const0_rtx)); 14119 14120 DONE; 14121}) 14122 14123;; Prologue and epilogue instructions 14124 14125;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 14126;; all of memory. This blocks insns from being moved across this point. 14127 14128(define_insn "blockage" 14129 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)] 14130 "" 14131 "" 14132 [(set_attr "length" "0")]) 14133 14134;; Insn emitted into the body of a function to return from a function. 14135;; This is only done if the function's epilogue is known to be simple. 14136;; See comments for ix86_can_use_return_insn_p in i386.c. 14137 14138(define_expand "return" 14139 [(return)] 14140 "ix86_can_use_return_insn_p ()" 14141{ 14142 if (current_function_pops_args) 14143 { 14144 rtx popc = GEN_INT (current_function_pops_args); 14145 emit_jump_insn (gen_return_pop_internal (popc)); 14146 DONE; 14147 } 14148}) 14149 14150(define_insn "return_internal" 14151 [(return)] 14152 "reload_completed" 14153 "ret" 14154 [(set_attr "length" "1") 14155 (set_attr "length_immediate" "0") 14156 (set_attr "modrm" "0")]) 14157 14158;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET 14159;; instruction Athlon and K8 have. 14160 14161(define_insn "return_internal_long" 14162 [(return) 14163 (unspec [(const_int 0)] UNSPEC_REP)] 14164 "reload_completed" 14165 "rep {;} ret" 14166 [(set_attr "length" "1") 14167 (set_attr "length_immediate" "0") 14168 (set_attr "prefix_rep" "1") 14169 (set_attr "modrm" "0")]) 14170 14171(define_insn "return_pop_internal" 14172 [(return) 14173 (use (match_operand:SI 0 "const_int_operand" ""))] 14174 "reload_completed" 14175 "ret\t%0" 14176 [(set_attr "length" "3") 14177 (set_attr "length_immediate" "2") 14178 (set_attr "modrm" "0")]) 14179 14180(define_insn "return_indirect_internal" 14181 [(return) 14182 (use (match_operand:SI 0 "register_operand" "r"))] 14183 "reload_completed" 14184 "jmp\t%A0" 14185 [(set_attr "type" "ibr") 14186 (set_attr "length_immediate" "0")]) 14187 14188(define_insn "nop" 14189 [(const_int 0)] 14190 "" 14191 "nop" 14192 [(set_attr "length" "1") 14193 (set_attr "length_immediate" "0") 14194 (set_attr "modrm" "0")]) 14195 14196;; Align to 16-byte boundary, max skip in op0. Used to avoid 14197;; branch prediction penalty for the third jump in a 16-byte 14198;; block on K8. 14199 14200(define_insn "align" 14201 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)] 14202 "" 14203{ 14204#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN 14205 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0])); 14206#else 14207 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that. 14208 The align insn is used to avoid 3 jump instructions in the row to improve 14209 branch prediction and the benefits hardly outweight the cost of extra 8 14210 nops on the average inserted by full alignment pseudo operation. */ 14211#endif 14212 return ""; 14213} 14214 [(set_attr "length" "16")]) 14215 14216(define_expand "prologue" 14217 [(const_int 1)] 14218 "" 14219 "ix86_expand_prologue (); DONE;") 14220 14221(define_insn "set_got" 14222 [(set (match_operand:SI 0 "register_operand" "=r") 14223 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 14224 (clobber (reg:CC FLAGS_REG))] 14225 "!TARGET_64BIT" 14226 { return output_set_got (operands[0]); } 14227 [(set_attr "type" "multi") 14228 (set_attr "length" "12")]) 14229 14230(define_insn "set_got_rex64" 14231 [(set (match_operand:DI 0 "register_operand" "=r") 14232 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))] 14233 "TARGET_64BIT" 14234 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0" 14235 [(set_attr "type" "lea") 14236 (set_attr "length" "6")]) 14237 14238(define_expand "epilogue" 14239 [(const_int 1)] 14240 "" 14241 "ix86_expand_epilogue (1); DONE;") 14242 14243(define_expand "sibcall_epilogue" 14244 [(const_int 1)] 14245 "" 14246 "ix86_expand_epilogue (0); DONE;") 14247 14248(define_expand "eh_return" 14249 [(use (match_operand 0 "register_operand" ""))] 14250 "" 14251{ 14252 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0]; 14253 14254 /* Tricky bit: we write the address of the handler to which we will 14255 be returning into someone else's stack frame, one word below the 14256 stack address we wish to restore. */ 14257 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa); 14258 tmp = plus_constant (tmp, -UNITS_PER_WORD); 14259 tmp = gen_rtx_MEM (Pmode, tmp); 14260 emit_move_insn (tmp, ra); 14261 14262 if (Pmode == SImode) 14263 emit_jump_insn (gen_eh_return_si (sa)); 14264 else 14265 emit_jump_insn (gen_eh_return_di (sa)); 14266 emit_barrier (); 14267 DONE; 14268}) 14269 14270(define_insn_and_split "eh_return_si" 14271 [(set (pc) 14272 (unspec [(match_operand:SI 0 "register_operand" "c")] 14273 UNSPEC_EH_RETURN))] 14274 "!TARGET_64BIT" 14275 "#" 14276 "reload_completed" 14277 [(const_int 1)] 14278 "ix86_expand_epilogue (2); DONE;") 14279 14280(define_insn_and_split "eh_return_di" 14281 [(set (pc) 14282 (unspec [(match_operand:DI 0 "register_operand" "c")] 14283 UNSPEC_EH_RETURN))] 14284 "TARGET_64BIT" 14285 "#" 14286 "reload_completed" 14287 [(const_int 1)] 14288 "ix86_expand_epilogue (2); DONE;") 14289 14290(define_insn "leave" 14291 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4))) 14292 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG))) 14293 (clobber (mem:BLK (scratch)))] 14294 "!TARGET_64BIT" 14295 "leave" 14296 [(set_attr "type" "leave")]) 14297 14298(define_insn "leave_rex64" 14299 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8))) 14300 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG))) 14301 (clobber (mem:BLK (scratch)))] 14302 "TARGET_64BIT" 14303 "leave" 14304 [(set_attr "type" "leave")]) 14305 14306(define_expand "ffssi2" 14307 [(parallel 14308 [(set (match_operand:SI 0 "register_operand" "") 14309 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" ""))) 14310 (clobber (match_scratch:SI 2 "")) 14311 (clobber (reg:CC FLAGS_REG))])] 14312 "" 14313 "") 14314 14315(define_insn_and_split "*ffs_cmove" 14316 [(set (match_operand:SI 0 "register_operand" "=r") 14317 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 14318 (clobber (match_scratch:SI 2 "=&r")) 14319 (clobber (reg:CC FLAGS_REG))] 14320 "TARGET_CMOVE" 14321 "#" 14322 "&& reload_completed" 14323 [(set (match_dup 2) (const_int -1)) 14324 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0))) 14325 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 14326 (set (match_dup 0) (if_then_else:SI 14327 (eq (reg:CCZ FLAGS_REG) (const_int 0)) 14328 (match_dup 2) 14329 (match_dup 0))) 14330 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 14331 (clobber (reg:CC FLAGS_REG))])] 14332 "") 14333 14334(define_insn_and_split "*ffs_no_cmove" 14335 [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 14336 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 14337 (clobber (match_scratch:SI 2 "=&q")) 14338 (clobber (reg:CC FLAGS_REG))] 14339 "" 14340 "#" 14341 "reload_completed" 14342 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0))) 14343 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 14344 (set (strict_low_part (match_dup 3)) 14345 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0))) 14346 (parallel [(set (match_dup 2) (neg:SI (match_dup 2))) 14347 (clobber (reg:CC FLAGS_REG))]) 14348 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2))) 14349 (clobber (reg:CC FLAGS_REG))]) 14350 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 14351 (clobber (reg:CC FLAGS_REG))])] 14352{ 14353 operands[3] = gen_lowpart (QImode, operands[2]); 14354 ix86_expand_clear (operands[2]); 14355}) 14356 14357(define_insn "*ffssi_1" 14358 [(set (reg:CCZ FLAGS_REG) 14359 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm") 14360 (const_int 0))) 14361 (set (match_operand:SI 0 "register_operand" "=r") 14362 (ctz:SI (match_dup 1)))] 14363 "" 14364 "bsf{l}\t{%1, %0|%0, %1}" 14365 [(set_attr "prefix_0f" "1")]) 14366 14367(define_expand "ffsdi2" 14368 [(parallel 14369 [(set (match_operand:DI 0 "register_operand" "") 14370 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" ""))) 14371 (clobber (match_scratch:DI 2 "")) 14372 (clobber (reg:CC FLAGS_REG))])] 14373 "TARGET_64BIT && TARGET_CMOVE" 14374 "") 14375 14376(define_insn_and_split "*ffs_rex64" 14377 [(set (match_operand:DI 0 "register_operand" "=r") 14378 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))) 14379 (clobber (match_scratch:DI 2 "=&r")) 14380 (clobber (reg:CC FLAGS_REG))] 14381 "TARGET_64BIT && TARGET_CMOVE" 14382 "#" 14383 "&& reload_completed" 14384 [(set (match_dup 2) (const_int -1)) 14385 (parallel [(set (reg:CCZ FLAGS_REG) 14386 (compare:CCZ (match_dup 1) (const_int 0))) 14387 (set (match_dup 0) (ctz:DI (match_dup 1)))]) 14388 (set (match_dup 0) (if_then_else:DI 14389 (eq (reg:CCZ FLAGS_REG) (const_int 0)) 14390 (match_dup 2) 14391 (match_dup 0))) 14392 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1))) 14393 (clobber (reg:CC FLAGS_REG))])] 14394 "") 14395 14396(define_insn "*ffsdi_1" 14397 [(set (reg:CCZ FLAGS_REG) 14398 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm") 14399 (const_int 0))) 14400 (set (match_operand:DI 0 "register_operand" "=r") 14401 (ctz:DI (match_dup 1)))] 14402 "TARGET_64BIT" 14403 "bsf{q}\t{%1, %0|%0, %1}" 14404 [(set_attr "prefix_0f" "1")]) 14405 14406(define_insn "ctzsi2" 14407 [(set (match_operand:SI 0 "register_operand" "=r") 14408 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 14409 (clobber (reg:CC FLAGS_REG))] 14410 "" 14411 "bsf{l}\t{%1, %0|%0, %1}" 14412 [(set_attr "prefix_0f" "1")]) 14413 14414(define_insn "ctzdi2" 14415 [(set (match_operand:DI 0 "register_operand" "=r") 14416 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))) 14417 (clobber (reg:CC FLAGS_REG))] 14418 "TARGET_64BIT" 14419 "bsf{q}\t{%1, %0|%0, %1}" 14420 [(set_attr "prefix_0f" "1")]) 14421 14422(define_expand "clzsi2" 14423 [(parallel 14424 [(set (match_operand:SI 0 "register_operand" "") 14425 (minus:SI (const_int 31) 14426 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))) 14427 (clobber (reg:CC FLAGS_REG))]) 14428 (parallel 14429 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31))) 14430 (clobber (reg:CC FLAGS_REG))])] 14431 "" 14432 "") 14433 14434(define_insn "*bsr" 14435 [(set (match_operand:SI 0 "register_operand" "=r") 14436 (minus:SI (const_int 31) 14437 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))) 14438 (clobber (reg:CC FLAGS_REG))] 14439 "" 14440 "bsr{l}\t{%1, %0|%0, %1}" 14441 [(set_attr "prefix_0f" "1")]) 14442 14443(define_expand "clzdi2" 14444 [(parallel 14445 [(set (match_operand:DI 0 "register_operand" "") 14446 (minus:DI (const_int 63) 14447 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))) 14448 (clobber (reg:CC FLAGS_REG))]) 14449 (parallel 14450 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63))) 14451 (clobber (reg:CC FLAGS_REG))])] 14452 "TARGET_64BIT" 14453 "") 14454 14455(define_insn "*bsr_rex64" 14456 [(set (match_operand:DI 0 "register_operand" "=r") 14457 (minus:DI (const_int 63) 14458 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) 14459 (clobber (reg:CC FLAGS_REG))] 14460 "TARGET_64BIT" 14461 "bsr{q}\t{%1, %0|%0, %1}" 14462 [(set_attr "prefix_0f" "1")]) 14463 14464;; Thread-local storage patterns for ELF. 14465;; 14466;; Note that these code sequences must appear exactly as shown 14467;; in order to allow linker relaxation. 14468 14469(define_insn "*tls_global_dynamic_32_gnu" 14470 [(set (match_operand:SI 0 "register_operand" "=a") 14471 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14472 (match_operand:SI 2 "tls_symbolic_operand" "") 14473 (match_operand:SI 3 "call_insn_operand" "")] 14474 UNSPEC_TLS_GD)) 14475 (clobber (match_scratch:SI 4 "=d")) 14476 (clobber (match_scratch:SI 5 "=c")) 14477 (clobber (reg:CC FLAGS_REG))] 14478 "!TARGET_64BIT && TARGET_GNU_TLS" 14479 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3" 14480 [(set_attr "type" "multi") 14481 (set_attr "length" "12")]) 14482 14483(define_insn "*tls_global_dynamic_32_sun" 14484 [(set (match_operand:SI 0 "register_operand" "=a") 14485 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14486 (match_operand:SI 2 "tls_symbolic_operand" "") 14487 (match_operand:SI 3 "call_insn_operand" "")] 14488 UNSPEC_TLS_GD)) 14489 (clobber (match_scratch:SI 4 "=d")) 14490 (clobber (match_scratch:SI 5 "=c")) 14491 (clobber (reg:CC FLAGS_REG))] 14492 "!TARGET_64BIT && TARGET_SUN_TLS" 14493 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]} 14494 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop" 14495 [(set_attr "type" "multi") 14496 (set_attr "length" "14")]) 14497 14498(define_expand "tls_global_dynamic_32" 14499 [(parallel [(set (match_operand:SI 0 "register_operand" "") 14500 (unspec:SI 14501 [(match_dup 2) 14502 (match_operand:SI 1 "tls_symbolic_operand" "") 14503 (match_dup 3)] 14504 UNSPEC_TLS_GD)) 14505 (clobber (match_scratch:SI 4 "")) 14506 (clobber (match_scratch:SI 5 "")) 14507 (clobber (reg:CC FLAGS_REG))])] 14508 "" 14509{ 14510 if (flag_pic) 14511 operands[2] = pic_offset_table_rtx; 14512 else 14513 { 14514 operands[2] = gen_reg_rtx (Pmode); 14515 emit_insn (gen_set_got (operands[2])); 14516 } 14517 operands[3] = ix86_tls_get_addr (); 14518}) 14519 14520(define_insn "*tls_global_dynamic_64" 14521 [(set (match_operand:DI 0 "register_operand" "=a") 14522 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" "")) 14523 (match_operand:DI 3 "" ""))) 14524 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 14525 UNSPEC_TLS_GD)] 14526 "TARGET_64BIT" 14527 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2" 14528 [(set_attr "type" "multi") 14529 (set_attr "length" "16")]) 14530 14531(define_expand "tls_global_dynamic_64" 14532 [(parallel [(set (match_operand:DI 0 "register_operand" "") 14533 (call:DI (mem:QI (match_dup 2)) (const_int 0))) 14534 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 14535 UNSPEC_TLS_GD)])] 14536 "" 14537{ 14538 operands[2] = ix86_tls_get_addr (); 14539}) 14540 14541(define_insn "*tls_local_dynamic_base_32_gnu" 14542 [(set (match_operand:SI 0 "register_operand" "=a") 14543 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14544 (match_operand:SI 2 "call_insn_operand" "")] 14545 UNSPEC_TLS_LD_BASE)) 14546 (clobber (match_scratch:SI 3 "=d")) 14547 (clobber (match_scratch:SI 4 "=c")) 14548 (clobber (reg:CC FLAGS_REG))] 14549 "!TARGET_64BIT && TARGET_GNU_TLS" 14550 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2" 14551 [(set_attr "type" "multi") 14552 (set_attr "length" "11")]) 14553 14554(define_insn "*tls_local_dynamic_base_32_sun" 14555 [(set (match_operand:SI 0 "register_operand" "=a") 14556 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14557 (match_operand:SI 2 "call_insn_operand" "")] 14558 UNSPEC_TLS_LD_BASE)) 14559 (clobber (match_scratch:SI 3 "=d")) 14560 (clobber (match_scratch:SI 4 "=c")) 14561 (clobber (reg:CC FLAGS_REG))] 14562 "!TARGET_64BIT && TARGET_SUN_TLS" 14563 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]} 14564 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3" 14565 [(set_attr "type" "multi") 14566 (set_attr "length" "13")]) 14567 14568(define_expand "tls_local_dynamic_base_32" 14569 [(parallel [(set (match_operand:SI 0 "register_operand" "") 14570 (unspec:SI [(match_dup 1) (match_dup 2)] 14571 UNSPEC_TLS_LD_BASE)) 14572 (clobber (match_scratch:SI 3 "")) 14573 (clobber (match_scratch:SI 4 "")) 14574 (clobber (reg:CC FLAGS_REG))])] 14575 "" 14576{ 14577 if (flag_pic) 14578 operands[1] = pic_offset_table_rtx; 14579 else 14580 { 14581 operands[1] = gen_reg_rtx (Pmode); 14582 emit_insn (gen_set_got (operands[1])); 14583 } 14584 operands[2] = ix86_tls_get_addr (); 14585}) 14586 14587(define_insn "*tls_local_dynamic_base_64" 14588 [(set (match_operand:DI 0 "register_operand" "=a") 14589 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" "")) 14590 (match_operand:DI 2 "" ""))) 14591 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)] 14592 "TARGET_64BIT" 14593 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1" 14594 [(set_attr "type" "multi") 14595 (set_attr "length" "12")]) 14596 14597(define_expand "tls_local_dynamic_base_64" 14598 [(parallel [(set (match_operand:DI 0 "register_operand" "") 14599 (call:DI (mem:QI (match_dup 1)) (const_int 0))) 14600 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])] 14601 "" 14602{ 14603 operands[1] = ix86_tls_get_addr (); 14604}) 14605 14606;; Local dynamic of a single variable is a lose. Show combine how 14607;; to convert that back to global dynamic. 14608 14609(define_insn_and_split "*tls_local_dynamic_32_once" 14610 [(set (match_operand:SI 0 "register_operand" "=a") 14611 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14612 (match_operand:SI 2 "call_insn_operand" "")] 14613 UNSPEC_TLS_LD_BASE) 14614 (const:SI (unspec:SI 14615 [(match_operand:SI 3 "tls_symbolic_operand" "")] 14616 UNSPEC_DTPOFF)))) 14617 (clobber (match_scratch:SI 4 "=d")) 14618 (clobber (match_scratch:SI 5 "=c")) 14619 (clobber (reg:CC FLAGS_REG))] 14620 "" 14621 "#" 14622 "" 14623 [(parallel [(set (match_dup 0) 14624 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)] 14625 UNSPEC_TLS_GD)) 14626 (clobber (match_dup 4)) 14627 (clobber (match_dup 5)) 14628 (clobber (reg:CC FLAGS_REG))])] 14629 "") 14630 14631;; Load and add the thread base pointer from %gs:0. 14632 14633(define_insn "*load_tp_si" 14634 [(set (match_operand:SI 0 "register_operand" "=r") 14635 (unspec:SI [(const_int 0)] UNSPEC_TP))] 14636 "!TARGET_64BIT" 14637 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}" 14638 [(set_attr "type" "imov") 14639 (set_attr "modrm" "0") 14640 (set_attr "length" "7") 14641 (set_attr "memory" "load") 14642 (set_attr "imm_disp" "false")]) 14643 14644(define_insn "*add_tp_si" 14645 [(set (match_operand:SI 0 "register_operand" "=r") 14646 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) 14647 (match_operand:SI 1 "register_operand" "0"))) 14648 (clobber (reg:CC FLAGS_REG))] 14649 "!TARGET_64BIT" 14650 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}" 14651 [(set_attr "type" "alu") 14652 (set_attr "modrm" "0") 14653 (set_attr "length" "7") 14654 (set_attr "memory" "load") 14655 (set_attr "imm_disp" "false")]) 14656 14657(define_insn "*load_tp_di" 14658 [(set (match_operand:DI 0 "register_operand" "=r") 14659 (unspec:DI [(const_int 0)] UNSPEC_TP))] 14660 "TARGET_64BIT" 14661 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}" 14662 [(set_attr "type" "imov") 14663 (set_attr "modrm" "0") 14664 (set_attr "length" "7") 14665 (set_attr "memory" "load") 14666 (set_attr "imm_disp" "false")]) 14667 14668(define_insn "*add_tp_di" 14669 [(set (match_operand:DI 0 "register_operand" "=r") 14670 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP) 14671 (match_operand:DI 1 "register_operand" "0"))) 14672 (clobber (reg:CC FLAGS_REG))] 14673 "TARGET_64BIT" 14674 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}" 14675 [(set_attr "type" "alu") 14676 (set_attr "modrm" "0") 14677 (set_attr "length" "7") 14678 (set_attr "memory" "load") 14679 (set_attr "imm_disp" "false")]) 14680 14681;; These patterns match the binary 387 instructions for addM3, subM3, 14682;; mulM3 and divM3. There are three patterns for each of DFmode and 14683;; SFmode. The first is the normal insn, the second the same insn but 14684;; with one operand a conversion, and the third the same insn but with 14685;; the other operand a conversion. The conversion may be SFmode or 14686;; SImode if the target mode DFmode, but only SImode if the target mode 14687;; is SFmode. 14688 14689;; Gcc is slightly more smart about handling normal two address instructions 14690;; so use special patterns for add and mull. 14691 14692(define_insn "*fop_sf_comm_mixed" 14693 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f") 14694 (match_operator:SF 3 "binary_fp_operator" 14695 [(match_operand:SF 1 "nonimmediate_operand" "%0,0") 14696 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))] 14697 "TARGET_MIX_SSE_I387 14698 && COMMUTATIVE_ARITH_P (operands[3]) 14699 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 14700 "* return output_387_binary_op (insn, operands);" 14701 [(set (attr "type") 14702 (if_then_else (eq_attr "alternative" "1") 14703 (if_then_else (match_operand:SF 3 "mult_operator" "") 14704 (const_string "ssemul") 14705 (const_string "sseadd")) 14706 (if_then_else (match_operand:SF 3 "mult_operator" "") 14707 (const_string "fmul") 14708 (const_string "fop")))) 14709 (set_attr "mode" "SF")]) 14710 14711(define_insn "*fop_sf_comm_sse" 14712 [(set (match_operand:SF 0 "register_operand" "=x") 14713 (match_operator:SF 3 "binary_fp_operator" 14714 [(match_operand:SF 1 "nonimmediate_operand" "%0") 14715 (match_operand:SF 2 "nonimmediate_operand" "xm")]))] 14716 "TARGET_SSE_MATH 14717 && COMMUTATIVE_ARITH_P (operands[3]) 14718 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 14719 "* return output_387_binary_op (insn, operands);" 14720 [(set (attr "type") 14721 (if_then_else (match_operand:SF 3 "mult_operator" "") 14722 (const_string "ssemul") 14723 (const_string "sseadd"))) 14724 (set_attr "mode" "SF")]) 14725 14726(define_insn "*fop_sf_comm_i387" 14727 [(set (match_operand:SF 0 "register_operand" "=f") 14728 (match_operator:SF 3 "binary_fp_operator" 14729 [(match_operand:SF 1 "nonimmediate_operand" "%0") 14730 (match_operand:SF 2 "nonimmediate_operand" "fm")]))] 14731 "TARGET_80387 14732 && COMMUTATIVE_ARITH_P (operands[3]) 14733 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 14734 "* return output_387_binary_op (insn, operands);" 14735 [(set (attr "type") 14736 (if_then_else (match_operand:SF 3 "mult_operator" "") 14737 (const_string "fmul") 14738 (const_string "fop"))) 14739 (set_attr "mode" "SF")]) 14740 14741(define_insn "*fop_sf_1_mixed" 14742 [(set (match_operand:SF 0 "register_operand" "=f,f,x") 14743 (match_operator:SF 3 "binary_fp_operator" 14744 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0") 14745 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))] 14746 "TARGET_MIX_SSE_I387 14747 && !COMMUTATIVE_ARITH_P (operands[3]) 14748 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 14749 "* return output_387_binary_op (insn, operands);" 14750 [(set (attr "type") 14751 (cond [(and (eq_attr "alternative" "2") 14752 (match_operand:SF 3 "mult_operator" "")) 14753 (const_string "ssemul") 14754 (and (eq_attr "alternative" "2") 14755 (match_operand:SF 3 "div_operator" "")) 14756 (const_string "ssediv") 14757 (eq_attr "alternative" "2") 14758 (const_string "sseadd") 14759 (match_operand:SF 3 "mult_operator" "") 14760 (const_string "fmul") 14761 (match_operand:SF 3 "div_operator" "") 14762 (const_string "fdiv") 14763 ] 14764 (const_string "fop"))) 14765 (set_attr "mode" "SF")]) 14766 14767(define_insn "*fop_sf_1_sse" 14768 [(set (match_operand:SF 0 "register_operand" "=x") 14769 (match_operator:SF 3 "binary_fp_operator" 14770 [(match_operand:SF 1 "register_operand" "0") 14771 (match_operand:SF 2 "nonimmediate_operand" "xm")]))] 14772 "TARGET_SSE_MATH 14773 && !COMMUTATIVE_ARITH_P (operands[3])" 14774 "* return output_387_binary_op (insn, operands);" 14775 [(set (attr "type") 14776 (cond [(match_operand:SF 3 "mult_operator" "") 14777 (const_string "ssemul") 14778 (match_operand:SF 3 "div_operator" "") 14779 (const_string "ssediv") 14780 ] 14781 (const_string "sseadd"))) 14782 (set_attr "mode" "SF")]) 14783 14784;; This pattern is not fully shadowed by the pattern above. 14785(define_insn "*fop_sf_1_i387" 14786 [(set (match_operand:SF 0 "register_operand" "=f,f") 14787 (match_operator:SF 3 "binary_fp_operator" 14788 [(match_operand:SF 1 "nonimmediate_operand" "0,fm") 14789 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))] 14790 "TARGET_80387 && !TARGET_SSE_MATH 14791 && !COMMUTATIVE_ARITH_P (operands[3]) 14792 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 14793 "* return output_387_binary_op (insn, operands);" 14794 [(set (attr "type") 14795 (cond [(match_operand:SF 3 "mult_operator" "") 14796 (const_string "fmul") 14797 (match_operand:SF 3 "div_operator" "") 14798 (const_string "fdiv") 14799 ] 14800 (const_string "fop"))) 14801 (set_attr "mode" "SF")]) 14802 14803;; ??? Add SSE splitters for these! 14804(define_insn "*fop_sf_2<mode>_i387" 14805 [(set (match_operand:SF 0 "register_operand" "=f,f") 14806 (match_operator:SF 3 "binary_fp_operator" 14807 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r")) 14808 (match_operand:SF 2 "register_operand" "0,0")]))] 14809 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH" 14810 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 14811 [(set (attr "type") 14812 (cond [(match_operand:SF 3 "mult_operator" "") 14813 (const_string "fmul") 14814 (match_operand:SF 3 "div_operator" "") 14815 (const_string "fdiv") 14816 ] 14817 (const_string "fop"))) 14818 (set_attr "fp_int_src" "true") 14819 (set_attr "mode" "<MODE>")]) 14820 14821(define_insn "*fop_sf_3<mode>_i387" 14822 [(set (match_operand:SF 0 "register_operand" "=f,f") 14823 (match_operator:SF 3 "binary_fp_operator" 14824 [(match_operand:SF 1 "register_operand" "0,0") 14825 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))] 14826 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH" 14827 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 14828 [(set (attr "type") 14829 (cond [(match_operand:SF 3 "mult_operator" "") 14830 (const_string "fmul") 14831 (match_operand:SF 3 "div_operator" "") 14832 (const_string "fdiv") 14833 ] 14834 (const_string "fop"))) 14835 (set_attr "fp_int_src" "true") 14836 (set_attr "mode" "<MODE>")]) 14837 14838(define_insn "*fop_df_comm_mixed" 14839 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f") 14840 (match_operator:DF 3 "binary_fp_operator" 14841 [(match_operand:DF 1 "nonimmediate_operand" "%0,0") 14842 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))] 14843 "TARGET_SSE2 && TARGET_MIX_SSE_I387 14844 && COMMUTATIVE_ARITH_P (operands[3]) 14845 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 14846 "* return output_387_binary_op (insn, operands);" 14847 [(set (attr "type") 14848 (if_then_else (eq_attr "alternative" "1") 14849 (if_then_else (match_operand:SF 3 "mult_operator" "") 14850 (const_string "ssemul") 14851 (const_string "sseadd")) 14852 (if_then_else (match_operand:SF 3 "mult_operator" "") 14853 (const_string "fmul") 14854 (const_string "fop")))) 14855 (set_attr "mode" "DF")]) 14856 14857(define_insn "*fop_df_comm_sse" 14858 [(set (match_operand:DF 0 "register_operand" "=Y") 14859 (match_operator:DF 3 "binary_fp_operator" 14860 [(match_operand:DF 1 "nonimmediate_operand" "%0") 14861 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))] 14862 "TARGET_SSE2 && TARGET_SSE_MATH 14863 && COMMUTATIVE_ARITH_P (operands[3]) 14864 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 14865 "* return output_387_binary_op (insn, operands);" 14866 [(set (attr "type") 14867 (if_then_else (match_operand:SF 3 "mult_operator" "") 14868 (const_string "ssemul") 14869 (const_string "sseadd"))) 14870 (set_attr "mode" "DF")]) 14871 14872(define_insn "*fop_df_comm_i387" 14873 [(set (match_operand:DF 0 "register_operand" "=f") 14874 (match_operator:DF 3 "binary_fp_operator" 14875 [(match_operand:DF 1 "nonimmediate_operand" "%0") 14876 (match_operand:DF 2 "nonimmediate_operand" "fm")]))] 14877 "TARGET_80387 14878 && COMMUTATIVE_ARITH_P (operands[3]) 14879 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 14880 "* return output_387_binary_op (insn, operands);" 14881 [(set (attr "type") 14882 (if_then_else (match_operand:SF 3 "mult_operator" "") 14883 (const_string "fmul") 14884 (const_string "fop"))) 14885 (set_attr "mode" "DF")]) 14886 14887(define_insn "*fop_df_1_mixed" 14888 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f") 14889 (match_operator:DF 3 "binary_fp_operator" 14890 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0") 14891 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))] 14892 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387 14893 && !COMMUTATIVE_ARITH_P (operands[3]) 14894 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 14895 "* return output_387_binary_op (insn, operands);" 14896 [(set (attr "type") 14897 (cond [(and (eq_attr "alternative" "2") 14898 (match_operand:SF 3 "mult_operator" "")) 14899 (const_string "ssemul") 14900 (and (eq_attr "alternative" "2") 14901 (match_operand:SF 3 "div_operator" "")) 14902 (const_string "ssediv") 14903 (eq_attr "alternative" "2") 14904 (const_string "sseadd") 14905 (match_operand:DF 3 "mult_operator" "") 14906 (const_string "fmul") 14907 (match_operand:DF 3 "div_operator" "") 14908 (const_string "fdiv") 14909 ] 14910 (const_string "fop"))) 14911 (set_attr "mode" "DF")]) 14912 14913(define_insn "*fop_df_1_sse" 14914 [(set (match_operand:DF 0 "register_operand" "=Y") 14915 (match_operator:DF 3 "binary_fp_operator" 14916 [(match_operand:DF 1 "register_operand" "0") 14917 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))] 14918 "TARGET_SSE2 && TARGET_SSE_MATH 14919 && !COMMUTATIVE_ARITH_P (operands[3])" 14920 "* return output_387_binary_op (insn, operands);" 14921 [(set_attr "mode" "DF") 14922 (set (attr "type") 14923 (cond [(match_operand:SF 3 "mult_operator" "") 14924 (const_string "ssemul") 14925 (match_operand:SF 3 "div_operator" "") 14926 (const_string "ssediv") 14927 ] 14928 (const_string "sseadd")))]) 14929 14930;; This pattern is not fully shadowed by the pattern above. 14931(define_insn "*fop_df_1_i387" 14932 [(set (match_operand:DF 0 "register_operand" "=f,f") 14933 (match_operator:DF 3 "binary_fp_operator" 14934 [(match_operand:DF 1 "nonimmediate_operand" "0,fm") 14935 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))] 14936 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH) 14937 && !COMMUTATIVE_ARITH_P (operands[3]) 14938 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 14939 "* return output_387_binary_op (insn, operands);" 14940 [(set (attr "type") 14941 (cond [(match_operand:DF 3 "mult_operator" "") 14942 (const_string "fmul") 14943 (match_operand:DF 3 "div_operator" "") 14944 (const_string "fdiv") 14945 ] 14946 (const_string "fop"))) 14947 (set_attr "mode" "DF")]) 14948 14949;; ??? Add SSE splitters for these! 14950(define_insn "*fop_df_2<mode>_i387" 14951 [(set (match_operand:DF 0 "register_operand" "=f,f") 14952 (match_operator:DF 3 "binary_fp_operator" 14953 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r")) 14954 (match_operand:DF 2 "register_operand" "0,0")]))] 14955 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 14956 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 14957 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 14958 [(set (attr "type") 14959 (cond [(match_operand:DF 3 "mult_operator" "") 14960 (const_string "fmul") 14961 (match_operand:DF 3 "div_operator" "") 14962 (const_string "fdiv") 14963 ] 14964 (const_string "fop"))) 14965 (set_attr "fp_int_src" "true") 14966 (set_attr "mode" "<MODE>")]) 14967 14968(define_insn "*fop_df_3<mode>_i387" 14969 [(set (match_operand:DF 0 "register_operand" "=f,f") 14970 (match_operator:DF 3 "binary_fp_operator" 14971 [(match_operand:DF 1 "register_operand" "0,0") 14972 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))] 14973 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 14974 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 14975 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 14976 [(set (attr "type") 14977 (cond [(match_operand:DF 3 "mult_operator" "") 14978 (const_string "fmul") 14979 (match_operand:DF 3 "div_operator" "") 14980 (const_string "fdiv") 14981 ] 14982 (const_string "fop"))) 14983 (set_attr "fp_int_src" "true") 14984 (set_attr "mode" "<MODE>")]) 14985 14986(define_insn "*fop_df_4_i387" 14987 [(set (match_operand:DF 0 "register_operand" "=f,f") 14988 (match_operator:DF 3 "binary_fp_operator" 14989 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0")) 14990 (match_operand:DF 2 "register_operand" "0,f")]))] 14991 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH) 14992 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 14993 "* return output_387_binary_op (insn, operands);" 14994 [(set (attr "type") 14995 (cond [(match_operand:DF 3 "mult_operator" "") 14996 (const_string "fmul") 14997 (match_operand:DF 3 "div_operator" "") 14998 (const_string "fdiv") 14999 ] 15000 (const_string "fop"))) 15001 (set_attr "mode" "SF")]) 15002 15003(define_insn "*fop_df_5_i387" 15004 [(set (match_operand:DF 0 "register_operand" "=f,f") 15005 (match_operator:DF 3 "binary_fp_operator" 15006 [(match_operand:DF 1 "register_operand" "0,f") 15007 (float_extend:DF 15008 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15009 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15010 "* return output_387_binary_op (insn, operands);" 15011 [(set (attr "type") 15012 (cond [(match_operand:DF 3 "mult_operator" "") 15013 (const_string "fmul") 15014 (match_operand:DF 3 "div_operator" "") 15015 (const_string "fdiv") 15016 ] 15017 (const_string "fop"))) 15018 (set_attr "mode" "SF")]) 15019 15020(define_insn "*fop_df_6_i387" 15021 [(set (match_operand:DF 0 "register_operand" "=f,f") 15022 (match_operator:DF 3 "binary_fp_operator" 15023 [(float_extend:DF 15024 (match_operand:SF 1 "register_operand" "0,f")) 15025 (float_extend:DF 15026 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15027 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15028 "* return output_387_binary_op (insn, operands);" 15029 [(set (attr "type") 15030 (cond [(match_operand:DF 3 "mult_operator" "") 15031 (const_string "fmul") 15032 (match_operand:DF 3 "div_operator" "") 15033 (const_string "fdiv") 15034 ] 15035 (const_string "fop"))) 15036 (set_attr "mode" "SF")]) 15037 15038(define_insn "*fop_xf_comm_i387" 15039 [(set (match_operand:XF 0 "register_operand" "=f") 15040 (match_operator:XF 3 "binary_fp_operator" 15041 [(match_operand:XF 1 "register_operand" "%0") 15042 (match_operand:XF 2 "register_operand" "f")]))] 15043 "TARGET_80387 15044 && COMMUTATIVE_ARITH_P (operands[3])" 15045 "* return output_387_binary_op (insn, operands);" 15046 [(set (attr "type") 15047 (if_then_else (match_operand:XF 3 "mult_operator" "") 15048 (const_string "fmul") 15049 (const_string "fop"))) 15050 (set_attr "mode" "XF")]) 15051 15052(define_insn "*fop_xf_1_i387" 15053 [(set (match_operand:XF 0 "register_operand" "=f,f") 15054 (match_operator:XF 3 "binary_fp_operator" 15055 [(match_operand:XF 1 "register_operand" "0,f") 15056 (match_operand:XF 2 "register_operand" "f,0")]))] 15057 "TARGET_80387 15058 && !COMMUTATIVE_ARITH_P (operands[3])" 15059 "* return output_387_binary_op (insn, operands);" 15060 [(set (attr "type") 15061 (cond [(match_operand:XF 3 "mult_operator" "") 15062 (const_string "fmul") 15063 (match_operand:XF 3 "div_operator" "") 15064 (const_string "fdiv") 15065 ] 15066 (const_string "fop"))) 15067 (set_attr "mode" "XF")]) 15068 15069(define_insn "*fop_xf_2<mode>_i387" 15070 [(set (match_operand:XF 0 "register_operand" "=f,f") 15071 (match_operator:XF 3 "binary_fp_operator" 15072 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r")) 15073 (match_operand:XF 2 "register_operand" "0,0")]))] 15074 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP" 15075 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15076 [(set (attr "type") 15077 (cond [(match_operand:XF 3 "mult_operator" "") 15078 (const_string "fmul") 15079 (match_operand:XF 3 "div_operator" "") 15080 (const_string "fdiv") 15081 ] 15082 (const_string "fop"))) 15083 (set_attr "fp_int_src" "true") 15084 (set_attr "mode" "<MODE>")]) 15085 15086(define_insn "*fop_xf_3<mode>_i387" 15087 [(set (match_operand:XF 0 "register_operand" "=f,f") 15088 (match_operator:XF 3 "binary_fp_operator" 15089 [(match_operand:XF 1 "register_operand" "0,0") 15090 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))] 15091 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP" 15092 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15093 [(set (attr "type") 15094 (cond [(match_operand:XF 3 "mult_operator" "") 15095 (const_string "fmul") 15096 (match_operand:XF 3 "div_operator" "") 15097 (const_string "fdiv") 15098 ] 15099 (const_string "fop"))) 15100 (set_attr "fp_int_src" "true") 15101 (set_attr "mode" "<MODE>")]) 15102 15103(define_insn "*fop_xf_4_i387" 15104 [(set (match_operand:XF 0 "register_operand" "=f,f") 15105 (match_operator:XF 3 "binary_fp_operator" 15106 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0")) 15107 (match_operand:XF 2 "register_operand" "0,f")]))] 15108 "TARGET_80387" 15109 "* return output_387_binary_op (insn, operands);" 15110 [(set (attr "type") 15111 (cond [(match_operand:XF 3 "mult_operator" "") 15112 (const_string "fmul") 15113 (match_operand:XF 3 "div_operator" "") 15114 (const_string "fdiv") 15115 ] 15116 (const_string "fop"))) 15117 (set_attr "mode" "SF")]) 15118 15119(define_insn "*fop_xf_5_i387" 15120 [(set (match_operand:XF 0 "register_operand" "=f,f") 15121 (match_operator:XF 3 "binary_fp_operator" 15122 [(match_operand:XF 1 "register_operand" "0,f") 15123 (float_extend:XF 15124 (match_operand 2 "nonimmediate_operand" "fm,0"))]))] 15125 "TARGET_80387" 15126 "* return output_387_binary_op (insn, operands);" 15127 [(set (attr "type") 15128 (cond [(match_operand:XF 3 "mult_operator" "") 15129 (const_string "fmul") 15130 (match_operand:XF 3 "div_operator" "") 15131 (const_string "fdiv") 15132 ] 15133 (const_string "fop"))) 15134 (set_attr "mode" "SF")]) 15135 15136(define_insn "*fop_xf_6_i387" 15137 [(set (match_operand:XF 0 "register_operand" "=f,f") 15138 (match_operator:XF 3 "binary_fp_operator" 15139 [(float_extend:XF 15140 (match_operand 1 "register_operand" "0,f")) 15141 (float_extend:XF 15142 (match_operand 2 "nonimmediate_operand" "fm,0"))]))] 15143 "TARGET_80387" 15144 "* return output_387_binary_op (insn, operands);" 15145 [(set (attr "type") 15146 (cond [(match_operand:XF 3 "mult_operator" "") 15147 (const_string "fmul") 15148 (match_operand:XF 3 "div_operator" "") 15149 (const_string "fdiv") 15150 ] 15151 (const_string "fop"))) 15152 (set_attr "mode" "SF")]) 15153 15154(define_split 15155 [(set (match_operand 0 "register_operand" "") 15156 (match_operator 3 "binary_fp_operator" 15157 [(float (match_operand:X87MODEI12 1 "register_operand" "")) 15158 (match_operand 2 "register_operand" "")]))] 15159 "TARGET_80387 && reload_completed 15160 && FLOAT_MODE_P (GET_MODE (operands[0]))" 15161 [(const_int 0)] 15162{ 15163 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]); 15164 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); 15165 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 15166 gen_rtx_fmt_ee (GET_CODE (operands[3]), 15167 GET_MODE (operands[3]), 15168 operands[4], 15169 operands[2]))); 15170 ix86_free_from_memory (GET_MODE (operands[1])); 15171 DONE; 15172}) 15173 15174(define_split 15175 [(set (match_operand 0 "register_operand" "") 15176 (match_operator 3 "binary_fp_operator" 15177 [(match_operand 1 "register_operand" "") 15178 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))] 15179 "TARGET_80387 && reload_completed 15180 && FLOAT_MODE_P (GET_MODE (operands[0]))" 15181 [(const_int 0)] 15182{ 15183 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); 15184 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); 15185 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 15186 gen_rtx_fmt_ee (GET_CODE (operands[3]), 15187 GET_MODE (operands[3]), 15188 operands[1], 15189 operands[4]))); 15190 ix86_free_from_memory (GET_MODE (operands[2])); 15191 DONE; 15192}) 15193 15194;; FPU special functions. 15195 15196(define_expand "sqrtsf2" 15197 [(set (match_operand:SF 0 "register_operand" "") 15198 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))] 15199 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH" 15200{ 15201 if (!TARGET_SSE_MATH) 15202 operands[1] = force_reg (SFmode, operands[1]); 15203}) 15204 15205(define_insn "*sqrtsf2_mixed" 15206 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f") 15207 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))] 15208 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387" 15209 "@ 15210 fsqrt 15211 sqrtss\t{%1, %0|%0, %1}" 15212 [(set_attr "type" "fpspc,sse") 15213 (set_attr "mode" "SF,SF") 15214 (set_attr "athlon_decode" "direct,*")]) 15215 15216(define_insn "*sqrtsf2_sse" 15217 [(set (match_operand:SF 0 "register_operand" "=x") 15218 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))] 15219 "TARGET_SSE_MATH" 15220 "sqrtss\t{%1, %0|%0, %1}" 15221 [(set_attr "type" "sse") 15222 (set_attr "mode" "SF") 15223 (set_attr "athlon_decode" "*")]) 15224 15225(define_insn "*sqrtsf2_i387" 15226 [(set (match_operand:SF 0 "register_operand" "=f") 15227 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))] 15228 "TARGET_USE_FANCY_MATH_387" 15229 "fsqrt" 15230 [(set_attr "type" "fpspc") 15231 (set_attr "mode" "SF") 15232 (set_attr "athlon_decode" "direct")]) 15233 15234(define_expand "sqrtdf2" 15235 [(set (match_operand:DF 0 "register_operand" "") 15236 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))] 15237 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 15238{ 15239 if (!(TARGET_SSE2 && TARGET_SSE_MATH)) 15240 operands[1] = force_reg (DFmode, operands[1]); 15241}) 15242 15243(define_insn "*sqrtdf2_mixed" 15244 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f") 15245 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))] 15246 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387" 15247 "@ 15248 fsqrt 15249 sqrtsd\t{%1, %0|%0, %1}" 15250 [(set_attr "type" "fpspc,sse") 15251 (set_attr "mode" "DF,DF") 15252 (set_attr "athlon_decode" "direct,*")]) 15253 15254(define_insn "*sqrtdf2_sse" 15255 [(set (match_operand:DF 0 "register_operand" "=Y") 15256 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))] 15257 "TARGET_SSE2 && TARGET_SSE_MATH" 15258 "sqrtsd\t{%1, %0|%0, %1}" 15259 [(set_attr "type" "sse") 15260 (set_attr "mode" "DF") 15261 (set_attr "athlon_decode" "*")]) 15262 15263(define_insn "*sqrtdf2_i387" 15264 [(set (match_operand:DF 0 "register_operand" "=f") 15265 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))] 15266 "TARGET_USE_FANCY_MATH_387" 15267 "fsqrt" 15268 [(set_attr "type" "fpspc") 15269 (set_attr "mode" "DF") 15270 (set_attr "athlon_decode" "direct")]) 15271 15272(define_insn "*sqrtextendsfdf2_i387" 15273 [(set (match_operand:DF 0 "register_operand" "=f") 15274 (sqrt:DF (float_extend:DF 15275 (match_operand:SF 1 "register_operand" "0"))))] 15276 "TARGET_USE_FANCY_MATH_387 15277 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)" 15278 "fsqrt" 15279 [(set_attr "type" "fpspc") 15280 (set_attr "mode" "DF") 15281 (set_attr "athlon_decode" "direct")]) 15282 15283(define_insn "sqrtxf2" 15284 [(set (match_operand:XF 0 "register_operand" "=f") 15285 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] 15286 "TARGET_USE_FANCY_MATH_387 15287 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) " 15288 "fsqrt" 15289 [(set_attr "type" "fpspc") 15290 (set_attr "mode" "XF") 15291 (set_attr "athlon_decode" "direct")]) 15292 15293(define_insn "*sqrtextendsfxf2_i387" 15294 [(set (match_operand:XF 0 "register_operand" "=f") 15295 (sqrt:XF (float_extend:XF 15296 (match_operand:SF 1 "register_operand" "0"))))] 15297 "TARGET_USE_FANCY_MATH_387" 15298 "fsqrt" 15299 [(set_attr "type" "fpspc") 15300 (set_attr "mode" "XF") 15301 (set_attr "athlon_decode" "direct")]) 15302 15303(define_insn "*sqrtextenddfxf2_i387" 15304 [(set (match_operand:XF 0 "register_operand" "=f") 15305 (sqrt:XF (float_extend:XF 15306 (match_operand:DF 1 "register_operand" "0"))))] 15307 "TARGET_USE_FANCY_MATH_387" 15308 "fsqrt" 15309 [(set_attr "type" "fpspc") 15310 (set_attr "mode" "XF") 15311 (set_attr "athlon_decode" "direct")]) 15312 15313(define_insn "fpremxf4" 15314 [(set (match_operand:XF 0 "register_operand" "=f") 15315 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15316 (match_operand:XF 3 "register_operand" "1")] 15317 UNSPEC_FPREM_F)) 15318 (set (match_operand:XF 1 "register_operand" "=u") 15319 (unspec:XF [(match_dup 2) (match_dup 3)] 15320 UNSPEC_FPREM_U)) 15321 (set (reg:CCFP FPSR_REG) 15322 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))] 15323 "TARGET_USE_FANCY_MATH_387 15324 && flag_unsafe_math_optimizations" 15325 "fprem" 15326 [(set_attr "type" "fpspc") 15327 (set_attr "mode" "XF")]) 15328 15329(define_expand "fmodsf3" 15330 [(use (match_operand:SF 0 "register_operand" "")) 15331 (use (match_operand:SF 1 "register_operand" "")) 15332 (use (match_operand:SF 2 "register_operand" ""))] 15333 "TARGET_USE_FANCY_MATH_387 15334 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15335 && flag_unsafe_math_optimizations" 15336{ 15337 rtx label = gen_label_rtx (); 15338 15339 rtx op1 = gen_reg_rtx (XFmode); 15340 rtx op2 = gen_reg_rtx (XFmode); 15341 15342 emit_insn(gen_extendsfxf2 (op1, operands[1])); 15343 emit_insn(gen_extendsfxf2 (op2, operands[2])); 15344 15345 emit_label (label); 15346 15347 emit_insn (gen_fpremxf4 (op1, op2, op1, op2)); 15348 ix86_emit_fp_unordered_jump (label); 15349 15350 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1)); 15351 DONE; 15352}) 15353 15354(define_expand "fmoddf3" 15355 [(use (match_operand:DF 0 "register_operand" "")) 15356 (use (match_operand:DF 1 "register_operand" "")) 15357 (use (match_operand:DF 2 "register_operand" ""))] 15358 "TARGET_USE_FANCY_MATH_387 15359 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15360 && flag_unsafe_math_optimizations" 15361{ 15362 rtx label = gen_label_rtx (); 15363 15364 rtx op1 = gen_reg_rtx (XFmode); 15365 rtx op2 = gen_reg_rtx (XFmode); 15366 15367 emit_insn (gen_extenddfxf2 (op1, operands[1])); 15368 emit_insn (gen_extenddfxf2 (op2, operands[2])); 15369 15370 emit_label (label); 15371 15372 emit_insn (gen_fpremxf4 (op1, op2, op1, op2)); 15373 ix86_emit_fp_unordered_jump (label); 15374 15375 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1)); 15376 DONE; 15377}) 15378 15379(define_expand "fmodxf3" 15380 [(use (match_operand:XF 0 "register_operand" "")) 15381 (use (match_operand:XF 1 "register_operand" "")) 15382 (use (match_operand:XF 2 "register_operand" ""))] 15383 "TARGET_USE_FANCY_MATH_387 15384 && flag_unsafe_math_optimizations" 15385{ 15386 rtx label = gen_label_rtx (); 15387 15388 emit_label (label); 15389 15390 emit_insn (gen_fpremxf4 (operands[1], operands[2], 15391 operands[1], operands[2])); 15392 ix86_emit_fp_unordered_jump (label); 15393 15394 emit_move_insn (operands[0], operands[1]); 15395 DONE; 15396}) 15397 15398(define_insn "fprem1xf4" 15399 [(set (match_operand:XF 0 "register_operand" "=f") 15400 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15401 (match_operand:XF 3 "register_operand" "1")] 15402 UNSPEC_FPREM1_F)) 15403 (set (match_operand:XF 1 "register_operand" "=u") 15404 (unspec:XF [(match_dup 2) (match_dup 3)] 15405 UNSPEC_FPREM1_U)) 15406 (set (reg:CCFP FPSR_REG) 15407 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))] 15408 "TARGET_USE_FANCY_MATH_387 15409 && flag_unsafe_math_optimizations" 15410 "fprem1" 15411 [(set_attr "type" "fpspc") 15412 (set_attr "mode" "XF")]) 15413 15414(define_expand "dremsf3" 15415 [(use (match_operand:SF 0 "register_operand" "")) 15416 (use (match_operand:SF 1 "register_operand" "")) 15417 (use (match_operand:SF 2 "register_operand" ""))] 15418 "TARGET_USE_FANCY_MATH_387 15419 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15420 && flag_unsafe_math_optimizations" 15421{ 15422 rtx label = gen_label_rtx (); 15423 15424 rtx op1 = gen_reg_rtx (XFmode); 15425 rtx op2 = gen_reg_rtx (XFmode); 15426 15427 emit_insn(gen_extendsfxf2 (op1, operands[1])); 15428 emit_insn(gen_extendsfxf2 (op2, operands[2])); 15429 15430 emit_label (label); 15431 15432 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2)); 15433 ix86_emit_fp_unordered_jump (label); 15434 15435 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1)); 15436 DONE; 15437}) 15438 15439(define_expand "dremdf3" 15440 [(use (match_operand:DF 0 "register_operand" "")) 15441 (use (match_operand:DF 1 "register_operand" "")) 15442 (use (match_operand:DF 2 "register_operand" ""))] 15443 "TARGET_USE_FANCY_MATH_387 15444 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15445 && flag_unsafe_math_optimizations" 15446{ 15447 rtx label = gen_label_rtx (); 15448 15449 rtx op1 = gen_reg_rtx (XFmode); 15450 rtx op2 = gen_reg_rtx (XFmode); 15451 15452 emit_insn (gen_extenddfxf2 (op1, operands[1])); 15453 emit_insn (gen_extenddfxf2 (op2, operands[2])); 15454 15455 emit_label (label); 15456 15457 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2)); 15458 ix86_emit_fp_unordered_jump (label); 15459 15460 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1)); 15461 DONE; 15462}) 15463 15464(define_expand "dremxf3" 15465 [(use (match_operand:XF 0 "register_operand" "")) 15466 (use (match_operand:XF 1 "register_operand" "")) 15467 (use (match_operand:XF 2 "register_operand" ""))] 15468 "TARGET_USE_FANCY_MATH_387 15469 && flag_unsafe_math_optimizations" 15470{ 15471 rtx label = gen_label_rtx (); 15472 15473 emit_label (label); 15474 15475 emit_insn (gen_fprem1xf4 (operands[1], operands[2], 15476 operands[1], operands[2])); 15477 ix86_emit_fp_unordered_jump (label); 15478 15479 emit_move_insn (operands[0], operands[1]); 15480 DONE; 15481}) 15482 15483(define_insn "*sindf2" 15484 [(set (match_operand:DF 0 "register_operand" "=f") 15485 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))] 15486 "TARGET_USE_FANCY_MATH_387 15487 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15488 && flag_unsafe_math_optimizations" 15489 "fsin" 15490 [(set_attr "type" "fpspc") 15491 (set_attr "mode" "DF")]) 15492 15493(define_insn "*sinsf2" 15494 [(set (match_operand:SF 0 "register_operand" "=f") 15495 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))] 15496 "TARGET_USE_FANCY_MATH_387 15497 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15498 && flag_unsafe_math_optimizations" 15499 "fsin" 15500 [(set_attr "type" "fpspc") 15501 (set_attr "mode" "SF")]) 15502 15503(define_insn "*sinextendsfdf2" 15504 [(set (match_operand:DF 0 "register_operand" "=f") 15505 (unspec:DF [(float_extend:DF 15506 (match_operand:SF 1 "register_operand" "0"))] 15507 UNSPEC_SIN))] 15508 "TARGET_USE_FANCY_MATH_387 15509 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15510 && flag_unsafe_math_optimizations" 15511 "fsin" 15512 [(set_attr "type" "fpspc") 15513 (set_attr "mode" "DF")]) 15514 15515(define_insn "*sinxf2" 15516 [(set (match_operand:XF 0 "register_operand" "=f") 15517 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))] 15518 "TARGET_USE_FANCY_MATH_387 15519 && flag_unsafe_math_optimizations" 15520 "fsin" 15521 [(set_attr "type" "fpspc") 15522 (set_attr "mode" "XF")]) 15523 15524(define_insn "*cosdf2" 15525 [(set (match_operand:DF 0 "register_operand" "=f") 15526 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))] 15527 "TARGET_USE_FANCY_MATH_387 15528 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15529 && flag_unsafe_math_optimizations" 15530 "fcos" 15531 [(set_attr "type" "fpspc") 15532 (set_attr "mode" "DF")]) 15533 15534(define_insn "*cossf2" 15535 [(set (match_operand:SF 0 "register_operand" "=f") 15536 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))] 15537 "TARGET_USE_FANCY_MATH_387 15538 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15539 && flag_unsafe_math_optimizations" 15540 "fcos" 15541 [(set_attr "type" "fpspc") 15542 (set_attr "mode" "SF")]) 15543 15544(define_insn "*cosextendsfdf2" 15545 [(set (match_operand:DF 0 "register_operand" "=f") 15546 (unspec:DF [(float_extend:DF 15547 (match_operand:SF 1 "register_operand" "0"))] 15548 UNSPEC_COS))] 15549 "TARGET_USE_FANCY_MATH_387 15550 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15551 && flag_unsafe_math_optimizations" 15552 "fcos" 15553 [(set_attr "type" "fpspc") 15554 (set_attr "mode" "DF")]) 15555 15556(define_insn "*cosxf2" 15557 [(set (match_operand:XF 0 "register_operand" "=f") 15558 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))] 15559 "TARGET_USE_FANCY_MATH_387 15560 && flag_unsafe_math_optimizations" 15561 "fcos" 15562 [(set_attr "type" "fpspc") 15563 (set_attr "mode" "XF")]) 15564 15565;; With sincos pattern defined, sin and cos builtin function will be 15566;; expanded to sincos pattern with one of its outputs left unused. 15567;; Cse pass will detected, if two sincos patterns can be combined, 15568;; otherwise sincos pattern will be split back to sin or cos pattern, 15569;; depending on the unused output. 15570 15571(define_insn "sincosdf3" 15572 [(set (match_operand:DF 0 "register_operand" "=f") 15573 (unspec:DF [(match_operand:DF 2 "register_operand" "0")] 15574 UNSPEC_SINCOS_COS)) 15575 (set (match_operand:DF 1 "register_operand" "=u") 15576 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15577 "TARGET_USE_FANCY_MATH_387 15578 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15579 && flag_unsafe_math_optimizations" 15580 "fsincos" 15581 [(set_attr "type" "fpspc") 15582 (set_attr "mode" "DF")]) 15583 15584(define_split 15585 [(set (match_operand:DF 0 "register_operand" "") 15586 (unspec:DF [(match_operand:DF 2 "register_operand" "")] 15587 UNSPEC_SINCOS_COS)) 15588 (set (match_operand:DF 1 "register_operand" "") 15589 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15590 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15591 && !reload_completed && !reload_in_progress" 15592 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))] 15593 "") 15594 15595(define_split 15596 [(set (match_operand:DF 0 "register_operand" "") 15597 (unspec:DF [(match_operand:DF 2 "register_operand" "")] 15598 UNSPEC_SINCOS_COS)) 15599 (set (match_operand:DF 1 "register_operand" "") 15600 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15601 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15602 && !reload_completed && !reload_in_progress" 15603 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))] 15604 "") 15605 15606(define_insn "sincossf3" 15607 [(set (match_operand:SF 0 "register_operand" "=f") 15608 (unspec:SF [(match_operand:SF 2 "register_operand" "0")] 15609 UNSPEC_SINCOS_COS)) 15610 (set (match_operand:SF 1 "register_operand" "=u") 15611 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15612 "TARGET_USE_FANCY_MATH_387 15613 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15614 && flag_unsafe_math_optimizations" 15615 "fsincos" 15616 [(set_attr "type" "fpspc") 15617 (set_attr "mode" "SF")]) 15618 15619(define_split 15620 [(set (match_operand:SF 0 "register_operand" "") 15621 (unspec:SF [(match_operand:SF 2 "register_operand" "")] 15622 UNSPEC_SINCOS_COS)) 15623 (set (match_operand:SF 1 "register_operand" "") 15624 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15625 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15626 && !reload_completed && !reload_in_progress" 15627 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))] 15628 "") 15629 15630(define_split 15631 [(set (match_operand:SF 0 "register_operand" "") 15632 (unspec:SF [(match_operand:SF 2 "register_operand" "")] 15633 UNSPEC_SINCOS_COS)) 15634 (set (match_operand:SF 1 "register_operand" "") 15635 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15636 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15637 && !reload_completed && !reload_in_progress" 15638 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))] 15639 "") 15640 15641(define_insn "*sincosextendsfdf3" 15642 [(set (match_operand:DF 0 "register_operand" "=f") 15643 (unspec:DF [(float_extend:DF 15644 (match_operand:SF 2 "register_operand" "0"))] 15645 UNSPEC_SINCOS_COS)) 15646 (set (match_operand:DF 1 "register_operand" "=u") 15647 (unspec:DF [(float_extend:DF 15648 (match_dup 2))] UNSPEC_SINCOS_SIN))] 15649 "TARGET_USE_FANCY_MATH_387 15650 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15651 && flag_unsafe_math_optimizations" 15652 "fsincos" 15653 [(set_attr "type" "fpspc") 15654 (set_attr "mode" "DF")]) 15655 15656(define_split 15657 [(set (match_operand:DF 0 "register_operand" "") 15658 (unspec:DF [(float_extend:DF 15659 (match_operand:SF 2 "register_operand" ""))] 15660 UNSPEC_SINCOS_COS)) 15661 (set (match_operand:DF 1 "register_operand" "") 15662 (unspec:DF [(float_extend:DF 15663 (match_dup 2))] UNSPEC_SINCOS_SIN))] 15664 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15665 && !reload_completed && !reload_in_progress" 15666 [(set (match_dup 1) (unspec:DF [(float_extend:DF 15667 (match_dup 2))] UNSPEC_SIN))] 15668 "") 15669 15670(define_split 15671 [(set (match_operand:DF 0 "register_operand" "") 15672 (unspec:DF [(float_extend:DF 15673 (match_operand:SF 2 "register_operand" ""))] 15674 UNSPEC_SINCOS_COS)) 15675 (set (match_operand:DF 1 "register_operand" "") 15676 (unspec:DF [(float_extend:DF 15677 (match_dup 2))] UNSPEC_SINCOS_SIN))] 15678 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15679 && !reload_completed && !reload_in_progress" 15680 [(set (match_dup 0) (unspec:DF [(float_extend:DF 15681 (match_dup 2))] UNSPEC_COS))] 15682 "") 15683 15684(define_insn "sincosxf3" 15685 [(set (match_operand:XF 0 "register_operand" "=f") 15686 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 15687 UNSPEC_SINCOS_COS)) 15688 (set (match_operand:XF 1 "register_operand" "=u") 15689 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15690 "TARGET_USE_FANCY_MATH_387 15691 && flag_unsafe_math_optimizations" 15692 "fsincos" 15693 [(set_attr "type" "fpspc") 15694 (set_attr "mode" "XF")]) 15695 15696(define_split 15697 [(set (match_operand:XF 0 "register_operand" "") 15698 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 15699 UNSPEC_SINCOS_COS)) 15700 (set (match_operand:XF 1 "register_operand" "") 15701 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15702 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15703 && !reload_completed && !reload_in_progress" 15704 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))] 15705 "") 15706 15707(define_split 15708 [(set (match_operand:XF 0 "register_operand" "") 15709 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 15710 UNSPEC_SINCOS_COS)) 15711 (set (match_operand:XF 1 "register_operand" "") 15712 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15713 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15714 && !reload_completed && !reload_in_progress" 15715 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))] 15716 "") 15717 15718(define_insn "*tandf3_1" 15719 [(set (match_operand:DF 0 "register_operand" "=f") 15720 (unspec:DF [(match_operand:DF 2 "register_operand" "0")] 15721 UNSPEC_TAN_ONE)) 15722 (set (match_operand:DF 1 "register_operand" "=u") 15723 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))] 15724 "TARGET_USE_FANCY_MATH_387 15725 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15726 && flag_unsafe_math_optimizations" 15727 "fptan" 15728 [(set_attr "type" "fpspc") 15729 (set_attr "mode" "DF")]) 15730 15731;; optimize sequence: fptan 15732;; fstp %st(0) 15733;; fld1 15734;; into fptan insn. 15735 15736(define_peephole2 15737 [(parallel[(set (match_operand:DF 0 "register_operand" "") 15738 (unspec:DF [(match_operand:DF 2 "register_operand" "")] 15739 UNSPEC_TAN_ONE)) 15740 (set (match_operand:DF 1 "register_operand" "") 15741 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]) 15742 (set (match_dup 0) 15743 (match_operand:DF 3 "immediate_operand" ""))] 15744 "standard_80387_constant_p (operands[3]) == 2" 15745 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE)) 15746 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])] 15747 "") 15748 15749(define_expand "tandf2" 15750 [(parallel [(set (match_dup 2) 15751 (unspec:DF [(match_operand:DF 1 "register_operand" "")] 15752 UNSPEC_TAN_ONE)) 15753 (set (match_operand:DF 0 "register_operand" "") 15754 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])] 15755 "TARGET_USE_FANCY_MATH_387 15756 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15757 && flag_unsafe_math_optimizations" 15758{ 15759 operands[2] = gen_reg_rtx (DFmode); 15760}) 15761 15762(define_insn "*tansf3_1" 15763 [(set (match_operand:SF 0 "register_operand" "=f") 15764 (unspec:SF [(match_operand:SF 2 "register_operand" "0")] 15765 UNSPEC_TAN_ONE)) 15766 (set (match_operand:SF 1 "register_operand" "=u") 15767 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))] 15768 "TARGET_USE_FANCY_MATH_387 15769 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15770 && flag_unsafe_math_optimizations" 15771 "fptan" 15772 [(set_attr "type" "fpspc") 15773 (set_attr "mode" "SF")]) 15774 15775;; optimize sequence: fptan 15776;; fstp %st(0) 15777;; fld1 15778;; into fptan insn. 15779 15780(define_peephole2 15781 [(parallel[(set (match_operand:SF 0 "register_operand" "") 15782 (unspec:SF [(match_operand:SF 2 "register_operand" "")] 15783 UNSPEC_TAN_ONE)) 15784 (set (match_operand:SF 1 "register_operand" "") 15785 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]) 15786 (set (match_dup 0) 15787 (match_operand:SF 3 "immediate_operand" ""))] 15788 "standard_80387_constant_p (operands[3]) == 2" 15789 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE)) 15790 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])] 15791 "") 15792 15793(define_expand "tansf2" 15794 [(parallel [(set (match_dup 2) 15795 (unspec:SF [(match_operand:SF 1 "register_operand" "")] 15796 UNSPEC_TAN_ONE)) 15797 (set (match_operand:SF 0 "register_operand" "") 15798 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])] 15799 "TARGET_USE_FANCY_MATH_387 15800 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15801 && flag_unsafe_math_optimizations" 15802{ 15803 operands[2] = gen_reg_rtx (SFmode); 15804}) 15805 15806(define_insn "*tanxf3_1" 15807 [(set (match_operand:XF 0 "register_operand" "=f") 15808 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 15809 UNSPEC_TAN_ONE)) 15810 (set (match_operand:XF 1 "register_operand" "=u") 15811 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))] 15812 "TARGET_USE_FANCY_MATH_387 15813 && flag_unsafe_math_optimizations" 15814 "fptan" 15815 [(set_attr "type" "fpspc") 15816 (set_attr "mode" "XF")]) 15817 15818;; optimize sequence: fptan 15819;; fstp %st(0) 15820;; fld1 15821;; into fptan insn. 15822 15823(define_peephole2 15824 [(parallel[(set (match_operand:XF 0 "register_operand" "") 15825 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 15826 UNSPEC_TAN_ONE)) 15827 (set (match_operand:XF 1 "register_operand" "") 15828 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]) 15829 (set (match_dup 0) 15830 (match_operand:XF 3 "immediate_operand" ""))] 15831 "standard_80387_constant_p (operands[3]) == 2" 15832 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE)) 15833 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])] 15834 "") 15835 15836(define_expand "tanxf2" 15837 [(parallel [(set (match_dup 2) 15838 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 15839 UNSPEC_TAN_ONE)) 15840 (set (match_operand:XF 0 "register_operand" "") 15841 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])] 15842 "TARGET_USE_FANCY_MATH_387 15843 && flag_unsafe_math_optimizations" 15844{ 15845 operands[2] = gen_reg_rtx (XFmode); 15846}) 15847 15848(define_insn "atan2df3_1" 15849 [(set (match_operand:DF 0 "register_operand" "=f") 15850 (unspec:DF [(match_operand:DF 2 "register_operand" "0") 15851 (match_operand:DF 1 "register_operand" "u")] 15852 UNSPEC_FPATAN)) 15853 (clobber (match_scratch:DF 3 "=1"))] 15854 "TARGET_USE_FANCY_MATH_387 15855 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15856 && flag_unsafe_math_optimizations" 15857 "fpatan" 15858 [(set_attr "type" "fpspc") 15859 (set_attr "mode" "DF")]) 15860 15861(define_expand "atan2df3" 15862 [(use (match_operand:DF 0 "register_operand" "")) 15863 (use (match_operand:DF 2 "register_operand" "")) 15864 (use (match_operand:DF 1 "register_operand" ""))] 15865 "TARGET_USE_FANCY_MATH_387 15866 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15867 && flag_unsafe_math_optimizations" 15868{ 15869 rtx copy = gen_reg_rtx (DFmode); 15870 emit_move_insn (copy, operands[1]); 15871 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2])); 15872 DONE; 15873}) 15874 15875(define_expand "atandf2" 15876 [(parallel [(set (match_operand:DF 0 "register_operand" "") 15877 (unspec:DF [(match_dup 2) 15878 (match_operand:DF 1 "register_operand" "")] 15879 UNSPEC_FPATAN)) 15880 (clobber (match_scratch:DF 3 ""))])] 15881 "TARGET_USE_FANCY_MATH_387 15882 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15883 && flag_unsafe_math_optimizations" 15884{ 15885 operands[2] = gen_reg_rtx (DFmode); 15886 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */ 15887}) 15888 15889(define_insn "atan2sf3_1" 15890 [(set (match_operand:SF 0 "register_operand" "=f") 15891 (unspec:SF [(match_operand:SF 2 "register_operand" "0") 15892 (match_operand:SF 1 "register_operand" "u")] 15893 UNSPEC_FPATAN)) 15894 (clobber (match_scratch:SF 3 "=1"))] 15895 "TARGET_USE_FANCY_MATH_387 15896 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15897 && flag_unsafe_math_optimizations" 15898 "fpatan" 15899 [(set_attr "type" "fpspc") 15900 (set_attr "mode" "SF")]) 15901 15902(define_expand "atan2sf3" 15903 [(use (match_operand:SF 0 "register_operand" "")) 15904 (use (match_operand:SF 2 "register_operand" "")) 15905 (use (match_operand:SF 1 "register_operand" ""))] 15906 "TARGET_USE_FANCY_MATH_387 15907 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15908 && flag_unsafe_math_optimizations" 15909{ 15910 rtx copy = gen_reg_rtx (SFmode); 15911 emit_move_insn (copy, operands[1]); 15912 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2])); 15913 DONE; 15914}) 15915 15916(define_expand "atansf2" 15917 [(parallel [(set (match_operand:SF 0 "register_operand" "") 15918 (unspec:SF [(match_dup 2) 15919 (match_operand:SF 1 "register_operand" "")] 15920 UNSPEC_FPATAN)) 15921 (clobber (match_scratch:SF 3 ""))])] 15922 "TARGET_USE_FANCY_MATH_387 15923 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15924 && flag_unsafe_math_optimizations" 15925{ 15926 operands[2] = gen_reg_rtx (SFmode); 15927 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */ 15928}) 15929 15930(define_insn "atan2xf3_1" 15931 [(set (match_operand:XF 0 "register_operand" "=f") 15932 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15933 (match_operand:XF 1 "register_operand" "u")] 15934 UNSPEC_FPATAN)) 15935 (clobber (match_scratch:XF 3 "=1"))] 15936 "TARGET_USE_FANCY_MATH_387 15937 && flag_unsafe_math_optimizations" 15938 "fpatan" 15939 [(set_attr "type" "fpspc") 15940 (set_attr "mode" "XF")]) 15941 15942(define_expand "atan2xf3" 15943 [(use (match_operand:XF 0 "register_operand" "")) 15944 (use (match_operand:XF 2 "register_operand" "")) 15945 (use (match_operand:XF 1 "register_operand" ""))] 15946 "TARGET_USE_FANCY_MATH_387 15947 && flag_unsafe_math_optimizations" 15948{ 15949 rtx copy = gen_reg_rtx (XFmode); 15950 emit_move_insn (copy, operands[1]); 15951 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2])); 15952 DONE; 15953}) 15954 15955(define_expand "atanxf2" 15956 [(parallel [(set (match_operand:XF 0 "register_operand" "") 15957 (unspec:XF [(match_dup 2) 15958 (match_operand:XF 1 "register_operand" "")] 15959 UNSPEC_FPATAN)) 15960 (clobber (match_scratch:XF 3 ""))])] 15961 "TARGET_USE_FANCY_MATH_387 15962 && flag_unsafe_math_optimizations" 15963{ 15964 operands[2] = gen_reg_rtx (XFmode); 15965 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 15966}) 15967 15968(define_expand "asindf2" 15969 [(set (match_dup 2) 15970 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 15971 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 15972 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 15973 (set (match_dup 6) (sqrt:XF (match_dup 5))) 15974 (parallel [(set (match_dup 7) 15975 (unspec:XF [(match_dup 6) (match_dup 2)] 15976 UNSPEC_FPATAN)) 15977 (clobber (match_scratch:XF 8 ""))]) 15978 (set (match_operand:DF 0 "register_operand" "") 15979 (float_truncate:DF (match_dup 7)))] 15980 "TARGET_USE_FANCY_MATH_387 15981 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15982 && flag_unsafe_math_optimizations" 15983{ 15984 int i; 15985 15986 for (i=2; i<8; i++) 15987 operands[i] = gen_reg_rtx (XFmode); 15988 15989 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 15990}) 15991 15992(define_expand "asinsf2" 15993 [(set (match_dup 2) 15994 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 15995 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 15996 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 15997 (set (match_dup 6) (sqrt:XF (match_dup 5))) 15998 (parallel [(set (match_dup 7) 15999 (unspec:XF [(match_dup 6) (match_dup 2)] 16000 UNSPEC_FPATAN)) 16001 (clobber (match_scratch:XF 8 ""))]) 16002 (set (match_operand:SF 0 "register_operand" "") 16003 (float_truncate:SF (match_dup 7)))] 16004 "TARGET_USE_FANCY_MATH_387 16005 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16006 && flag_unsafe_math_optimizations" 16007{ 16008 int i; 16009 16010 for (i=2; i<8; i++) 16011 operands[i] = gen_reg_rtx (XFmode); 16012 16013 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16014}) 16015 16016(define_expand "asinxf2" 16017 [(set (match_dup 2) 16018 (mult:XF (match_operand:XF 1 "register_operand" "") 16019 (match_dup 1))) 16020 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 16021 (set (match_dup 5) (sqrt:XF (match_dup 4))) 16022 (parallel [(set (match_operand:XF 0 "register_operand" "") 16023 (unspec:XF [(match_dup 5) (match_dup 1)] 16024 UNSPEC_FPATAN)) 16025 (clobber (match_scratch:XF 6 ""))])] 16026 "TARGET_USE_FANCY_MATH_387 16027 && flag_unsafe_math_optimizations" 16028{ 16029 int i; 16030 16031 for (i=2; i<6; i++) 16032 operands[i] = gen_reg_rtx (XFmode); 16033 16034 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16035}) 16036 16037(define_expand "acosdf2" 16038 [(set (match_dup 2) 16039 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16040 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16041 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16042 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16043 (parallel [(set (match_dup 7) 16044 (unspec:XF [(match_dup 2) (match_dup 6)] 16045 UNSPEC_FPATAN)) 16046 (clobber (match_scratch:XF 8 ""))]) 16047 (set (match_operand:DF 0 "register_operand" "") 16048 (float_truncate:DF (match_dup 7)))] 16049 "TARGET_USE_FANCY_MATH_387 16050 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16051 && flag_unsafe_math_optimizations" 16052{ 16053 int i; 16054 16055 for (i=2; i<8; i++) 16056 operands[i] = gen_reg_rtx (XFmode); 16057 16058 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16059}) 16060 16061(define_expand "acossf2" 16062 [(set (match_dup 2) 16063 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16064 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16065 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16066 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16067 (parallel [(set (match_dup 7) 16068 (unspec:XF [(match_dup 2) (match_dup 6)] 16069 UNSPEC_FPATAN)) 16070 (clobber (match_scratch:XF 8 ""))]) 16071 (set (match_operand:SF 0 "register_operand" "") 16072 (float_truncate:SF (match_dup 7)))] 16073 "TARGET_USE_FANCY_MATH_387 16074 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16075 && flag_unsafe_math_optimizations" 16076{ 16077 int i; 16078 16079 for (i=2; i<8; i++) 16080 operands[i] = gen_reg_rtx (XFmode); 16081 16082 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16083}) 16084 16085(define_expand "acosxf2" 16086 [(set (match_dup 2) 16087 (mult:XF (match_operand:XF 1 "register_operand" "") 16088 (match_dup 1))) 16089 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 16090 (set (match_dup 5) (sqrt:XF (match_dup 4))) 16091 (parallel [(set (match_operand:XF 0 "register_operand" "") 16092 (unspec:XF [(match_dup 1) (match_dup 5)] 16093 UNSPEC_FPATAN)) 16094 (clobber (match_scratch:XF 6 ""))])] 16095 "TARGET_USE_FANCY_MATH_387 16096 && flag_unsafe_math_optimizations" 16097{ 16098 int i; 16099 16100 for (i=2; i<6; i++) 16101 operands[i] = gen_reg_rtx (XFmode); 16102 16103 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16104}) 16105 16106(define_insn "fyl2x_xf3" 16107 [(set (match_operand:XF 0 "register_operand" "=f") 16108 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16109 (match_operand:XF 1 "register_operand" "u")] 16110 UNSPEC_FYL2X)) 16111 (clobber (match_scratch:XF 3 "=1"))] 16112 "TARGET_USE_FANCY_MATH_387 16113 && flag_unsafe_math_optimizations" 16114 "fyl2x" 16115 [(set_attr "type" "fpspc") 16116 (set_attr "mode" "XF")]) 16117 16118(define_expand "logsf2" 16119 [(set (match_dup 2) 16120 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16121 (parallel [(set (match_dup 4) 16122 (unspec:XF [(match_dup 2) 16123 (match_dup 3)] UNSPEC_FYL2X)) 16124 (clobber (match_scratch:XF 5 ""))]) 16125 (set (match_operand:SF 0 "register_operand" "") 16126 (float_truncate:SF (match_dup 4)))] 16127 "TARGET_USE_FANCY_MATH_387 16128 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16129 && flag_unsafe_math_optimizations" 16130{ 16131 rtx temp; 16132 16133 operands[2] = gen_reg_rtx (XFmode); 16134 operands[3] = gen_reg_rtx (XFmode); 16135 operands[4] = gen_reg_rtx (XFmode); 16136 16137 temp = standard_80387_constant_rtx (4); /* fldln2 */ 16138 emit_move_insn (operands[3], temp); 16139}) 16140 16141(define_expand "logdf2" 16142 [(set (match_dup 2) 16143 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16144 (parallel [(set (match_dup 4) 16145 (unspec:XF [(match_dup 2) 16146 (match_dup 3)] UNSPEC_FYL2X)) 16147 (clobber (match_scratch:XF 5 ""))]) 16148 (set (match_operand:DF 0 "register_operand" "") 16149 (float_truncate:DF (match_dup 4)))] 16150 "TARGET_USE_FANCY_MATH_387 16151 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16152 && flag_unsafe_math_optimizations" 16153{ 16154 rtx temp; 16155 16156 operands[2] = gen_reg_rtx (XFmode); 16157 operands[3] = gen_reg_rtx (XFmode); 16158 operands[4] = gen_reg_rtx (XFmode); 16159 16160 temp = standard_80387_constant_rtx (4); /* fldln2 */ 16161 emit_move_insn (operands[3], temp); 16162}) 16163 16164(define_expand "logxf2" 16165 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16166 (unspec:XF [(match_operand:XF 1 "register_operand" "") 16167 (match_dup 2)] UNSPEC_FYL2X)) 16168 (clobber (match_scratch:XF 3 ""))])] 16169 "TARGET_USE_FANCY_MATH_387 16170 && flag_unsafe_math_optimizations" 16171{ 16172 rtx temp; 16173 16174 operands[2] = gen_reg_rtx (XFmode); 16175 temp = standard_80387_constant_rtx (4); /* fldln2 */ 16176 emit_move_insn (operands[2], temp); 16177}) 16178 16179(define_expand "log10sf2" 16180 [(set (match_dup 2) 16181 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16182 (parallel [(set (match_dup 4) 16183 (unspec:XF [(match_dup 2) 16184 (match_dup 3)] UNSPEC_FYL2X)) 16185 (clobber (match_scratch:XF 5 ""))]) 16186 (set (match_operand:SF 0 "register_operand" "") 16187 (float_truncate:SF (match_dup 4)))] 16188 "TARGET_USE_FANCY_MATH_387 16189 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16190 && flag_unsafe_math_optimizations" 16191{ 16192 rtx temp; 16193 16194 operands[2] = gen_reg_rtx (XFmode); 16195 operands[3] = gen_reg_rtx (XFmode); 16196 operands[4] = gen_reg_rtx (XFmode); 16197 16198 temp = standard_80387_constant_rtx (3); /* fldlg2 */ 16199 emit_move_insn (operands[3], temp); 16200}) 16201 16202(define_expand "log10df2" 16203 [(set (match_dup 2) 16204 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16205 (parallel [(set (match_dup 4) 16206 (unspec:XF [(match_dup 2) 16207 (match_dup 3)] UNSPEC_FYL2X)) 16208 (clobber (match_scratch:XF 5 ""))]) 16209 (set (match_operand:DF 0 "register_operand" "") 16210 (float_truncate:DF (match_dup 4)))] 16211 "TARGET_USE_FANCY_MATH_387 16212 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16213 && flag_unsafe_math_optimizations" 16214{ 16215 rtx temp; 16216 16217 operands[2] = gen_reg_rtx (XFmode); 16218 operands[3] = gen_reg_rtx (XFmode); 16219 operands[4] = gen_reg_rtx (XFmode); 16220 16221 temp = standard_80387_constant_rtx (3); /* fldlg2 */ 16222 emit_move_insn (operands[3], temp); 16223}) 16224 16225(define_expand "log10xf2" 16226 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16227 (unspec:XF [(match_operand:XF 1 "register_operand" "") 16228 (match_dup 2)] UNSPEC_FYL2X)) 16229 (clobber (match_scratch:XF 3 ""))])] 16230 "TARGET_USE_FANCY_MATH_387 16231 && flag_unsafe_math_optimizations" 16232{ 16233 rtx temp; 16234 16235 operands[2] = gen_reg_rtx (XFmode); 16236 temp = standard_80387_constant_rtx (3); /* fldlg2 */ 16237 emit_move_insn (operands[2], temp); 16238}) 16239 16240(define_expand "log2sf2" 16241 [(set (match_dup 2) 16242 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16243 (parallel [(set (match_dup 4) 16244 (unspec:XF [(match_dup 2) 16245 (match_dup 3)] UNSPEC_FYL2X)) 16246 (clobber (match_scratch:XF 5 ""))]) 16247 (set (match_operand:SF 0 "register_operand" "") 16248 (float_truncate:SF (match_dup 4)))] 16249 "TARGET_USE_FANCY_MATH_387 16250 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16251 && flag_unsafe_math_optimizations" 16252{ 16253 operands[2] = gen_reg_rtx (XFmode); 16254 operands[3] = gen_reg_rtx (XFmode); 16255 operands[4] = gen_reg_rtx (XFmode); 16256 16257 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16258}) 16259 16260(define_expand "log2df2" 16261 [(set (match_dup 2) 16262 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16263 (parallel [(set (match_dup 4) 16264 (unspec:XF [(match_dup 2) 16265 (match_dup 3)] UNSPEC_FYL2X)) 16266 (clobber (match_scratch:XF 5 ""))]) 16267 (set (match_operand:DF 0 "register_operand" "") 16268 (float_truncate:DF (match_dup 4)))] 16269 "TARGET_USE_FANCY_MATH_387 16270 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16271 && flag_unsafe_math_optimizations" 16272{ 16273 operands[2] = gen_reg_rtx (XFmode); 16274 operands[3] = gen_reg_rtx (XFmode); 16275 operands[4] = gen_reg_rtx (XFmode); 16276 16277 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16278}) 16279 16280(define_expand "log2xf2" 16281 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16282 (unspec:XF [(match_operand:XF 1 "register_operand" "") 16283 (match_dup 2)] UNSPEC_FYL2X)) 16284 (clobber (match_scratch:XF 3 ""))])] 16285 "TARGET_USE_FANCY_MATH_387 16286 && flag_unsafe_math_optimizations" 16287{ 16288 operands[2] = gen_reg_rtx (XFmode); 16289 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 16290}) 16291 16292(define_insn "fyl2xp1_xf3" 16293 [(set (match_operand:XF 0 "register_operand" "=f") 16294 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16295 (match_operand:XF 1 "register_operand" "u")] 16296 UNSPEC_FYL2XP1)) 16297 (clobber (match_scratch:XF 3 "=1"))] 16298 "TARGET_USE_FANCY_MATH_387 16299 && flag_unsafe_math_optimizations" 16300 "fyl2xp1" 16301 [(set_attr "type" "fpspc") 16302 (set_attr "mode" "XF")]) 16303 16304(define_expand "log1psf2" 16305 [(use (match_operand:SF 0 "register_operand" "")) 16306 (use (match_operand:SF 1 "register_operand" ""))] 16307 "TARGET_USE_FANCY_MATH_387 16308 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16309 && flag_unsafe_math_optimizations" 16310{ 16311 rtx op0 = gen_reg_rtx (XFmode); 16312 rtx op1 = gen_reg_rtx (XFmode); 16313 16314 emit_insn (gen_extendsfxf2 (op1, operands[1])); 16315 ix86_emit_i387_log1p (op0, op1); 16316 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 16317 DONE; 16318}) 16319 16320(define_expand "log1pdf2" 16321 [(use (match_operand:DF 0 "register_operand" "")) 16322 (use (match_operand:DF 1 "register_operand" ""))] 16323 "TARGET_USE_FANCY_MATH_387 16324 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16325 && flag_unsafe_math_optimizations" 16326{ 16327 rtx op0 = gen_reg_rtx (XFmode); 16328 rtx op1 = gen_reg_rtx (XFmode); 16329 16330 emit_insn (gen_extenddfxf2 (op1, operands[1])); 16331 ix86_emit_i387_log1p (op0, op1); 16332 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 16333 DONE; 16334}) 16335 16336(define_expand "log1pxf2" 16337 [(use (match_operand:XF 0 "register_operand" "")) 16338 (use (match_operand:XF 1 "register_operand" ""))] 16339 "TARGET_USE_FANCY_MATH_387 16340 && flag_unsafe_math_optimizations" 16341{ 16342 ix86_emit_i387_log1p (operands[0], operands[1]); 16343 DONE; 16344}) 16345 16346(define_insn "*fxtractxf3" 16347 [(set (match_operand:XF 0 "register_operand" "=f") 16348 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 16349 UNSPEC_XTRACT_FRACT)) 16350 (set (match_operand:XF 1 "register_operand" "=u") 16351 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))] 16352 "TARGET_USE_FANCY_MATH_387 16353 && flag_unsafe_math_optimizations" 16354 "fxtract" 16355 [(set_attr "type" "fpspc") 16356 (set_attr "mode" "XF")]) 16357 16358(define_expand "logbsf2" 16359 [(set (match_dup 2) 16360 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16361 (parallel [(set (match_dup 3) 16362 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT)) 16363 (set (match_dup 4) 16364 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]) 16365 (set (match_operand:SF 0 "register_operand" "") 16366 (float_truncate:SF (match_dup 4)))] 16367 "TARGET_USE_FANCY_MATH_387 16368 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16369 && flag_unsafe_math_optimizations" 16370{ 16371 operands[2] = gen_reg_rtx (XFmode); 16372 operands[3] = gen_reg_rtx (XFmode); 16373 operands[4] = gen_reg_rtx (XFmode); 16374}) 16375 16376(define_expand "logbdf2" 16377 [(set (match_dup 2) 16378 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16379 (parallel [(set (match_dup 3) 16380 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT)) 16381 (set (match_dup 4) 16382 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]) 16383 (set (match_operand:DF 0 "register_operand" "") 16384 (float_truncate:DF (match_dup 4)))] 16385 "TARGET_USE_FANCY_MATH_387 16386 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16387 && flag_unsafe_math_optimizations" 16388{ 16389 operands[2] = gen_reg_rtx (XFmode); 16390 operands[3] = gen_reg_rtx (XFmode); 16391 operands[4] = gen_reg_rtx (XFmode); 16392}) 16393 16394(define_expand "logbxf2" 16395 [(parallel [(set (match_dup 2) 16396 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 16397 UNSPEC_XTRACT_FRACT)) 16398 (set (match_operand:XF 0 "register_operand" "") 16399 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 16400 "TARGET_USE_FANCY_MATH_387 16401 && flag_unsafe_math_optimizations" 16402{ 16403 operands[2] = gen_reg_rtx (XFmode); 16404}) 16405 16406(define_expand "ilogbsi2" 16407 [(parallel [(set (match_dup 2) 16408 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 16409 UNSPEC_XTRACT_FRACT)) 16410 (set (match_operand:XF 3 "register_operand" "") 16411 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))]) 16412 (parallel [(set (match_operand:SI 0 "register_operand" "") 16413 (fix:SI (match_dup 3))) 16414 (clobber (reg:CC FLAGS_REG))])] 16415 "TARGET_USE_FANCY_MATH_387 16416 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16417 && flag_unsafe_math_optimizations" 16418{ 16419 operands[2] = gen_reg_rtx (XFmode); 16420 operands[3] = gen_reg_rtx (XFmode); 16421}) 16422 16423(define_insn "*f2xm1xf2" 16424 [(set (match_operand:XF 0 "register_operand" "=f") 16425 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16426 UNSPEC_F2XM1))] 16427 "TARGET_USE_FANCY_MATH_387 16428 && flag_unsafe_math_optimizations" 16429 "f2xm1" 16430 [(set_attr "type" "fpspc") 16431 (set_attr "mode" "XF")]) 16432 16433(define_insn "*fscalexf4" 16434 [(set (match_operand:XF 0 "register_operand" "=f") 16435 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16436 (match_operand:XF 3 "register_operand" "1")] 16437 UNSPEC_FSCALE_FRACT)) 16438 (set (match_operand:XF 1 "register_operand" "=u") 16439 (unspec:XF [(match_dup 2) (match_dup 3)] 16440 UNSPEC_FSCALE_EXP))] 16441 "TARGET_USE_FANCY_MATH_387 16442 && flag_unsafe_math_optimizations" 16443 "fscale" 16444 [(set_attr "type" "fpspc") 16445 (set_attr "mode" "XF")]) 16446 16447(define_expand "expsf2" 16448 [(set (match_dup 2) 16449 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16450 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16451 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16452 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16453 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16454 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 16455 (parallel [(set (match_dup 10) 16456 (unspec:XF [(match_dup 9) (match_dup 5)] 16457 UNSPEC_FSCALE_FRACT)) 16458 (set (match_dup 11) 16459 (unspec:XF [(match_dup 9) (match_dup 5)] 16460 UNSPEC_FSCALE_EXP))]) 16461 (set (match_operand:SF 0 "register_operand" "") 16462 (float_truncate:SF (match_dup 10)))] 16463 "TARGET_USE_FANCY_MATH_387 16464 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16465 && flag_unsafe_math_optimizations" 16466{ 16467 rtx temp; 16468 int i; 16469 16470 for (i=2; i<12; i++) 16471 operands[i] = gen_reg_rtx (XFmode); 16472 temp = standard_80387_constant_rtx (5); /* fldl2e */ 16473 emit_move_insn (operands[3], temp); 16474 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 16475}) 16476 16477(define_expand "expdf2" 16478 [(set (match_dup 2) 16479 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16480 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16481 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16482 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16483 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16484 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 16485 (parallel [(set (match_dup 10) 16486 (unspec:XF [(match_dup 9) (match_dup 5)] 16487 UNSPEC_FSCALE_FRACT)) 16488 (set (match_dup 11) 16489 (unspec:XF [(match_dup 9) (match_dup 5)] 16490 UNSPEC_FSCALE_EXP))]) 16491 (set (match_operand:DF 0 "register_operand" "") 16492 (float_truncate:DF (match_dup 10)))] 16493 "TARGET_USE_FANCY_MATH_387 16494 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16495 && flag_unsafe_math_optimizations" 16496{ 16497 rtx temp; 16498 int i; 16499 16500 for (i=2; i<12; i++) 16501 operands[i] = gen_reg_rtx (XFmode); 16502 temp = standard_80387_constant_rtx (5); /* fldl2e */ 16503 emit_move_insn (operands[3], temp); 16504 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 16505}) 16506 16507(define_expand "expxf2" 16508 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 16509 (match_dup 2))) 16510 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 16511 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 16512 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 16513 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 16514 (parallel [(set (match_operand:XF 0 "register_operand" "") 16515 (unspec:XF [(match_dup 8) (match_dup 4)] 16516 UNSPEC_FSCALE_FRACT)) 16517 (set (match_dup 9) 16518 (unspec:XF [(match_dup 8) (match_dup 4)] 16519 UNSPEC_FSCALE_EXP))])] 16520 "TARGET_USE_FANCY_MATH_387 16521 && flag_unsafe_math_optimizations" 16522{ 16523 rtx temp; 16524 int i; 16525 16526 for (i=2; i<10; i++) 16527 operands[i] = gen_reg_rtx (XFmode); 16528 temp = standard_80387_constant_rtx (5); /* fldl2e */ 16529 emit_move_insn (operands[2], temp); 16530 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ 16531}) 16532 16533(define_expand "exp10sf2" 16534 [(set (match_dup 2) 16535 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16536 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16537 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16538 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16539 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16540 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 16541 (parallel [(set (match_dup 10) 16542 (unspec:XF [(match_dup 9) (match_dup 5)] 16543 UNSPEC_FSCALE_FRACT)) 16544 (set (match_dup 11) 16545 (unspec:XF [(match_dup 9) (match_dup 5)] 16546 UNSPEC_FSCALE_EXP))]) 16547 (set (match_operand:SF 0 "register_operand" "") 16548 (float_truncate:SF (match_dup 10)))] 16549 "TARGET_USE_FANCY_MATH_387 16550 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16551 && flag_unsafe_math_optimizations" 16552{ 16553 rtx temp; 16554 int i; 16555 16556 for (i=2; i<12; i++) 16557 operands[i] = gen_reg_rtx (XFmode); 16558 temp = standard_80387_constant_rtx (6); /* fldl2t */ 16559 emit_move_insn (operands[3], temp); 16560 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 16561}) 16562 16563(define_expand "exp10df2" 16564 [(set (match_dup 2) 16565 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16566 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16567 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16568 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16569 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16570 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 16571 (parallel [(set (match_dup 10) 16572 (unspec:XF [(match_dup 9) (match_dup 5)] 16573 UNSPEC_FSCALE_FRACT)) 16574 (set (match_dup 11) 16575 (unspec:XF [(match_dup 9) (match_dup 5)] 16576 UNSPEC_FSCALE_EXP))]) 16577 (set (match_operand:DF 0 "register_operand" "") 16578 (float_truncate:DF (match_dup 10)))] 16579 "TARGET_USE_FANCY_MATH_387 16580 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16581 && flag_unsafe_math_optimizations" 16582{ 16583 rtx temp; 16584 int i; 16585 16586 for (i=2; i<12; i++) 16587 operands[i] = gen_reg_rtx (XFmode); 16588 temp = standard_80387_constant_rtx (6); /* fldl2t */ 16589 emit_move_insn (operands[3], temp); 16590 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 16591}) 16592 16593(define_expand "exp10xf2" 16594 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 16595 (match_dup 2))) 16596 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 16597 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 16598 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 16599 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 16600 (parallel [(set (match_operand:XF 0 "register_operand" "") 16601 (unspec:XF [(match_dup 8) (match_dup 4)] 16602 UNSPEC_FSCALE_FRACT)) 16603 (set (match_dup 9) 16604 (unspec:XF [(match_dup 8) (match_dup 4)] 16605 UNSPEC_FSCALE_EXP))])] 16606 "TARGET_USE_FANCY_MATH_387 16607 && flag_unsafe_math_optimizations" 16608{ 16609 rtx temp; 16610 int i; 16611 16612 for (i=2; i<10; i++) 16613 operands[i] = gen_reg_rtx (XFmode); 16614 temp = standard_80387_constant_rtx (6); /* fldl2t */ 16615 emit_move_insn (operands[2], temp); 16616 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ 16617}) 16618 16619(define_expand "exp2sf2" 16620 [(set (match_dup 2) 16621 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16622 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT)) 16623 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3))) 16624 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1)) 16625 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6))) 16626 (parallel [(set (match_dup 8) 16627 (unspec:XF [(match_dup 7) (match_dup 3)] 16628 UNSPEC_FSCALE_FRACT)) 16629 (set (match_dup 9) 16630 (unspec:XF [(match_dup 7) (match_dup 3)] 16631 UNSPEC_FSCALE_EXP))]) 16632 (set (match_operand:SF 0 "register_operand" "") 16633 (float_truncate:SF (match_dup 8)))] 16634 "TARGET_USE_FANCY_MATH_387 16635 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16636 && flag_unsafe_math_optimizations" 16637{ 16638 int i; 16639 16640 for (i=2; i<10; i++) 16641 operands[i] = gen_reg_rtx (XFmode); 16642 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */ 16643}) 16644 16645(define_expand "exp2df2" 16646 [(set (match_dup 2) 16647 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16648 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT)) 16649 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3))) 16650 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1)) 16651 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6))) 16652 (parallel [(set (match_dup 8) 16653 (unspec:XF [(match_dup 7) (match_dup 3)] 16654 UNSPEC_FSCALE_FRACT)) 16655 (set (match_dup 9) 16656 (unspec:XF [(match_dup 7) (match_dup 3)] 16657 UNSPEC_FSCALE_EXP))]) 16658 (set (match_operand:DF 0 "register_operand" "") 16659 (float_truncate:DF (match_dup 8)))] 16660 "TARGET_USE_FANCY_MATH_387 16661 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16662 && flag_unsafe_math_optimizations" 16663{ 16664 int i; 16665 16666 for (i=2; i<10; i++) 16667 operands[i] = gen_reg_rtx (XFmode); 16668 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */ 16669}) 16670 16671(define_expand "exp2xf2" 16672 [(set (match_dup 2) (match_operand:XF 1 "register_operand" "")) 16673 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT)) 16674 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3))) 16675 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1)) 16676 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6))) 16677 (parallel [(set (match_operand:XF 0 "register_operand" "") 16678 (unspec:XF [(match_dup 7) (match_dup 3)] 16679 UNSPEC_FSCALE_FRACT)) 16680 (set (match_dup 8) 16681 (unspec:XF [(match_dup 7) (match_dup 3)] 16682 UNSPEC_FSCALE_EXP))])] 16683 "TARGET_USE_FANCY_MATH_387 16684 && flag_unsafe_math_optimizations" 16685{ 16686 int i; 16687 16688 for (i=2; i<9; i++) 16689 operands[i] = gen_reg_rtx (XFmode); 16690 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */ 16691}) 16692 16693(define_expand "expm1df2" 16694 [(set (match_dup 2) 16695 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16696 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16697 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16698 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16699 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16700 (parallel [(set (match_dup 8) 16701 (unspec:XF [(match_dup 7) (match_dup 5)] 16702 UNSPEC_FSCALE_FRACT)) 16703 (set (match_dup 9) 16704 (unspec:XF [(match_dup 7) (match_dup 5)] 16705 UNSPEC_FSCALE_EXP))]) 16706 (parallel [(set (match_dup 11) 16707 (unspec:XF [(match_dup 10) (match_dup 9)] 16708 UNSPEC_FSCALE_FRACT)) 16709 (set (match_dup 12) 16710 (unspec:XF [(match_dup 10) (match_dup 9)] 16711 UNSPEC_FSCALE_EXP))]) 16712 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10))) 16713 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8))) 16714 (set (match_operand:DF 0 "register_operand" "") 16715 (float_truncate:DF (match_dup 14)))] 16716 "TARGET_USE_FANCY_MATH_387 16717 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16718 && flag_unsafe_math_optimizations" 16719{ 16720 rtx temp; 16721 int i; 16722 16723 for (i=2; i<15; i++) 16724 operands[i] = gen_reg_rtx (XFmode); 16725 temp = standard_80387_constant_rtx (5); /* fldl2e */ 16726 emit_move_insn (operands[3], temp); 16727 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */ 16728}) 16729 16730(define_expand "expm1sf2" 16731 [(set (match_dup 2) 16732 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16733 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16734 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16735 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16736 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16737 (parallel [(set (match_dup 8) 16738 (unspec:XF [(match_dup 7) (match_dup 5)] 16739 UNSPEC_FSCALE_FRACT)) 16740 (set (match_dup 9) 16741 (unspec:XF [(match_dup 7) (match_dup 5)] 16742 UNSPEC_FSCALE_EXP))]) 16743 (parallel [(set (match_dup 11) 16744 (unspec:XF [(match_dup 10) (match_dup 9)] 16745 UNSPEC_FSCALE_FRACT)) 16746 (set (match_dup 12) 16747 (unspec:XF [(match_dup 10) (match_dup 9)] 16748 UNSPEC_FSCALE_EXP))]) 16749 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10))) 16750 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8))) 16751 (set (match_operand:SF 0 "register_operand" "") 16752 (float_truncate:SF (match_dup 14)))] 16753 "TARGET_USE_FANCY_MATH_387 16754 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16755 && flag_unsafe_math_optimizations" 16756{ 16757 rtx temp; 16758 int i; 16759 16760 for (i=2; i<15; i++) 16761 operands[i] = gen_reg_rtx (XFmode); 16762 temp = standard_80387_constant_rtx (5); /* fldl2e */ 16763 emit_move_insn (operands[3], temp); 16764 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */ 16765}) 16766 16767(define_expand "expm1xf2" 16768 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 16769 (match_dup 2))) 16770 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 16771 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 16772 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 16773 (parallel [(set (match_dup 7) 16774 (unspec:XF [(match_dup 6) (match_dup 4)] 16775 UNSPEC_FSCALE_FRACT)) 16776 (set (match_dup 8) 16777 (unspec:XF [(match_dup 6) (match_dup 4)] 16778 UNSPEC_FSCALE_EXP))]) 16779 (parallel [(set (match_dup 10) 16780 (unspec:XF [(match_dup 9) (match_dup 8)] 16781 UNSPEC_FSCALE_FRACT)) 16782 (set (match_dup 11) 16783 (unspec:XF [(match_dup 9) (match_dup 8)] 16784 UNSPEC_FSCALE_EXP))]) 16785 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9))) 16786 (set (match_operand:XF 0 "register_operand" "") 16787 (plus:XF (match_dup 12) (match_dup 7)))] 16788 "TARGET_USE_FANCY_MATH_387 16789 && flag_unsafe_math_optimizations" 16790{ 16791 rtx temp; 16792 int i; 16793 16794 for (i=2; i<13; i++) 16795 operands[i] = gen_reg_rtx (XFmode); 16796 temp = standard_80387_constant_rtx (5); /* fldl2e */ 16797 emit_move_insn (operands[2], temp); 16798 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */ 16799}) 16800 16801(define_expand "ldexpdf3" 16802 [(set (match_dup 3) 16803 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16804 (set (match_dup 4) 16805 (float:XF (match_operand:SI 2 "register_operand" ""))) 16806 (parallel [(set (match_dup 5) 16807 (unspec:XF [(match_dup 3) (match_dup 4)] 16808 UNSPEC_FSCALE_FRACT)) 16809 (set (match_dup 6) 16810 (unspec:XF [(match_dup 3) (match_dup 4)] 16811 UNSPEC_FSCALE_EXP))]) 16812 (set (match_operand:DF 0 "register_operand" "") 16813 (float_truncate:DF (match_dup 5)))] 16814 "TARGET_USE_FANCY_MATH_387 16815 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16816 && flag_unsafe_math_optimizations" 16817{ 16818 int i; 16819 16820 for (i=3; i<7; i++) 16821 operands[i] = gen_reg_rtx (XFmode); 16822}) 16823 16824(define_expand "ldexpsf3" 16825 [(set (match_dup 3) 16826 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16827 (set (match_dup 4) 16828 (float:XF (match_operand:SI 2 "register_operand" ""))) 16829 (parallel [(set (match_dup 5) 16830 (unspec:XF [(match_dup 3) (match_dup 4)] 16831 UNSPEC_FSCALE_FRACT)) 16832 (set (match_dup 6) 16833 (unspec:XF [(match_dup 3) (match_dup 4)] 16834 UNSPEC_FSCALE_EXP))]) 16835 (set (match_operand:SF 0 "register_operand" "") 16836 (float_truncate:SF (match_dup 5)))] 16837 "TARGET_USE_FANCY_MATH_387 16838 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16839 && flag_unsafe_math_optimizations" 16840{ 16841 int i; 16842 16843 for (i=3; i<7; i++) 16844 operands[i] = gen_reg_rtx (XFmode); 16845}) 16846 16847(define_expand "ldexpxf3" 16848 [(set (match_dup 3) 16849 (float:XF (match_operand:SI 2 "register_operand" ""))) 16850 (parallel [(set (match_operand:XF 0 " register_operand" "") 16851 (unspec:XF [(match_operand:XF 1 "register_operand" "") 16852 (match_dup 3)] 16853 UNSPEC_FSCALE_FRACT)) 16854 (set (match_dup 4) 16855 (unspec:XF [(match_dup 1) (match_dup 3)] 16856 UNSPEC_FSCALE_EXP))])] 16857 "TARGET_USE_FANCY_MATH_387 16858 && flag_unsafe_math_optimizations" 16859{ 16860 int i; 16861 16862 for (i=3; i<5; i++) 16863 operands[i] = gen_reg_rtx (XFmode); 16864}) 16865 16866 16867(define_insn "frndintxf2" 16868 [(set (match_operand:XF 0 "register_operand" "=f") 16869 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16870 UNSPEC_FRNDINT))] 16871 "TARGET_USE_FANCY_MATH_387 16872 && flag_unsafe_math_optimizations" 16873 "frndint" 16874 [(set_attr "type" "fpspc") 16875 (set_attr "mode" "XF")]) 16876 16877(define_expand "rintdf2" 16878 [(use (match_operand:DF 0 "register_operand" "")) 16879 (use (match_operand:DF 1 "register_operand" ""))] 16880 "TARGET_USE_FANCY_MATH_387 16881 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16882 && flag_unsafe_math_optimizations" 16883{ 16884 rtx op0 = gen_reg_rtx (XFmode); 16885 rtx op1 = gen_reg_rtx (XFmode); 16886 16887 emit_insn (gen_extenddfxf2 (op1, operands[1])); 16888 emit_insn (gen_frndintxf2 (op0, op1)); 16889 16890 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 16891 DONE; 16892}) 16893 16894(define_expand "rintsf2" 16895 [(use (match_operand:SF 0 "register_operand" "")) 16896 (use (match_operand:SF 1 "register_operand" ""))] 16897 "TARGET_USE_FANCY_MATH_387 16898 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16899 && flag_unsafe_math_optimizations" 16900{ 16901 rtx op0 = gen_reg_rtx (XFmode); 16902 rtx op1 = gen_reg_rtx (XFmode); 16903 16904 emit_insn (gen_extendsfxf2 (op1, operands[1])); 16905 emit_insn (gen_frndintxf2 (op0, op1)); 16906 16907 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 16908 DONE; 16909}) 16910 16911(define_expand "rintxf2" 16912 [(use (match_operand:XF 0 "register_operand" "")) 16913 (use (match_operand:XF 1 "register_operand" ""))] 16914 "TARGET_USE_FANCY_MATH_387 16915 && flag_unsafe_math_optimizations" 16916{ 16917 emit_insn (gen_frndintxf2 (operands[0], operands[1])); 16918 DONE; 16919}) 16920 16921(define_insn_and_split "*fistdi2_1" 16922 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 16923 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 16924 UNSPEC_FIST))] 16925 "TARGET_USE_FANCY_MATH_387 16926 && flag_unsafe_math_optimizations 16927 && !(reload_completed || reload_in_progress)" 16928 "#" 16929 "&& 1" 16930 [(const_int 0)] 16931{ 16932 if (memory_operand (operands[0], VOIDmode)) 16933 emit_insn (gen_fistdi2 (operands[0], operands[1])); 16934 else 16935 { 16936 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP); 16937 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1], 16938 operands[2])); 16939 } 16940 DONE; 16941} 16942 [(set_attr "type" "fpspc") 16943 (set_attr "mode" "DI")]) 16944 16945(define_insn "fistdi2" 16946 [(set (match_operand:DI 0 "memory_operand" "=m") 16947 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 16948 UNSPEC_FIST)) 16949 (clobber (match_scratch:XF 2 "=&1f"))] 16950 "TARGET_USE_FANCY_MATH_387 16951 && flag_unsafe_math_optimizations" 16952 "* return output_fix_trunc (insn, operands, 0);" 16953 [(set_attr "type" "fpspc") 16954 (set_attr "mode" "DI")]) 16955 16956(define_insn "fistdi2_with_temp" 16957 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 16958 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 16959 UNSPEC_FIST)) 16960 (clobber (match_operand:DI 2 "memory_operand" "=m,m")) 16961 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 16962 "TARGET_USE_FANCY_MATH_387 16963 && flag_unsafe_math_optimizations" 16964 "#" 16965 [(set_attr "type" "fpspc") 16966 (set_attr "mode" "DI")]) 16967 16968(define_split 16969 [(set (match_operand:DI 0 "register_operand" "") 16970 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 16971 UNSPEC_FIST)) 16972 (clobber (match_operand:DI 2 "memory_operand" "")) 16973 (clobber (match_scratch 3 ""))] 16974 "reload_completed" 16975 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 16976 (clobber (match_dup 3))]) 16977 (set (match_dup 0) (match_dup 2))] 16978 "") 16979 16980(define_split 16981 [(set (match_operand:DI 0 "memory_operand" "") 16982 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 16983 UNSPEC_FIST)) 16984 (clobber (match_operand:DI 2 "memory_operand" "")) 16985 (clobber (match_scratch 3 ""))] 16986 "reload_completed" 16987 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 16988 (clobber (match_dup 3))])] 16989 "") 16990 16991(define_insn_and_split "*fist<mode>2_1" 16992 [(set (match_operand:X87MODEI12 0 "register_operand" "=r") 16993 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 16994 UNSPEC_FIST))] 16995 "TARGET_USE_FANCY_MATH_387 16996 && flag_unsafe_math_optimizations 16997 && !(reload_completed || reload_in_progress)" 16998 "#" 16999 "&& 1" 17000 [(const_int 0)] 17001{ 17002 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17003 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1], 17004 operands[2])); 17005 DONE; 17006} 17007 [(set_attr "type" "fpspc") 17008 (set_attr "mode" "<MODE>")]) 17009 17010(define_insn "fist<mode>2" 17011 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 17012 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17013 UNSPEC_FIST))] 17014 "TARGET_USE_FANCY_MATH_387 17015 && flag_unsafe_math_optimizations" 17016 "* return output_fix_trunc (insn, operands, 0);" 17017 [(set_attr "type" "fpspc") 17018 (set_attr "mode" "<MODE>")]) 17019 17020(define_insn "fist<mode>2_with_temp" 17021 [(set (match_operand:X87MODEI12 0 "register_operand" "=r") 17022 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17023 UNSPEC_FIST)) 17024 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))] 17025 "TARGET_USE_FANCY_MATH_387 17026 && flag_unsafe_math_optimizations" 17027 "#" 17028 [(set_attr "type" "fpspc") 17029 (set_attr "mode" "<MODE>")]) 17030 17031(define_split 17032 [(set (match_operand:X87MODEI12 0 "register_operand" "") 17033 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17034 UNSPEC_FIST)) 17035 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))] 17036 "reload_completed" 17037 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] 17038 UNSPEC_FIST)) 17039 (set (match_dup 0) (match_dup 2))] 17040 "") 17041 17042(define_split 17043 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 17044 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17045 UNSPEC_FIST)) 17046 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))] 17047 "reload_completed" 17048 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] 17049 UNSPEC_FIST))] 17050 "") 17051 17052(define_expand "lrint<mode>2" 17053 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") 17054 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] 17055 UNSPEC_FIST))] 17056 "TARGET_USE_FANCY_MATH_387 17057 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17058 && flag_unsafe_math_optimizations" 17059 "") 17060 17061;; Rounding mode control word calculation could clobber FLAGS_REG. 17062(define_insn_and_split "frndintxf2_floor" 17063 [(set (match_operand:XF 0 "register_operand" "=f") 17064 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17065 UNSPEC_FRNDINT_FLOOR)) 17066 (clobber (reg:CC FLAGS_REG))] 17067 "TARGET_USE_FANCY_MATH_387 17068 && flag_unsafe_math_optimizations 17069 && !(reload_completed || reload_in_progress)" 17070 "#" 17071 "&& 1" 17072 [(const_int 0)] 17073{ 17074 ix86_optimize_mode_switching[I387_FLOOR] = 1; 17075 17076 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17077 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); 17078 17079 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1], 17080 operands[2], operands[3])); 17081 DONE; 17082} 17083 [(set_attr "type" "frndint") 17084 (set_attr "i387_cw" "floor") 17085 (set_attr "mode" "XF")]) 17086 17087(define_insn "frndintxf2_floor_i387" 17088 [(set (match_operand:XF 0 "register_operand" "=f") 17089 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17090 UNSPEC_FRNDINT_FLOOR)) 17091 (use (match_operand:HI 2 "memory_operand" "m")) 17092 (use (match_operand:HI 3 "memory_operand" "m"))] 17093 "TARGET_USE_FANCY_MATH_387 17094 && flag_unsafe_math_optimizations" 17095 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 17096 [(set_attr "type" "frndint") 17097 (set_attr "i387_cw" "floor") 17098 (set_attr "mode" "XF")]) 17099 17100(define_expand "floorxf2" 17101 [(use (match_operand:XF 0 "register_operand" "")) 17102 (use (match_operand:XF 1 "register_operand" ""))] 17103 "TARGET_USE_FANCY_MATH_387 17104 && flag_unsafe_math_optimizations" 17105{ 17106 emit_insn (gen_frndintxf2_floor (operands[0], operands[1])); 17107 DONE; 17108}) 17109 17110(define_expand "floordf2" 17111 [(use (match_operand:DF 0 "register_operand" "")) 17112 (use (match_operand:DF 1 "register_operand" ""))] 17113 "TARGET_USE_FANCY_MATH_387 17114 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17115 && flag_unsafe_math_optimizations" 17116{ 17117 rtx op0 = gen_reg_rtx (XFmode); 17118 rtx op1 = gen_reg_rtx (XFmode); 17119 17120 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17121 emit_insn (gen_frndintxf2_floor (op0, op1)); 17122 17123 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17124 DONE; 17125}) 17126 17127(define_expand "floorsf2" 17128 [(use (match_operand:SF 0 "register_operand" "")) 17129 (use (match_operand:SF 1 "register_operand" ""))] 17130 "TARGET_USE_FANCY_MATH_387 17131 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17132 && flag_unsafe_math_optimizations" 17133{ 17134 rtx op0 = gen_reg_rtx (XFmode); 17135 rtx op1 = gen_reg_rtx (XFmode); 17136 17137 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17138 emit_insn (gen_frndintxf2_floor (op0, op1)); 17139 17140 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17141 DONE; 17142}) 17143 17144(define_insn_and_split "*fist<mode>2_floor_1" 17145 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 17146 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")] 17147 UNSPEC_FIST_FLOOR)) 17148 (clobber (reg:CC FLAGS_REG))] 17149 "TARGET_USE_FANCY_MATH_387 17150 && flag_unsafe_math_optimizations 17151 && !(reload_completed || reload_in_progress)" 17152 "#" 17153 "&& 1" 17154 [(const_int 0)] 17155{ 17156 ix86_optimize_mode_switching[I387_FLOOR] = 1; 17157 17158 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17159 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); 17160 if (memory_operand (operands[0], VOIDmode)) 17161 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1], 17162 operands[2], operands[3])); 17163 else 17164 { 17165 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17166 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1], 17167 operands[2], operands[3], 17168 operands[4])); 17169 } 17170 DONE; 17171} 17172 [(set_attr "type" "fistp") 17173 (set_attr "i387_cw" "floor") 17174 (set_attr "mode" "<MODE>")]) 17175 17176(define_insn "fistdi2_floor" 17177 [(set (match_operand:DI 0 "memory_operand" "=m") 17178 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 17179 UNSPEC_FIST_FLOOR)) 17180 (use (match_operand:HI 2 "memory_operand" "m")) 17181 (use (match_operand:HI 3 "memory_operand" "m")) 17182 (clobber (match_scratch:XF 4 "=&1f"))] 17183 "TARGET_USE_FANCY_MATH_387 17184 && flag_unsafe_math_optimizations" 17185 "* return output_fix_trunc (insn, operands, 0);" 17186 [(set_attr "type" "fistp") 17187 (set_attr "i387_cw" "floor") 17188 (set_attr "mode" "DI")]) 17189 17190(define_insn "fistdi2_floor_with_temp" 17191 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17192 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17193 UNSPEC_FIST_FLOOR)) 17194 (use (match_operand:HI 2 "memory_operand" "m,m")) 17195 (use (match_operand:HI 3 "memory_operand" "m,m")) 17196 (clobber (match_operand:DI 4 "memory_operand" "=m,m")) 17197 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 17198 "TARGET_USE_FANCY_MATH_387 17199 && flag_unsafe_math_optimizations" 17200 "#" 17201 [(set_attr "type" "fistp") 17202 (set_attr "i387_cw" "floor") 17203 (set_attr "mode" "DI")]) 17204 17205(define_split 17206 [(set (match_operand:DI 0 "register_operand" "") 17207 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17208 UNSPEC_FIST_FLOOR)) 17209 (use (match_operand:HI 2 "memory_operand" "")) 17210 (use (match_operand:HI 3 "memory_operand" "")) 17211 (clobber (match_operand:DI 4 "memory_operand" "")) 17212 (clobber (match_scratch 5 ""))] 17213 "reload_completed" 17214 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) 17215 (use (match_dup 2)) 17216 (use (match_dup 3)) 17217 (clobber (match_dup 5))]) 17218 (set (match_dup 0) (match_dup 4))] 17219 "") 17220 17221(define_split 17222 [(set (match_operand:DI 0 "memory_operand" "") 17223 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17224 UNSPEC_FIST_FLOOR)) 17225 (use (match_operand:HI 2 "memory_operand" "")) 17226 (use (match_operand:HI 3 "memory_operand" "")) 17227 (clobber (match_operand:DI 4 "memory_operand" "")) 17228 (clobber (match_scratch 5 ""))] 17229 "reload_completed" 17230 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) 17231 (use (match_dup 2)) 17232 (use (match_dup 3)) 17233 (clobber (match_dup 5))])] 17234 "") 17235 17236(define_insn "fist<mode>2_floor" 17237 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 17238 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17239 UNSPEC_FIST_FLOOR)) 17240 (use (match_operand:HI 2 "memory_operand" "m")) 17241 (use (match_operand:HI 3 "memory_operand" "m"))] 17242 "TARGET_USE_FANCY_MATH_387 17243 && flag_unsafe_math_optimizations" 17244 "* return output_fix_trunc (insn, operands, 0);" 17245 [(set_attr "type" "fistp") 17246 (set_attr "i387_cw" "floor") 17247 (set_attr "mode" "<MODE>")]) 17248 17249(define_insn "fist<mode>2_floor_with_temp" 17250 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") 17251 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")] 17252 UNSPEC_FIST_FLOOR)) 17253 (use (match_operand:HI 2 "memory_operand" "m,m")) 17254 (use (match_operand:HI 3 "memory_operand" "m,m")) 17255 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))] 17256 "TARGET_USE_FANCY_MATH_387 17257 && flag_unsafe_math_optimizations" 17258 "#" 17259 [(set_attr "type" "fistp") 17260 (set_attr "i387_cw" "floor") 17261 (set_attr "mode" "<MODE>")]) 17262 17263(define_split 17264 [(set (match_operand:X87MODEI12 0 "register_operand" "") 17265 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17266 UNSPEC_FIST_FLOOR)) 17267 (use (match_operand:HI 2 "memory_operand" "")) 17268 (use (match_operand:HI 3 "memory_operand" "")) 17269 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 17270 "reload_completed" 17271 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)] 17272 UNSPEC_FIST_FLOOR)) 17273 (use (match_dup 2)) 17274 (use (match_dup 3))]) 17275 (set (match_dup 0) (match_dup 4))] 17276 "") 17277 17278(define_split 17279 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 17280 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17281 UNSPEC_FIST_FLOOR)) 17282 (use (match_operand:HI 2 "memory_operand" "")) 17283 (use (match_operand:HI 3 "memory_operand" "")) 17284 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 17285 "reload_completed" 17286 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] 17287 UNSPEC_FIST_FLOOR)) 17288 (use (match_dup 2)) 17289 (use (match_dup 3))])] 17290 "") 17291 17292(define_expand "lfloor<mode>2" 17293 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") 17294 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] 17295 UNSPEC_FIST_FLOOR)) 17296 (clobber (reg:CC FLAGS_REG))])] 17297 "TARGET_USE_FANCY_MATH_387 17298 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17299 && flag_unsafe_math_optimizations" 17300 "") 17301 17302;; Rounding mode control word calculation could clobber FLAGS_REG. 17303(define_insn_and_split "frndintxf2_ceil" 17304 [(set (match_operand:XF 0 "register_operand" "=f") 17305 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17306 UNSPEC_FRNDINT_CEIL)) 17307 (clobber (reg:CC FLAGS_REG))] 17308 "TARGET_USE_FANCY_MATH_387 17309 && flag_unsafe_math_optimizations 17310 && !(reload_completed || reload_in_progress)" 17311 "#" 17312 "&& 1" 17313 [(const_int 0)] 17314{ 17315 ix86_optimize_mode_switching[I387_CEIL] = 1; 17316 17317 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17318 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); 17319 17320 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1], 17321 operands[2], operands[3])); 17322 DONE; 17323} 17324 [(set_attr "type" "frndint") 17325 (set_attr "i387_cw" "ceil") 17326 (set_attr "mode" "XF")]) 17327 17328(define_insn "frndintxf2_ceil_i387" 17329 [(set (match_operand:XF 0 "register_operand" "=f") 17330 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17331 UNSPEC_FRNDINT_CEIL)) 17332 (use (match_operand:HI 2 "memory_operand" "m")) 17333 (use (match_operand:HI 3 "memory_operand" "m"))] 17334 "TARGET_USE_FANCY_MATH_387 17335 && flag_unsafe_math_optimizations" 17336 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 17337 [(set_attr "type" "frndint") 17338 (set_attr "i387_cw" "ceil") 17339 (set_attr "mode" "XF")]) 17340 17341(define_expand "ceilxf2" 17342 [(use (match_operand:XF 0 "register_operand" "")) 17343 (use (match_operand:XF 1 "register_operand" ""))] 17344 "TARGET_USE_FANCY_MATH_387 17345 && flag_unsafe_math_optimizations" 17346{ 17347 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1])); 17348 DONE; 17349}) 17350 17351(define_expand "ceildf2" 17352 [(use (match_operand:DF 0 "register_operand" "")) 17353 (use (match_operand:DF 1 "register_operand" ""))] 17354 "TARGET_USE_FANCY_MATH_387 17355 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17356 && flag_unsafe_math_optimizations" 17357{ 17358 rtx op0 = gen_reg_rtx (XFmode); 17359 rtx op1 = gen_reg_rtx (XFmode); 17360 17361 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17362 emit_insn (gen_frndintxf2_ceil (op0, op1)); 17363 17364 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17365 DONE; 17366}) 17367 17368(define_expand "ceilsf2" 17369 [(use (match_operand:SF 0 "register_operand" "")) 17370 (use (match_operand:SF 1 "register_operand" ""))] 17371 "TARGET_USE_FANCY_MATH_387 17372 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17373 && flag_unsafe_math_optimizations" 17374{ 17375 rtx op0 = gen_reg_rtx (XFmode); 17376 rtx op1 = gen_reg_rtx (XFmode); 17377 17378 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17379 emit_insn (gen_frndintxf2_ceil (op0, op1)); 17380 17381 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17382 DONE; 17383}) 17384 17385(define_insn_and_split "*fist<mode>2_ceil_1" 17386 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 17387 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")] 17388 UNSPEC_FIST_CEIL)) 17389 (clobber (reg:CC FLAGS_REG))] 17390 "TARGET_USE_FANCY_MATH_387 17391 && flag_unsafe_math_optimizations 17392 && !(reload_completed || reload_in_progress)" 17393 "#" 17394 "&& 1" 17395 [(const_int 0)] 17396{ 17397 ix86_optimize_mode_switching[I387_CEIL] = 1; 17398 17399 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17400 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); 17401 if (memory_operand (operands[0], VOIDmode)) 17402 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1], 17403 operands[2], operands[3])); 17404 else 17405 { 17406 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17407 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1], 17408 operands[2], operands[3], 17409 operands[4])); 17410 } 17411 DONE; 17412} 17413 [(set_attr "type" "fistp") 17414 (set_attr "i387_cw" "ceil") 17415 (set_attr "mode" "<MODE>")]) 17416 17417(define_insn "fistdi2_ceil" 17418 [(set (match_operand:DI 0 "memory_operand" "=m") 17419 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 17420 UNSPEC_FIST_CEIL)) 17421 (use (match_operand:HI 2 "memory_operand" "m")) 17422 (use (match_operand:HI 3 "memory_operand" "m")) 17423 (clobber (match_scratch:XF 4 "=&1f"))] 17424 "TARGET_USE_FANCY_MATH_387 17425 && flag_unsafe_math_optimizations" 17426 "* return output_fix_trunc (insn, operands, 0);" 17427 [(set_attr "type" "fistp") 17428 (set_attr "i387_cw" "ceil") 17429 (set_attr "mode" "DI")]) 17430 17431(define_insn "fistdi2_ceil_with_temp" 17432 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17433 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17434 UNSPEC_FIST_CEIL)) 17435 (use (match_operand:HI 2 "memory_operand" "m,m")) 17436 (use (match_operand:HI 3 "memory_operand" "m,m")) 17437 (clobber (match_operand:DI 4 "memory_operand" "=m,m")) 17438 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 17439 "TARGET_USE_FANCY_MATH_387 17440 && flag_unsafe_math_optimizations" 17441 "#" 17442 [(set_attr "type" "fistp") 17443 (set_attr "i387_cw" "ceil") 17444 (set_attr "mode" "DI")]) 17445 17446(define_split 17447 [(set (match_operand:DI 0 "register_operand" "") 17448 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17449 UNSPEC_FIST_CEIL)) 17450 (use (match_operand:HI 2 "memory_operand" "")) 17451 (use (match_operand:HI 3 "memory_operand" "")) 17452 (clobber (match_operand:DI 4 "memory_operand" "")) 17453 (clobber (match_scratch 5 ""))] 17454 "reload_completed" 17455 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) 17456 (use (match_dup 2)) 17457 (use (match_dup 3)) 17458 (clobber (match_dup 5))]) 17459 (set (match_dup 0) (match_dup 4))] 17460 "") 17461 17462(define_split 17463 [(set (match_operand:DI 0 "memory_operand" "") 17464 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17465 UNSPEC_FIST_CEIL)) 17466 (use (match_operand:HI 2 "memory_operand" "")) 17467 (use (match_operand:HI 3 "memory_operand" "")) 17468 (clobber (match_operand:DI 4 "memory_operand" "")) 17469 (clobber (match_scratch 5 ""))] 17470 "reload_completed" 17471 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) 17472 (use (match_dup 2)) 17473 (use (match_dup 3)) 17474 (clobber (match_dup 5))])] 17475 "") 17476 17477(define_insn "fist<mode>2_ceil" 17478 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 17479 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17480 UNSPEC_FIST_CEIL)) 17481 (use (match_operand:HI 2 "memory_operand" "m")) 17482 (use (match_operand:HI 3 "memory_operand" "m"))] 17483 "TARGET_USE_FANCY_MATH_387 17484 && flag_unsafe_math_optimizations" 17485 "* return output_fix_trunc (insn, operands, 0);" 17486 [(set_attr "type" "fistp") 17487 (set_attr "i387_cw" "ceil") 17488 (set_attr "mode" "<MODE>")]) 17489 17490(define_insn "fist<mode>2_ceil_with_temp" 17491 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") 17492 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")] 17493 UNSPEC_FIST_CEIL)) 17494 (use (match_operand:HI 2 "memory_operand" "m,m")) 17495 (use (match_operand:HI 3 "memory_operand" "m,m")) 17496 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))] 17497 "TARGET_USE_FANCY_MATH_387 17498 && flag_unsafe_math_optimizations" 17499 "#" 17500 [(set_attr "type" "fistp") 17501 (set_attr "i387_cw" "ceil") 17502 (set_attr "mode" "<MODE>")]) 17503 17504(define_split 17505 [(set (match_operand:X87MODEI12 0 "register_operand" "") 17506 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17507 UNSPEC_FIST_CEIL)) 17508 (use (match_operand:HI 2 "memory_operand" "")) 17509 (use (match_operand:HI 3 "memory_operand" "")) 17510 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 17511 "reload_completed" 17512 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)] 17513 UNSPEC_FIST_CEIL)) 17514 (use (match_dup 2)) 17515 (use (match_dup 3))]) 17516 (set (match_dup 0) (match_dup 4))] 17517 "") 17518 17519(define_split 17520 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 17521 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17522 UNSPEC_FIST_CEIL)) 17523 (use (match_operand:HI 2 "memory_operand" "")) 17524 (use (match_operand:HI 3 "memory_operand" "")) 17525 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 17526 "reload_completed" 17527 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] 17528 UNSPEC_FIST_CEIL)) 17529 (use (match_dup 2)) 17530 (use (match_dup 3))])] 17531 "") 17532 17533(define_expand "lceil<mode>2" 17534 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") 17535 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] 17536 UNSPEC_FIST_CEIL)) 17537 (clobber (reg:CC FLAGS_REG))])] 17538 "TARGET_USE_FANCY_MATH_387 17539 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17540 && flag_unsafe_math_optimizations" 17541 "") 17542 17543;; Rounding mode control word calculation could clobber FLAGS_REG. 17544(define_insn_and_split "frndintxf2_trunc" 17545 [(set (match_operand:XF 0 "register_operand" "=f") 17546 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17547 UNSPEC_FRNDINT_TRUNC)) 17548 (clobber (reg:CC FLAGS_REG))] 17549 "TARGET_USE_FANCY_MATH_387 17550 && flag_unsafe_math_optimizations 17551 && !(reload_completed || reload_in_progress)" 17552 "#" 17553 "&& 1" 17554 [(const_int 0)] 17555{ 17556 ix86_optimize_mode_switching[I387_TRUNC] = 1; 17557 17558 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17559 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 17560 17561 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1], 17562 operands[2], operands[3])); 17563 DONE; 17564} 17565 [(set_attr "type" "frndint") 17566 (set_attr "i387_cw" "trunc") 17567 (set_attr "mode" "XF")]) 17568 17569(define_insn "frndintxf2_trunc_i387" 17570 [(set (match_operand:XF 0 "register_operand" "=f") 17571 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17572 UNSPEC_FRNDINT_TRUNC)) 17573 (use (match_operand:HI 2 "memory_operand" "m")) 17574 (use (match_operand:HI 3 "memory_operand" "m"))] 17575 "TARGET_USE_FANCY_MATH_387 17576 && flag_unsafe_math_optimizations" 17577 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 17578 [(set_attr "type" "frndint") 17579 (set_attr "i387_cw" "trunc") 17580 (set_attr "mode" "XF")]) 17581 17582(define_expand "btruncxf2" 17583 [(use (match_operand:XF 0 "register_operand" "")) 17584 (use (match_operand:XF 1 "register_operand" ""))] 17585 "TARGET_USE_FANCY_MATH_387 17586 && flag_unsafe_math_optimizations" 17587{ 17588 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1])); 17589 DONE; 17590}) 17591 17592(define_expand "btruncdf2" 17593 [(use (match_operand:DF 0 "register_operand" "")) 17594 (use (match_operand:DF 1 "register_operand" ""))] 17595 "TARGET_USE_FANCY_MATH_387 17596 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17597 && flag_unsafe_math_optimizations" 17598{ 17599 rtx op0 = gen_reg_rtx (XFmode); 17600 rtx op1 = gen_reg_rtx (XFmode); 17601 17602 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17603 emit_insn (gen_frndintxf2_trunc (op0, op1)); 17604 17605 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17606 DONE; 17607}) 17608 17609(define_expand "btruncsf2" 17610 [(use (match_operand:SF 0 "register_operand" "")) 17611 (use (match_operand:SF 1 "register_operand" ""))] 17612 "TARGET_USE_FANCY_MATH_387 17613 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17614 && flag_unsafe_math_optimizations" 17615{ 17616 rtx op0 = gen_reg_rtx (XFmode); 17617 rtx op1 = gen_reg_rtx (XFmode); 17618 17619 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17620 emit_insn (gen_frndintxf2_trunc (op0, op1)); 17621 17622 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17623 DONE; 17624}) 17625 17626;; Rounding mode control word calculation could clobber FLAGS_REG. 17627(define_insn_and_split "frndintxf2_mask_pm" 17628 [(set (match_operand:XF 0 "register_operand" "=f") 17629 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17630 UNSPEC_FRNDINT_MASK_PM)) 17631 (clobber (reg:CC FLAGS_REG))] 17632 "TARGET_USE_FANCY_MATH_387 17633 && flag_unsafe_math_optimizations 17634 && !(reload_completed || reload_in_progress)" 17635 "#" 17636 "&& 1" 17637 [(const_int 0)] 17638{ 17639 ix86_optimize_mode_switching[I387_MASK_PM] = 1; 17640 17641 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17642 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM); 17643 17644 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1], 17645 operands[2], operands[3])); 17646 DONE; 17647} 17648 [(set_attr "type" "frndint") 17649 (set_attr "i387_cw" "mask_pm") 17650 (set_attr "mode" "XF")]) 17651 17652(define_insn "frndintxf2_mask_pm_i387" 17653 [(set (match_operand:XF 0 "register_operand" "=f") 17654 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17655 UNSPEC_FRNDINT_MASK_PM)) 17656 (use (match_operand:HI 2 "memory_operand" "m")) 17657 (use (match_operand:HI 3 "memory_operand" "m"))] 17658 "TARGET_USE_FANCY_MATH_387 17659 && flag_unsafe_math_optimizations" 17660 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2" 17661 [(set_attr "type" "frndint") 17662 (set_attr "i387_cw" "mask_pm") 17663 (set_attr "mode" "XF")]) 17664 17665(define_expand "nearbyintxf2" 17666 [(use (match_operand:XF 0 "register_operand" "")) 17667 (use (match_operand:XF 1 "register_operand" ""))] 17668 "TARGET_USE_FANCY_MATH_387 17669 && flag_unsafe_math_optimizations" 17670{ 17671 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1])); 17672 17673 DONE; 17674}) 17675 17676(define_expand "nearbyintdf2" 17677 [(use (match_operand:DF 0 "register_operand" "")) 17678 (use (match_operand:DF 1 "register_operand" ""))] 17679 "TARGET_USE_FANCY_MATH_387 17680 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17681 && flag_unsafe_math_optimizations" 17682{ 17683 rtx op0 = gen_reg_rtx (XFmode); 17684 rtx op1 = gen_reg_rtx (XFmode); 17685 17686 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17687 emit_insn (gen_frndintxf2_mask_pm (op0, op1)); 17688 17689 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17690 DONE; 17691}) 17692 17693(define_expand "nearbyintsf2" 17694 [(use (match_operand:SF 0 "register_operand" "")) 17695 (use (match_operand:SF 1 "register_operand" ""))] 17696 "TARGET_USE_FANCY_MATH_387 17697 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17698 && flag_unsafe_math_optimizations" 17699{ 17700 rtx op0 = gen_reg_rtx (XFmode); 17701 rtx op1 = gen_reg_rtx (XFmode); 17702 17703 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17704 emit_insn (gen_frndintxf2_mask_pm (op0, op1)); 17705 17706 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17707 DONE; 17708}) 17709 17710 17711;; Block operation instructions 17712 17713(define_insn "cld" 17714 [(set (reg:SI DIRFLAG_REG) (const_int 0))] 17715 "" 17716 "cld" 17717 [(set_attr "type" "cld")]) 17718 17719(define_expand "movmemsi" 17720 [(use (match_operand:BLK 0 "memory_operand" "")) 17721 (use (match_operand:BLK 1 "memory_operand" "")) 17722 (use (match_operand:SI 2 "nonmemory_operand" "")) 17723 (use (match_operand:SI 3 "const_int_operand" ""))] 17724 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS" 17725{ 17726 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3])) 17727 DONE; 17728 else 17729 FAIL; 17730}) 17731 17732(define_expand "movmemdi" 17733 [(use (match_operand:BLK 0 "memory_operand" "")) 17734 (use (match_operand:BLK 1 "memory_operand" "")) 17735 (use (match_operand:DI 2 "nonmemory_operand" "")) 17736 (use (match_operand:DI 3 "const_int_operand" ""))] 17737 "TARGET_64BIT" 17738{ 17739 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3])) 17740 DONE; 17741 else 17742 FAIL; 17743}) 17744 17745;; Most CPUs don't like single string operations 17746;; Handle this case here to simplify previous expander. 17747 17748(define_expand "strmov" 17749 [(set (match_dup 4) (match_operand 3 "memory_operand" "")) 17750 (set (match_operand 1 "memory_operand" "") (match_dup 4)) 17751 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5)) 17752 (clobber (reg:CC FLAGS_REG))]) 17753 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6)) 17754 (clobber (reg:CC FLAGS_REG))])] 17755 "" 17756{ 17757 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1]))); 17758 17759 /* If .md ever supports :P for Pmode, these can be directly 17760 in the pattern above. */ 17761 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust); 17762 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust); 17763 17764 if (TARGET_SINGLE_STRINGOP || optimize_size) 17765 { 17766 emit_insn (gen_strmov_singleop (operands[0], operands[1], 17767 operands[2], operands[3], 17768 operands[5], operands[6])); 17769 DONE; 17770 } 17771 17772 operands[4] = gen_reg_rtx (GET_MODE (operands[1])); 17773}) 17774 17775(define_expand "strmov_singleop" 17776 [(parallel [(set (match_operand 1 "memory_operand" "") 17777 (match_operand 3 "memory_operand" "")) 17778 (set (match_operand 0 "register_operand" "") 17779 (match_operand 4 "" "")) 17780 (set (match_operand 2 "register_operand" "") 17781 (match_operand 5 "" "")) 17782 (use (reg:SI DIRFLAG_REG))])] 17783 "TARGET_SINGLE_STRINGOP || optimize_size" 17784 "") 17785 17786(define_insn "*strmovdi_rex_1" 17787 [(set (mem:DI (match_operand:DI 2 "register_operand" "0")) 17788 (mem:DI (match_operand:DI 3 "register_operand" "1"))) 17789 (set (match_operand:DI 0 "register_operand" "=D") 17790 (plus:DI (match_dup 2) 17791 (const_int 8))) 17792 (set (match_operand:DI 1 "register_operand" "=S") 17793 (plus:DI (match_dup 3) 17794 (const_int 8))) 17795 (use (reg:SI DIRFLAG_REG))] 17796 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 17797 "movsq" 17798 [(set_attr "type" "str") 17799 (set_attr "mode" "DI") 17800 (set_attr "memory" "both")]) 17801 17802(define_insn "*strmovsi_1" 17803 [(set (mem:SI (match_operand:SI 2 "register_operand" "0")) 17804 (mem:SI (match_operand:SI 3 "register_operand" "1"))) 17805 (set (match_operand:SI 0 "register_operand" "=D") 17806 (plus:SI (match_dup 2) 17807 (const_int 4))) 17808 (set (match_operand:SI 1 "register_operand" "=S") 17809 (plus:SI (match_dup 3) 17810 (const_int 4))) 17811 (use (reg:SI DIRFLAG_REG))] 17812 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 17813 "{movsl|movsd}" 17814 [(set_attr "type" "str") 17815 (set_attr "mode" "SI") 17816 (set_attr "memory" "both")]) 17817 17818(define_insn "*strmovsi_rex_1" 17819 [(set (mem:SI (match_operand:DI 2 "register_operand" "0")) 17820 (mem:SI (match_operand:DI 3 "register_operand" "1"))) 17821 (set (match_operand:DI 0 "register_operand" "=D") 17822 (plus:DI (match_dup 2) 17823 (const_int 4))) 17824 (set (match_operand:DI 1 "register_operand" "=S") 17825 (plus:DI (match_dup 3) 17826 (const_int 4))) 17827 (use (reg:SI DIRFLAG_REG))] 17828 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 17829 "{movsl|movsd}" 17830 [(set_attr "type" "str") 17831 (set_attr "mode" "SI") 17832 (set_attr "memory" "both")]) 17833 17834(define_insn "*strmovhi_1" 17835 [(set (mem:HI (match_operand:SI 2 "register_operand" "0")) 17836 (mem:HI (match_operand:SI 3 "register_operand" "1"))) 17837 (set (match_operand:SI 0 "register_operand" "=D") 17838 (plus:SI (match_dup 2) 17839 (const_int 2))) 17840 (set (match_operand:SI 1 "register_operand" "=S") 17841 (plus:SI (match_dup 3) 17842 (const_int 2))) 17843 (use (reg:SI DIRFLAG_REG))] 17844 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 17845 "movsw" 17846 [(set_attr "type" "str") 17847 (set_attr "memory" "both") 17848 (set_attr "mode" "HI")]) 17849 17850(define_insn "*strmovhi_rex_1" 17851 [(set (mem:HI (match_operand:DI 2 "register_operand" "0")) 17852 (mem:HI (match_operand:DI 3 "register_operand" "1"))) 17853 (set (match_operand:DI 0 "register_operand" "=D") 17854 (plus:DI (match_dup 2) 17855 (const_int 2))) 17856 (set (match_operand:DI 1 "register_operand" "=S") 17857 (plus:DI (match_dup 3) 17858 (const_int 2))) 17859 (use (reg:SI DIRFLAG_REG))] 17860 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 17861 "movsw" 17862 [(set_attr "type" "str") 17863 (set_attr "memory" "both") 17864 (set_attr "mode" "HI")]) 17865 17866(define_insn "*strmovqi_1" 17867 [(set (mem:QI (match_operand:SI 2 "register_operand" "0")) 17868 (mem:QI (match_operand:SI 3 "register_operand" "1"))) 17869 (set (match_operand:SI 0 "register_operand" "=D") 17870 (plus:SI (match_dup 2) 17871 (const_int 1))) 17872 (set (match_operand:SI 1 "register_operand" "=S") 17873 (plus:SI (match_dup 3) 17874 (const_int 1))) 17875 (use (reg:SI DIRFLAG_REG))] 17876 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 17877 "movsb" 17878 [(set_attr "type" "str") 17879 (set_attr "memory" "both") 17880 (set_attr "mode" "QI")]) 17881 17882(define_insn "*strmovqi_rex_1" 17883 [(set (mem:QI (match_operand:DI 2 "register_operand" "0")) 17884 (mem:QI (match_operand:DI 3 "register_operand" "1"))) 17885 (set (match_operand:DI 0 "register_operand" "=D") 17886 (plus:DI (match_dup 2) 17887 (const_int 1))) 17888 (set (match_operand:DI 1 "register_operand" "=S") 17889 (plus:DI (match_dup 3) 17890 (const_int 1))) 17891 (use (reg:SI DIRFLAG_REG))] 17892 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 17893 "movsb" 17894 [(set_attr "type" "str") 17895 (set_attr "memory" "both") 17896 (set_attr "mode" "QI")]) 17897 17898(define_expand "rep_mov" 17899 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0)) 17900 (set (match_operand 0 "register_operand" "") 17901 (match_operand 5 "" "")) 17902 (set (match_operand 2 "register_operand" "") 17903 (match_operand 6 "" "")) 17904 (set (match_operand 1 "memory_operand" "") 17905 (match_operand 3 "memory_operand" "")) 17906 (use (match_dup 4)) 17907 (use (reg:SI DIRFLAG_REG))])] 17908 "" 17909 "") 17910 17911(define_insn "*rep_movdi_rex64" 17912 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) 17913 (set (match_operand:DI 0 "register_operand" "=D") 17914 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2") 17915 (const_int 3)) 17916 (match_operand:DI 3 "register_operand" "0"))) 17917 (set (match_operand:DI 1 "register_operand" "=S") 17918 (plus:DI (ashift:DI (match_dup 5) (const_int 3)) 17919 (match_operand:DI 4 "register_operand" "1"))) 17920 (set (mem:BLK (match_dup 3)) 17921 (mem:BLK (match_dup 4))) 17922 (use (match_dup 5)) 17923 (use (reg:SI DIRFLAG_REG))] 17924 "TARGET_64BIT" 17925 "{rep\;movsq|rep movsq}" 17926 [(set_attr "type" "str") 17927 (set_attr "prefix_rep" "1") 17928 (set_attr "memory" "both") 17929 (set_attr "mode" "DI")]) 17930 17931(define_insn "*rep_movsi" 17932 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0)) 17933 (set (match_operand:SI 0 "register_operand" "=D") 17934 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2") 17935 (const_int 2)) 17936 (match_operand:SI 3 "register_operand" "0"))) 17937 (set (match_operand:SI 1 "register_operand" "=S") 17938 (plus:SI (ashift:SI (match_dup 5) (const_int 2)) 17939 (match_operand:SI 4 "register_operand" "1"))) 17940 (set (mem:BLK (match_dup 3)) 17941 (mem:BLK (match_dup 4))) 17942 (use (match_dup 5)) 17943 (use (reg:SI DIRFLAG_REG))] 17944 "!TARGET_64BIT" 17945 "{rep\;movsl|rep movsd}" 17946 [(set_attr "type" "str") 17947 (set_attr "prefix_rep" "1") 17948 (set_attr "memory" "both") 17949 (set_attr "mode" "SI")]) 17950 17951(define_insn "*rep_movsi_rex64" 17952 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) 17953 (set (match_operand:DI 0 "register_operand" "=D") 17954 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2") 17955 (const_int 2)) 17956 (match_operand:DI 3 "register_operand" "0"))) 17957 (set (match_operand:DI 1 "register_operand" "=S") 17958 (plus:DI (ashift:DI (match_dup 5) (const_int 2)) 17959 (match_operand:DI 4 "register_operand" "1"))) 17960 (set (mem:BLK (match_dup 3)) 17961 (mem:BLK (match_dup 4))) 17962 (use (match_dup 5)) 17963 (use (reg:SI DIRFLAG_REG))] 17964 "TARGET_64BIT" 17965 "{rep\;movsl|rep movsd}" 17966 [(set_attr "type" "str") 17967 (set_attr "prefix_rep" "1") 17968 (set_attr "memory" "both") 17969 (set_attr "mode" "SI")]) 17970 17971(define_insn "*rep_movqi" 17972 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0)) 17973 (set (match_operand:SI 0 "register_operand" "=D") 17974 (plus:SI (match_operand:SI 3 "register_operand" "0") 17975 (match_operand:SI 5 "register_operand" "2"))) 17976 (set (match_operand:SI 1 "register_operand" "=S") 17977 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5))) 17978 (set (mem:BLK (match_dup 3)) 17979 (mem:BLK (match_dup 4))) 17980 (use (match_dup 5)) 17981 (use (reg:SI DIRFLAG_REG))] 17982 "!TARGET_64BIT" 17983 "{rep\;movsb|rep movsb}" 17984 [(set_attr "type" "str") 17985 (set_attr "prefix_rep" "1") 17986 (set_attr "memory" "both") 17987 (set_attr "mode" "SI")]) 17988 17989(define_insn "*rep_movqi_rex64" 17990 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) 17991 (set (match_operand:DI 0 "register_operand" "=D") 17992 (plus:DI (match_operand:DI 3 "register_operand" "0") 17993 (match_operand:DI 5 "register_operand" "2"))) 17994 (set (match_operand:DI 1 "register_operand" "=S") 17995 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5))) 17996 (set (mem:BLK (match_dup 3)) 17997 (mem:BLK (match_dup 4))) 17998 (use (match_dup 5)) 17999 (use (reg:SI DIRFLAG_REG))] 18000 "TARGET_64BIT" 18001 "{rep\;movsb|rep movsb}" 18002 [(set_attr "type" "str") 18003 (set_attr "prefix_rep" "1") 18004 (set_attr "memory" "both") 18005 (set_attr "mode" "SI")]) 18006 18007(define_expand "setmemsi" 18008 [(use (match_operand:BLK 0 "memory_operand" "")) 18009 (use (match_operand:SI 1 "nonmemory_operand" "")) 18010 (use (match_operand 2 "const_int_operand" "")) 18011 (use (match_operand 3 "const_int_operand" ""))] 18012 "" 18013{ 18014 /* If value to set is not zero, use the library routine. */ 18015 if (operands[2] != const0_rtx) 18016 FAIL; 18017 18018 if (ix86_expand_clrmem (operands[0], operands[1], operands[3])) 18019 DONE; 18020 else 18021 FAIL; 18022}) 18023 18024(define_expand "setmemdi" 18025 [(use (match_operand:BLK 0 "memory_operand" "")) 18026 (use (match_operand:DI 1 "nonmemory_operand" "")) 18027 (use (match_operand 2 "const_int_operand" "")) 18028 (use (match_operand 3 "const_int_operand" ""))] 18029 "TARGET_64BIT" 18030{ 18031 /* If value to set is not zero, use the library routine. */ 18032 if (operands[2] != const0_rtx) 18033 FAIL; 18034 18035 if (ix86_expand_clrmem (operands[0], operands[1], operands[3])) 18036 DONE; 18037 else 18038 FAIL; 18039}) 18040 18041;; Most CPUs don't like single string operations 18042;; Handle this case here to simplify previous expander. 18043 18044(define_expand "strset" 18045 [(set (match_operand 1 "memory_operand" "") 18046 (match_operand 2 "register_operand" "")) 18047 (parallel [(set (match_operand 0 "register_operand" "") 18048 (match_dup 3)) 18049 (clobber (reg:CC FLAGS_REG))])] 18050 "" 18051{ 18052 if (GET_MODE (operands[1]) != GET_MODE (operands[2])) 18053 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0); 18054 18055 /* If .md ever supports :P for Pmode, this can be directly 18056 in the pattern above. */ 18057 operands[3] = gen_rtx_PLUS (Pmode, operands[0], 18058 GEN_INT (GET_MODE_SIZE (GET_MODE 18059 (operands[2])))); 18060 if (TARGET_SINGLE_STRINGOP || optimize_size) 18061 { 18062 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2], 18063 operands[3])); 18064 DONE; 18065 } 18066}) 18067 18068(define_expand "strset_singleop" 18069 [(parallel [(set (match_operand 1 "memory_operand" "") 18070 (match_operand 2 "register_operand" "")) 18071 (set (match_operand 0 "register_operand" "") 18072 (match_operand 3 "" "")) 18073 (use (reg:SI DIRFLAG_REG))])] 18074 "TARGET_SINGLE_STRINGOP || optimize_size" 18075 "") 18076 18077(define_insn "*strsetdi_rex_1" 18078 [(set (mem:DI (match_operand:DI 1 "register_operand" "0")) 18079 (match_operand:DI 2 "register_operand" "a")) 18080 (set (match_operand:DI 0 "register_operand" "=D") 18081 (plus:DI (match_dup 1) 18082 (const_int 8))) 18083 (use (reg:SI DIRFLAG_REG))] 18084 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18085 "stosq" 18086 [(set_attr "type" "str") 18087 (set_attr "memory" "store") 18088 (set_attr "mode" "DI")]) 18089 18090(define_insn "*strsetsi_1" 18091 [(set (mem:SI (match_operand:SI 1 "register_operand" "0")) 18092 (match_operand:SI 2 "register_operand" "a")) 18093 (set (match_operand:SI 0 "register_operand" "=D") 18094 (plus:SI (match_dup 1) 18095 (const_int 4))) 18096 (use (reg:SI DIRFLAG_REG))] 18097 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18098 "{stosl|stosd}" 18099 [(set_attr "type" "str") 18100 (set_attr "memory" "store") 18101 (set_attr "mode" "SI")]) 18102 18103(define_insn "*strsetsi_rex_1" 18104 [(set (mem:SI (match_operand:DI 1 "register_operand" "0")) 18105 (match_operand:SI 2 "register_operand" "a")) 18106 (set (match_operand:DI 0 "register_operand" "=D") 18107 (plus:DI (match_dup 1) 18108 (const_int 4))) 18109 (use (reg:SI DIRFLAG_REG))] 18110 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18111 "{stosl|stosd}" 18112 [(set_attr "type" "str") 18113 (set_attr "memory" "store") 18114 (set_attr "mode" "SI")]) 18115 18116(define_insn "*strsethi_1" 18117 [(set (mem:HI (match_operand:SI 1 "register_operand" "0")) 18118 (match_operand:HI 2 "register_operand" "a")) 18119 (set (match_operand:SI 0 "register_operand" "=D") 18120 (plus:SI (match_dup 1) 18121 (const_int 2))) 18122 (use (reg:SI DIRFLAG_REG))] 18123 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18124 "stosw" 18125 [(set_attr "type" "str") 18126 (set_attr "memory" "store") 18127 (set_attr "mode" "HI")]) 18128 18129(define_insn "*strsethi_rex_1" 18130 [(set (mem:HI (match_operand:DI 1 "register_operand" "0")) 18131 (match_operand:HI 2 "register_operand" "a")) 18132 (set (match_operand:DI 0 "register_operand" "=D") 18133 (plus:DI (match_dup 1) 18134 (const_int 2))) 18135 (use (reg:SI DIRFLAG_REG))] 18136 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18137 "stosw" 18138 [(set_attr "type" "str") 18139 (set_attr "memory" "store") 18140 (set_attr "mode" "HI")]) 18141 18142(define_insn "*strsetqi_1" 18143 [(set (mem:QI (match_operand:SI 1 "register_operand" "0")) 18144 (match_operand:QI 2 "register_operand" "a")) 18145 (set (match_operand:SI 0 "register_operand" "=D") 18146 (plus:SI (match_dup 1) 18147 (const_int 1))) 18148 (use (reg:SI DIRFLAG_REG))] 18149 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18150 "stosb" 18151 [(set_attr "type" "str") 18152 (set_attr "memory" "store") 18153 (set_attr "mode" "QI")]) 18154 18155(define_insn "*strsetqi_rex_1" 18156 [(set (mem:QI (match_operand:DI 1 "register_operand" "0")) 18157 (match_operand:QI 2 "register_operand" "a")) 18158 (set (match_operand:DI 0 "register_operand" "=D") 18159 (plus:DI (match_dup 1) 18160 (const_int 1))) 18161 (use (reg:SI DIRFLAG_REG))] 18162 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18163 "stosb" 18164 [(set_attr "type" "str") 18165 (set_attr "memory" "store") 18166 (set_attr "mode" "QI")]) 18167 18168(define_expand "rep_stos" 18169 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0)) 18170 (set (match_operand 0 "register_operand" "") 18171 (match_operand 4 "" "")) 18172 (set (match_operand 2 "memory_operand" "") (const_int 0)) 18173 (use (match_operand 3 "register_operand" "")) 18174 (use (match_dup 1)) 18175 (use (reg:SI DIRFLAG_REG))])] 18176 "" 18177 "") 18178 18179(define_insn "*rep_stosdi_rex64" 18180 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) 18181 (set (match_operand:DI 0 "register_operand" "=D") 18182 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1") 18183 (const_int 3)) 18184 (match_operand:DI 3 "register_operand" "0"))) 18185 (set (mem:BLK (match_dup 3)) 18186 (const_int 0)) 18187 (use (match_operand:DI 2 "register_operand" "a")) 18188 (use (match_dup 4)) 18189 (use (reg:SI DIRFLAG_REG))] 18190 "TARGET_64BIT" 18191 "{rep\;stosq|rep stosq}" 18192 [(set_attr "type" "str") 18193 (set_attr "prefix_rep" "1") 18194 (set_attr "memory" "store") 18195 (set_attr "mode" "DI")]) 18196 18197(define_insn "*rep_stossi" 18198 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0)) 18199 (set (match_operand:SI 0 "register_operand" "=D") 18200 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1") 18201 (const_int 2)) 18202 (match_operand:SI 3 "register_operand" "0"))) 18203 (set (mem:BLK (match_dup 3)) 18204 (const_int 0)) 18205 (use (match_operand:SI 2 "register_operand" "a")) 18206 (use (match_dup 4)) 18207 (use (reg:SI DIRFLAG_REG))] 18208 "!TARGET_64BIT" 18209 "{rep\;stosl|rep stosd}" 18210 [(set_attr "type" "str") 18211 (set_attr "prefix_rep" "1") 18212 (set_attr "memory" "store") 18213 (set_attr "mode" "SI")]) 18214 18215(define_insn "*rep_stossi_rex64" 18216 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) 18217 (set (match_operand:DI 0 "register_operand" "=D") 18218 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1") 18219 (const_int 2)) 18220 (match_operand:DI 3 "register_operand" "0"))) 18221 (set (mem:BLK (match_dup 3)) 18222 (const_int 0)) 18223 (use (match_operand:SI 2 "register_operand" "a")) 18224 (use (match_dup 4)) 18225 (use (reg:SI DIRFLAG_REG))] 18226 "TARGET_64BIT" 18227 "{rep\;stosl|rep stosd}" 18228 [(set_attr "type" "str") 18229 (set_attr "prefix_rep" "1") 18230 (set_attr "memory" "store") 18231 (set_attr "mode" "SI")]) 18232 18233(define_insn "*rep_stosqi" 18234 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0)) 18235 (set (match_operand:SI 0 "register_operand" "=D") 18236 (plus:SI (match_operand:SI 3 "register_operand" "0") 18237 (match_operand:SI 4 "register_operand" "1"))) 18238 (set (mem:BLK (match_dup 3)) 18239 (const_int 0)) 18240 (use (match_operand:QI 2 "register_operand" "a")) 18241 (use (match_dup 4)) 18242 (use (reg:SI DIRFLAG_REG))] 18243 "!TARGET_64BIT" 18244 "{rep\;stosb|rep stosb}" 18245 [(set_attr "type" "str") 18246 (set_attr "prefix_rep" "1") 18247 (set_attr "memory" "store") 18248 (set_attr "mode" "QI")]) 18249 18250(define_insn "*rep_stosqi_rex64" 18251 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) 18252 (set (match_operand:DI 0 "register_operand" "=D") 18253 (plus:DI (match_operand:DI 3 "register_operand" "0") 18254 (match_operand:DI 4 "register_operand" "1"))) 18255 (set (mem:BLK (match_dup 3)) 18256 (const_int 0)) 18257 (use (match_operand:QI 2 "register_operand" "a")) 18258 (use (match_dup 4)) 18259 (use (reg:SI DIRFLAG_REG))] 18260 "TARGET_64BIT" 18261 "{rep\;stosb|rep stosb}" 18262 [(set_attr "type" "str") 18263 (set_attr "prefix_rep" "1") 18264 (set_attr "memory" "store") 18265 (set_attr "mode" "QI")]) 18266 18267(define_expand "cmpstrnsi" 18268 [(set (match_operand:SI 0 "register_operand" "") 18269 (compare:SI (match_operand:BLK 1 "general_operand" "") 18270 (match_operand:BLK 2 "general_operand" ""))) 18271 (use (match_operand 3 "general_operand" "")) 18272 (use (match_operand 4 "immediate_operand" ""))] 18273 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS" 18274{ 18275 rtx addr1, addr2, out, outlow, count, countreg, align; 18276 18277 /* Can't use this if the user has appropriated esi or edi. */ 18278 if (global_regs[4] || global_regs[5]) 18279 FAIL; 18280 18281 out = operands[0]; 18282 if (GET_CODE (out) != REG) 18283 out = gen_reg_rtx (SImode); 18284 18285 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); 18286 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0)); 18287 if (addr1 != XEXP (operands[1], 0)) 18288 operands[1] = replace_equiv_address_nv (operands[1], addr1); 18289 if (addr2 != XEXP (operands[2], 0)) 18290 operands[2] = replace_equiv_address_nv (operands[2], addr2); 18291 18292 count = operands[3]; 18293 countreg = ix86_zero_extend_to_Pmode (count); 18294 18295 /* %%% Iff we are testing strict equality, we can use known alignment 18296 to good advantage. This may be possible with combine, particularly 18297 once cc0 is dead. */ 18298 align = operands[4]; 18299 18300 emit_insn (gen_cld ()); 18301 if (GET_CODE (count) == CONST_INT) 18302 { 18303 if (INTVAL (count) == 0) 18304 { 18305 emit_move_insn (operands[0], const0_rtx); 18306 DONE; 18307 } 18308 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align, 18309 operands[1], operands[2])); 18310 } 18311 else 18312 { 18313 if (TARGET_64BIT) 18314 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg)); 18315 else 18316 emit_insn (gen_cmpsi_1 (countreg, countreg)); 18317 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align, 18318 operands[1], operands[2])); 18319 } 18320 18321 outlow = gen_lowpart (QImode, out); 18322 emit_insn (gen_cmpintqi (outlow)); 18323 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow)); 18324 18325 if (operands[0] != out) 18326 emit_move_insn (operands[0], out); 18327 18328 DONE; 18329}) 18330 18331;; Produce a tri-state integer (-1, 0, 1) from condition codes. 18332 18333(define_expand "cmpintqi" 18334 [(set (match_dup 1) 18335 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 18336 (set (match_dup 2) 18337 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 18338 (parallel [(set (match_operand:QI 0 "register_operand" "") 18339 (minus:QI (match_dup 1) 18340 (match_dup 2))) 18341 (clobber (reg:CC FLAGS_REG))])] 18342 "" 18343 "operands[1] = gen_reg_rtx (QImode); 18344 operands[2] = gen_reg_rtx (QImode);") 18345 18346;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is 18347;; zero. Emit extra code to make sure that a zero-length compare is EQ. 18348 18349(define_expand "cmpstrnqi_nz_1" 18350 [(parallel [(set (reg:CC FLAGS_REG) 18351 (compare:CC (match_operand 4 "memory_operand" "") 18352 (match_operand 5 "memory_operand" ""))) 18353 (use (match_operand 2 "register_operand" "")) 18354 (use (match_operand:SI 3 "immediate_operand" "")) 18355 (use (reg:SI DIRFLAG_REG)) 18356 (clobber (match_operand 0 "register_operand" "")) 18357 (clobber (match_operand 1 "register_operand" "")) 18358 (clobber (match_dup 2))])] 18359 "" 18360 "") 18361 18362(define_insn "*cmpstrnqi_nz_1" 18363 [(set (reg:CC FLAGS_REG) 18364 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0")) 18365 (mem:BLK (match_operand:SI 5 "register_operand" "1")))) 18366 (use (match_operand:SI 6 "register_operand" "2")) 18367 (use (match_operand:SI 3 "immediate_operand" "i")) 18368 (use (reg:SI DIRFLAG_REG)) 18369 (clobber (match_operand:SI 0 "register_operand" "=S")) 18370 (clobber (match_operand:SI 1 "register_operand" "=D")) 18371 (clobber (match_operand:SI 2 "register_operand" "=c"))] 18372 "!TARGET_64BIT" 18373 "repz{\;| }cmpsb" 18374 [(set_attr "type" "str") 18375 (set_attr "mode" "QI") 18376 (set_attr "prefix_rep" "1")]) 18377 18378(define_insn "*cmpstrnqi_nz_rex_1" 18379 [(set (reg:CC FLAGS_REG) 18380 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0")) 18381 (mem:BLK (match_operand:DI 5 "register_operand" "1")))) 18382 (use (match_operand:DI 6 "register_operand" "2")) 18383 (use (match_operand:SI 3 "immediate_operand" "i")) 18384 (use (reg:SI DIRFLAG_REG)) 18385 (clobber (match_operand:DI 0 "register_operand" "=S")) 18386 (clobber (match_operand:DI 1 "register_operand" "=D")) 18387 (clobber (match_operand:DI 2 "register_operand" "=c"))] 18388 "TARGET_64BIT" 18389 "repz{\;| }cmpsb" 18390 [(set_attr "type" "str") 18391 (set_attr "mode" "QI") 18392 (set_attr "prefix_rep" "1")]) 18393 18394;; The same, but the count is not known to not be zero. 18395 18396(define_expand "cmpstrnqi_1" 18397 [(parallel [(set (reg:CC FLAGS_REG) 18398 (if_then_else:CC (ne (match_operand 2 "register_operand" "") 18399 (const_int 0)) 18400 (compare:CC (match_operand 4 "memory_operand" "") 18401 (match_operand 5 "memory_operand" "")) 18402 (const_int 0))) 18403 (use (match_operand:SI 3 "immediate_operand" "")) 18404 (use (reg:CC FLAGS_REG)) 18405 (use (reg:SI DIRFLAG_REG)) 18406 (clobber (match_operand 0 "register_operand" "")) 18407 (clobber (match_operand 1 "register_operand" "")) 18408 (clobber (match_dup 2))])] 18409 "" 18410 "") 18411 18412(define_insn "*cmpstrnqi_1" 18413 [(set (reg:CC FLAGS_REG) 18414 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2") 18415 (const_int 0)) 18416 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0")) 18417 (mem:BLK (match_operand:SI 5 "register_operand" "1"))) 18418 (const_int 0))) 18419 (use (match_operand:SI 3 "immediate_operand" "i")) 18420 (use (reg:CC FLAGS_REG)) 18421 (use (reg:SI DIRFLAG_REG)) 18422 (clobber (match_operand:SI 0 "register_operand" "=S")) 18423 (clobber (match_operand:SI 1 "register_operand" "=D")) 18424 (clobber (match_operand:SI 2 "register_operand" "=c"))] 18425 "!TARGET_64BIT" 18426 "repz{\;| }cmpsb" 18427 [(set_attr "type" "str") 18428 (set_attr "mode" "QI") 18429 (set_attr "prefix_rep" "1")]) 18430 18431(define_insn "*cmpstrnqi_rex_1" 18432 [(set (reg:CC FLAGS_REG) 18433 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2") 18434 (const_int 0)) 18435 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0")) 18436 (mem:BLK (match_operand:DI 5 "register_operand" "1"))) 18437 (const_int 0))) 18438 (use (match_operand:SI 3 "immediate_operand" "i")) 18439 (use (reg:CC FLAGS_REG)) 18440 (use (reg:SI DIRFLAG_REG)) 18441 (clobber (match_operand:DI 0 "register_operand" "=S")) 18442 (clobber (match_operand:DI 1 "register_operand" "=D")) 18443 (clobber (match_operand:DI 2 "register_operand" "=c"))] 18444 "TARGET_64BIT" 18445 "repz{\;| }cmpsb" 18446 [(set_attr "type" "str") 18447 (set_attr "mode" "QI") 18448 (set_attr "prefix_rep" "1")]) 18449 18450(define_expand "strlensi" 18451 [(set (match_operand:SI 0 "register_operand" "") 18452 (unspec:SI [(match_operand:BLK 1 "general_operand" "") 18453 (match_operand:QI 2 "immediate_operand" "") 18454 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))] 18455 "" 18456{ 18457 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) 18458 DONE; 18459 else 18460 FAIL; 18461}) 18462 18463(define_expand "strlendi" 18464 [(set (match_operand:DI 0 "register_operand" "") 18465 (unspec:DI [(match_operand:BLK 1 "general_operand" "") 18466 (match_operand:QI 2 "immediate_operand" "") 18467 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))] 18468 "" 18469{ 18470 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) 18471 DONE; 18472 else 18473 FAIL; 18474}) 18475 18476(define_expand "strlenqi_1" 18477 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" "")) 18478 (use (reg:SI DIRFLAG_REG)) 18479 (clobber (match_operand 1 "register_operand" "")) 18480 (clobber (reg:CC FLAGS_REG))])] 18481 "" 18482 "") 18483 18484(define_insn "*strlenqi_1" 18485 [(set (match_operand:SI 0 "register_operand" "=&c") 18486 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1")) 18487 (match_operand:QI 2 "register_operand" "a") 18488 (match_operand:SI 3 "immediate_operand" "i") 18489 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS)) 18490 (use (reg:SI DIRFLAG_REG)) 18491 (clobber (match_operand:SI 1 "register_operand" "=D")) 18492 (clobber (reg:CC FLAGS_REG))] 18493 "!TARGET_64BIT" 18494 "repnz{\;| }scasb" 18495 [(set_attr "type" "str") 18496 (set_attr "mode" "QI") 18497 (set_attr "prefix_rep" "1")]) 18498 18499(define_insn "*strlenqi_rex_1" 18500 [(set (match_operand:DI 0 "register_operand" "=&c") 18501 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1")) 18502 (match_operand:QI 2 "register_operand" "a") 18503 (match_operand:DI 3 "immediate_operand" "i") 18504 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS)) 18505 (use (reg:SI DIRFLAG_REG)) 18506 (clobber (match_operand:DI 1 "register_operand" "=D")) 18507 (clobber (reg:CC FLAGS_REG))] 18508 "TARGET_64BIT" 18509 "repnz{\;| }scasb" 18510 [(set_attr "type" "str") 18511 (set_attr "mode" "QI") 18512 (set_attr "prefix_rep" "1")]) 18513 18514;; Peephole optimizations to clean up after cmpstrn*. This should be 18515;; handled in combine, but it is not currently up to the task. 18516;; When used for their truth value, the cmpstrn* expanders generate 18517;; code like this: 18518;; 18519;; repz cmpsb 18520;; seta %al 18521;; setb %dl 18522;; cmpb %al, %dl 18523;; jcc label 18524;; 18525;; The intermediate three instructions are unnecessary. 18526 18527;; This one handles cmpstrn*_nz_1... 18528(define_peephole2 18529 [(parallel[ 18530 (set (reg:CC FLAGS_REG) 18531 (compare:CC (mem:BLK (match_operand 4 "register_operand" "")) 18532 (mem:BLK (match_operand 5 "register_operand" "")))) 18533 (use (match_operand 6 "register_operand" "")) 18534 (use (match_operand:SI 3 "immediate_operand" "")) 18535 (use (reg:SI DIRFLAG_REG)) 18536 (clobber (match_operand 0 "register_operand" "")) 18537 (clobber (match_operand 1 "register_operand" "")) 18538 (clobber (match_operand 2 "register_operand" ""))]) 18539 (set (match_operand:QI 7 "register_operand" "") 18540 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 18541 (set (match_operand:QI 8 "register_operand" "") 18542 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 18543 (set (reg FLAGS_REG) 18544 (compare (match_dup 7) (match_dup 8))) 18545 ] 18546 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 18547 [(parallel[ 18548 (set (reg:CC FLAGS_REG) 18549 (compare:CC (mem:BLK (match_dup 4)) 18550 (mem:BLK (match_dup 5)))) 18551 (use (match_dup 6)) 18552 (use (match_dup 3)) 18553 (use (reg:SI DIRFLAG_REG)) 18554 (clobber (match_dup 0)) 18555 (clobber (match_dup 1)) 18556 (clobber (match_dup 2))])] 18557 "") 18558 18559;; ...and this one handles cmpstrn*_1. 18560(define_peephole2 18561 [(parallel[ 18562 (set (reg:CC FLAGS_REG) 18563 (if_then_else:CC (ne (match_operand 6 "register_operand" "") 18564 (const_int 0)) 18565 (compare:CC (mem:BLK (match_operand 4 "register_operand" "")) 18566 (mem:BLK (match_operand 5 "register_operand" ""))) 18567 (const_int 0))) 18568 (use (match_operand:SI 3 "immediate_operand" "")) 18569 (use (reg:CC FLAGS_REG)) 18570 (use (reg:SI DIRFLAG_REG)) 18571 (clobber (match_operand 0 "register_operand" "")) 18572 (clobber (match_operand 1 "register_operand" "")) 18573 (clobber (match_operand 2 "register_operand" ""))]) 18574 (set (match_operand:QI 7 "register_operand" "") 18575 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 18576 (set (match_operand:QI 8 "register_operand" "") 18577 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 18578 (set (reg FLAGS_REG) 18579 (compare (match_dup 7) (match_dup 8))) 18580 ] 18581 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 18582 [(parallel[ 18583 (set (reg:CC FLAGS_REG) 18584 (if_then_else:CC (ne (match_dup 6) 18585 (const_int 0)) 18586 (compare:CC (mem:BLK (match_dup 4)) 18587 (mem:BLK (match_dup 5))) 18588 (const_int 0))) 18589 (use (match_dup 3)) 18590 (use (reg:CC FLAGS_REG)) 18591 (use (reg:SI DIRFLAG_REG)) 18592 (clobber (match_dup 0)) 18593 (clobber (match_dup 1)) 18594 (clobber (match_dup 2))])] 18595 "") 18596 18597 18598 18599;; Conditional move instructions. 18600 18601(define_expand "movdicc" 18602 [(set (match_operand:DI 0 "register_operand" "") 18603 (if_then_else:DI (match_operand 1 "comparison_operator" "") 18604 (match_operand:DI 2 "general_operand" "") 18605 (match_operand:DI 3 "general_operand" "")))] 18606 "TARGET_64BIT" 18607 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 18608 18609(define_insn "x86_movdicc_0_m1_rex64" 18610 [(set (match_operand:DI 0 "register_operand" "=r") 18611 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "") 18612 (const_int -1) 18613 (const_int 0))) 18614 (clobber (reg:CC FLAGS_REG))] 18615 "TARGET_64BIT" 18616 "sbb{q}\t%0, %0" 18617 ; Since we don't have the proper number of operands for an alu insn, 18618 ; fill in all the blanks. 18619 [(set_attr "type" "alu") 18620 (set_attr "pent_pair" "pu") 18621 (set_attr "memory" "none") 18622 (set_attr "imm_disp" "false") 18623 (set_attr "mode" "DI") 18624 (set_attr "length_immediate" "0")]) 18625 18626(define_insn "*movdicc_c_rex64" 18627 [(set (match_operand:DI 0 "register_operand" "=r,r") 18628 (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 18629 [(reg FLAGS_REG) (const_int 0)]) 18630 (match_operand:DI 2 "nonimmediate_operand" "rm,0") 18631 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))] 18632 "TARGET_64BIT && TARGET_CMOVE 18633 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 18634 "@ 18635 cmov%O2%C1\t{%2, %0|%0, %2} 18636 cmov%O2%c1\t{%3, %0|%0, %3}" 18637 [(set_attr "type" "icmov") 18638 (set_attr "mode" "DI")]) 18639 18640(define_expand "movsicc" 18641 [(set (match_operand:SI 0 "register_operand" "") 18642 (if_then_else:SI (match_operand 1 "comparison_operator" "") 18643 (match_operand:SI 2 "general_operand" "") 18644 (match_operand:SI 3 "general_operand" "")))] 18645 "" 18646 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 18647 18648;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing 18649;; the register first winds up with `sbbl $0,reg', which is also weird. 18650;; So just document what we're doing explicitly. 18651 18652(define_insn "x86_movsicc_0_m1" 18653 [(set (match_operand:SI 0 "register_operand" "=r") 18654 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "") 18655 (const_int -1) 18656 (const_int 0))) 18657 (clobber (reg:CC FLAGS_REG))] 18658 "" 18659 "sbb{l}\t%0, %0" 18660 ; Since we don't have the proper number of operands for an alu insn, 18661 ; fill in all the blanks. 18662 [(set_attr "type" "alu") 18663 (set_attr "pent_pair" "pu") 18664 (set_attr "memory" "none") 18665 (set_attr "imm_disp" "false") 18666 (set_attr "mode" "SI") 18667 (set_attr "length_immediate" "0")]) 18668 18669(define_insn "*movsicc_noc" 18670 [(set (match_operand:SI 0 "register_operand" "=r,r") 18671 (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 18672 [(reg FLAGS_REG) (const_int 0)]) 18673 (match_operand:SI 2 "nonimmediate_operand" "rm,0") 18674 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))] 18675 "TARGET_CMOVE 18676 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 18677 "@ 18678 cmov%O2%C1\t{%2, %0|%0, %2} 18679 cmov%O2%c1\t{%3, %0|%0, %3}" 18680 [(set_attr "type" "icmov") 18681 (set_attr "mode" "SI")]) 18682 18683(define_expand "movhicc" 18684 [(set (match_operand:HI 0 "register_operand" "") 18685 (if_then_else:HI (match_operand 1 "comparison_operator" "") 18686 (match_operand:HI 2 "general_operand" "") 18687 (match_operand:HI 3 "general_operand" "")))] 18688 "TARGET_HIMODE_MATH" 18689 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 18690 18691(define_insn "*movhicc_noc" 18692 [(set (match_operand:HI 0 "register_operand" "=r,r") 18693 (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 18694 [(reg FLAGS_REG) (const_int 0)]) 18695 (match_operand:HI 2 "nonimmediate_operand" "rm,0") 18696 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))] 18697 "TARGET_CMOVE 18698 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 18699 "@ 18700 cmov%O2%C1\t{%2, %0|%0, %2} 18701 cmov%O2%c1\t{%3, %0|%0, %3}" 18702 [(set_attr "type" "icmov") 18703 (set_attr "mode" "HI")]) 18704 18705(define_expand "movqicc" 18706 [(set (match_operand:QI 0 "register_operand" "") 18707 (if_then_else:QI (match_operand 1 "comparison_operator" "") 18708 (match_operand:QI 2 "general_operand" "") 18709 (match_operand:QI 3 "general_operand" "")))] 18710 "TARGET_QIMODE_MATH" 18711 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 18712 18713(define_insn_and_split "*movqicc_noc" 18714 [(set (match_operand:QI 0 "register_operand" "=r,r") 18715 (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 18716 [(match_operand 4 "flags_reg_operand" "") 18717 (const_int 0)]) 18718 (match_operand:QI 2 "register_operand" "r,0") 18719 (match_operand:QI 3 "register_operand" "0,r")))] 18720 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL" 18721 "#" 18722 "&& reload_completed" 18723 [(set (match_dup 0) 18724 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) 18725 (match_dup 2) 18726 (match_dup 3)))] 18727 "operands[0] = gen_lowpart (SImode, operands[0]); 18728 operands[2] = gen_lowpart (SImode, operands[2]); 18729 operands[3] = gen_lowpart (SImode, operands[3]);" 18730 [(set_attr "type" "icmov") 18731 (set_attr "mode" "SI")]) 18732 18733(define_expand "movsfcc" 18734 [(set (match_operand:SF 0 "register_operand" "") 18735 (if_then_else:SF (match_operand 1 "comparison_operator" "") 18736 (match_operand:SF 2 "register_operand" "") 18737 (match_operand:SF 3 "register_operand" "")))] 18738 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH" 18739 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") 18740 18741(define_insn "*movsfcc_1_387" 18742 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f") 18743 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 18744 [(reg FLAGS_REG) (const_int 0)]) 18745 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0") 18746 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))] 18747 "TARGET_80387 && TARGET_CMOVE 18748 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 18749 "@ 18750 fcmov%F1\t{%2, %0|%0, %2} 18751 fcmov%f1\t{%3, %0|%0, %3} 18752 cmov%O2%C1\t{%2, %0|%0, %2} 18753 cmov%O2%c1\t{%3, %0|%0, %3}" 18754 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 18755 (set_attr "mode" "SF,SF,SI,SI")]) 18756 18757(define_expand "movdfcc" 18758 [(set (match_operand:DF 0 "register_operand" "") 18759 (if_then_else:DF (match_operand 1 "comparison_operator" "") 18760 (match_operand:DF 2 "register_operand" "") 18761 (match_operand:DF 3 "register_operand" "")))] 18762 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)" 18763 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") 18764 18765(define_insn "*movdfcc_1" 18766 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f") 18767 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 18768 [(reg FLAGS_REG) (const_int 0)]) 18769 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0") 18770 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))] 18771 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 18772 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 18773 "@ 18774 fcmov%F1\t{%2, %0|%0, %2} 18775 fcmov%f1\t{%3, %0|%0, %3} 18776 # 18777 #" 18778 [(set_attr "type" "fcmov,fcmov,multi,multi") 18779 (set_attr "mode" "DF")]) 18780 18781(define_insn "*movdfcc_1_rex64" 18782 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f") 18783 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 18784 [(reg FLAGS_REG) (const_int 0)]) 18785 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f") 18786 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))] 18787 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 18788 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 18789 "@ 18790 fcmov%F1\t{%2, %0|%0, %2} 18791 fcmov%f1\t{%3, %0|%0, %3} 18792 cmov%O2%C1\t{%2, %0|%0, %2} 18793 cmov%O2%c1\t{%3, %0|%0, %3}" 18794 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 18795 (set_attr "mode" "DF")]) 18796 18797(define_split 18798 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "") 18799 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 18800 [(match_operand 4 "flags_reg_operand" "") 18801 (const_int 0)]) 18802 (match_operand:DF 2 "nonimmediate_operand" "") 18803 (match_operand:DF 3 "nonimmediate_operand" "")))] 18804 "!TARGET_64BIT && reload_completed" 18805 [(set (match_dup 2) 18806 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) 18807 (match_dup 5) 18808 (match_dup 7))) 18809 (set (match_dup 3) 18810 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) 18811 (match_dup 6) 18812 (match_dup 8)))] 18813 "split_di (operands+2, 1, operands+5, operands+6); 18814 split_di (operands+3, 1, operands+7, operands+8); 18815 split_di (operands, 1, operands+2, operands+3);") 18816 18817(define_expand "movxfcc" 18818 [(set (match_operand:XF 0 "register_operand" "") 18819 (if_then_else:XF (match_operand 1 "comparison_operator" "") 18820 (match_operand:XF 2 "register_operand" "") 18821 (match_operand:XF 3 "register_operand" "")))] 18822 "TARGET_80387 && TARGET_CMOVE" 18823 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") 18824 18825(define_insn "*movxfcc_1" 18826 [(set (match_operand:XF 0 "register_operand" "=f,f") 18827 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 18828 [(reg FLAGS_REG) (const_int 0)]) 18829 (match_operand:XF 2 "register_operand" "f,0") 18830 (match_operand:XF 3 "register_operand" "0,f")))] 18831 "TARGET_80387 && TARGET_CMOVE" 18832 "@ 18833 fcmov%F1\t{%2, %0|%0, %2} 18834 fcmov%f1\t{%3, %0|%0, %3}" 18835 [(set_attr "type" "fcmov") 18836 (set_attr "mode" "XF")]) 18837 18838;; These versions of the min/max patterns are intentionally ignorant of 18839;; their behavior wrt -0.0 and NaN (via the commutative operand mark). 18840;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator 18841;; are undefined in this condition, we're certain this is correct. 18842 18843(define_insn "sminsf3" 18844 [(set (match_operand:SF 0 "register_operand" "=x") 18845 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0") 18846 (match_operand:SF 2 "nonimmediate_operand" "xm")))] 18847 "TARGET_SSE_MATH" 18848 "minss\t{%2, %0|%0, %2}" 18849 [(set_attr "type" "sseadd") 18850 (set_attr "mode" "SF")]) 18851 18852(define_insn "smaxsf3" 18853 [(set (match_operand:SF 0 "register_operand" "=x") 18854 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0") 18855 (match_operand:SF 2 "nonimmediate_operand" "xm")))] 18856 "TARGET_SSE_MATH" 18857 "maxss\t{%2, %0|%0, %2}" 18858 [(set_attr "type" "sseadd") 18859 (set_attr "mode" "SF")]) 18860 18861(define_insn "smindf3" 18862 [(set (match_operand:DF 0 "register_operand" "=x") 18863 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0") 18864 (match_operand:DF 2 "nonimmediate_operand" "xm")))] 18865 "TARGET_SSE2 && TARGET_SSE_MATH" 18866 "minsd\t{%2, %0|%0, %2}" 18867 [(set_attr "type" "sseadd") 18868 (set_attr "mode" "DF")]) 18869 18870(define_insn "smaxdf3" 18871 [(set (match_operand:DF 0 "register_operand" "=x") 18872 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0") 18873 (match_operand:DF 2 "nonimmediate_operand" "xm")))] 18874 "TARGET_SSE2 && TARGET_SSE_MATH" 18875 "maxsd\t{%2, %0|%0, %2}" 18876 [(set_attr "type" "sseadd") 18877 (set_attr "mode" "DF")]) 18878 18879;; These versions of the min/max patterns implement exactly the operations 18880;; min = (op1 < op2 ? op1 : op2) 18881;; max = (!(op1 < op2) ? op1 : op2) 18882;; Their operands are not commutative, and thus they may be used in the 18883;; presence of -0.0 and NaN. 18884 18885(define_insn "*ieee_sminsf3" 18886 [(set (match_operand:SF 0 "register_operand" "=x") 18887 (unspec:SF [(match_operand:SF 1 "register_operand" "0") 18888 (match_operand:SF 2 "nonimmediate_operand" "xm")] 18889 UNSPEC_IEEE_MIN))] 18890 "TARGET_SSE_MATH" 18891 "minss\t{%2, %0|%0, %2}" 18892 [(set_attr "type" "sseadd") 18893 (set_attr "mode" "SF")]) 18894 18895(define_insn "*ieee_smaxsf3" 18896 [(set (match_operand:SF 0 "register_operand" "=x") 18897 (unspec:SF [(match_operand:SF 1 "register_operand" "0") 18898 (match_operand:SF 2 "nonimmediate_operand" "xm")] 18899 UNSPEC_IEEE_MAX))] 18900 "TARGET_SSE_MATH" 18901 "maxss\t{%2, %0|%0, %2}" 18902 [(set_attr "type" "sseadd") 18903 (set_attr "mode" "SF")]) 18904 18905(define_insn "*ieee_smindf3" 18906 [(set (match_operand:DF 0 "register_operand" "=x") 18907 (unspec:DF [(match_operand:DF 1 "register_operand" "0") 18908 (match_operand:DF 2 "nonimmediate_operand" "xm")] 18909 UNSPEC_IEEE_MIN))] 18910 "TARGET_SSE2 && TARGET_SSE_MATH" 18911 "minsd\t{%2, %0|%0, %2}" 18912 [(set_attr "type" "sseadd") 18913 (set_attr "mode" "DF")]) 18914 18915(define_insn "*ieee_smaxdf3" 18916 [(set (match_operand:DF 0 "register_operand" "=x") 18917 (unspec:DF [(match_operand:DF 1 "register_operand" "0") 18918 (match_operand:DF 2 "nonimmediate_operand" "xm")] 18919 UNSPEC_IEEE_MAX))] 18920 "TARGET_SSE2 && TARGET_SSE_MATH" 18921 "maxsd\t{%2, %0|%0, %2}" 18922 [(set_attr "type" "sseadd") 18923 (set_attr "mode" "DF")]) 18924 18925;; Make two stack loads independent: 18926;; fld aa fld aa 18927;; fld %st(0) -> fld bb 18928;; fmul bb fmul %st(1), %st 18929;; 18930;; Actually we only match the last two instructions for simplicity. 18931(define_peephole2 18932 [(set (match_operand 0 "fp_register_operand" "") 18933 (match_operand 1 "fp_register_operand" "")) 18934 (set (match_dup 0) 18935 (match_operator 2 "binary_fp_operator" 18936 [(match_dup 0) 18937 (match_operand 3 "memory_operand" "")]))] 18938 "REGNO (operands[0]) != REGNO (operands[1])" 18939 [(set (match_dup 0) (match_dup 3)) 18940 (set (match_dup 0) (match_dup 4))] 18941 18942 ;; The % modifier is not operational anymore in peephole2's, so we have to 18943 ;; swap the operands manually in the case of addition and multiplication. 18944 "if (COMMUTATIVE_ARITH_P (operands[2])) 18945 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), 18946 operands[0], operands[1]); 18947 else 18948 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), 18949 operands[1], operands[0]);") 18950 18951;; Conditional addition patterns 18952(define_expand "addqicc" 18953 [(match_operand:QI 0 "register_operand" "") 18954 (match_operand 1 "comparison_operator" "") 18955 (match_operand:QI 2 "register_operand" "") 18956 (match_operand:QI 3 "const_int_operand" "")] 18957 "" 18958 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 18959 18960(define_expand "addhicc" 18961 [(match_operand:HI 0 "register_operand" "") 18962 (match_operand 1 "comparison_operator" "") 18963 (match_operand:HI 2 "register_operand" "") 18964 (match_operand:HI 3 "const_int_operand" "")] 18965 "" 18966 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 18967 18968(define_expand "addsicc" 18969 [(match_operand:SI 0 "register_operand" "") 18970 (match_operand 1 "comparison_operator" "") 18971 (match_operand:SI 2 "register_operand" "") 18972 (match_operand:SI 3 "const_int_operand" "")] 18973 "" 18974 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 18975 18976(define_expand "adddicc" 18977 [(match_operand:DI 0 "register_operand" "") 18978 (match_operand 1 "comparison_operator" "") 18979 (match_operand:DI 2 "register_operand" "") 18980 (match_operand:DI 3 "const_int_operand" "")] 18981 "TARGET_64BIT" 18982 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 18983 18984 18985;; Misc patterns (?) 18986 18987;; This pattern exists to put a dependency on all ebp-based memory accesses. 18988;; Otherwise there will be nothing to keep 18989;; 18990;; [(set (reg ebp) (reg esp))] 18991;; [(set (reg esp) (plus (reg esp) (const_int -160000))) 18992;; (clobber (eflags)] 18993;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))] 18994;; 18995;; in proper program order. 18996(define_insn "pro_epilogue_adjust_stack_1" 18997 [(set (match_operand:SI 0 "register_operand" "=r,r") 18998 (plus:SI (match_operand:SI 1 "register_operand" "0,r") 18999 (match_operand:SI 2 "immediate_operand" "i,i"))) 19000 (clobber (reg:CC FLAGS_REG)) 19001 (clobber (mem:BLK (scratch)))] 19002 "!TARGET_64BIT" 19003{ 19004 switch (get_attr_type (insn)) 19005 { 19006 case TYPE_IMOV: 19007 return "mov{l}\t{%1, %0|%0, %1}"; 19008 19009 case TYPE_ALU: 19010 if (GET_CODE (operands[2]) == CONST_INT 19011 && (INTVAL (operands[2]) == 128 19012 || (INTVAL (operands[2]) < 0 19013 && INTVAL (operands[2]) != -128))) 19014 { 19015 operands[2] = GEN_INT (-INTVAL (operands[2])); 19016 return "sub{l}\t{%2, %0|%0, %2}"; 19017 } 19018 return "add{l}\t{%2, %0|%0, %2}"; 19019 19020 case TYPE_LEA: 19021 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 19022 return "lea{l}\t{%a2, %0|%0, %a2}"; 19023 19024 default: 19025 gcc_unreachable (); 19026 } 19027} 19028 [(set (attr "type") 19029 (cond [(eq_attr "alternative" "0") 19030 (const_string "alu") 19031 (match_operand:SI 2 "const0_operand" "") 19032 (const_string "imov") 19033 ] 19034 (const_string "lea"))) 19035 (set_attr "mode" "SI")]) 19036 19037(define_insn "pro_epilogue_adjust_stack_rex64" 19038 [(set (match_operand:DI 0 "register_operand" "=r,r") 19039 (plus:DI (match_operand:DI 1 "register_operand" "0,r") 19040 (match_operand:DI 2 "x86_64_immediate_operand" "e,e"))) 19041 (clobber (reg:CC FLAGS_REG)) 19042 (clobber (mem:BLK (scratch)))] 19043 "TARGET_64BIT" 19044{ 19045 switch (get_attr_type (insn)) 19046 { 19047 case TYPE_IMOV: 19048 return "mov{q}\t{%1, %0|%0, %1}"; 19049 19050 case TYPE_ALU: 19051 if (GET_CODE (operands[2]) == CONST_INT 19052 /* Avoid overflows. */ 19053 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 19054 && (INTVAL (operands[2]) == 128 19055 || (INTVAL (operands[2]) < 0 19056 && INTVAL (operands[2]) != -128))) 19057 { 19058 operands[2] = GEN_INT (-INTVAL (operands[2])); 19059 return "sub{q}\t{%2, %0|%0, %2}"; 19060 } 19061 return "add{q}\t{%2, %0|%0, %2}"; 19062 19063 case TYPE_LEA: 19064 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 19065 return "lea{q}\t{%a2, %0|%0, %a2}"; 19066 19067 default: 19068 gcc_unreachable (); 19069 } 19070} 19071 [(set (attr "type") 19072 (cond [(eq_attr "alternative" "0") 19073 (const_string "alu") 19074 (match_operand:DI 2 "const0_operand" "") 19075 (const_string "imov") 19076 ] 19077 (const_string "lea"))) 19078 (set_attr "mode" "DI")]) 19079 19080(define_insn "pro_epilogue_adjust_stack_rex64_2" 19081 [(set (match_operand:DI 0 "register_operand" "=r,r") 19082 (plus:DI (match_operand:DI 1 "register_operand" "0,r") 19083 (match_operand:DI 3 "immediate_operand" "i,i"))) 19084 (use (match_operand:DI 2 "register_operand" "r,r")) 19085 (clobber (reg:CC FLAGS_REG)) 19086 (clobber (mem:BLK (scratch)))] 19087 "TARGET_64BIT" 19088{ 19089 switch (get_attr_type (insn)) 19090 { 19091 case TYPE_ALU: 19092 return "add{q}\t{%2, %0|%0, %2}"; 19093 19094 case TYPE_LEA: 19095 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]); 19096 return "lea{q}\t{%a2, %0|%0, %a2}"; 19097 19098 default: 19099 gcc_unreachable (); 19100 } 19101} 19102 [(set_attr "type" "alu,lea") 19103 (set_attr "mode" "DI")]) 19104 19105(define_expand "allocate_stack_worker" 19106 [(match_operand:SI 0 "register_operand" "")] 19107 "TARGET_STACK_PROBE" 19108{ 19109 if (reload_completed) 19110 { 19111 if (TARGET_64BIT) 19112 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0])); 19113 else 19114 emit_insn (gen_allocate_stack_worker_postreload (operands[0])); 19115 } 19116 else 19117 { 19118 if (TARGET_64BIT) 19119 emit_insn (gen_allocate_stack_worker_rex64 (operands[0])); 19120 else 19121 emit_insn (gen_allocate_stack_worker_1 (operands[0])); 19122 } 19123 DONE; 19124}) 19125 19126(define_insn "allocate_stack_worker_1" 19127 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")] 19128 UNSPECV_STACK_PROBE) 19129 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0))) 19130 (clobber (match_scratch:SI 1 "=0")) 19131 (clobber (reg:CC FLAGS_REG))] 19132 "!TARGET_64BIT && TARGET_STACK_PROBE" 19133 "call\t__alloca" 19134 [(set_attr "type" "multi") 19135 (set_attr "length" "5")]) 19136 19137(define_expand "allocate_stack_worker_postreload" 19138 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")] 19139 UNSPECV_STACK_PROBE) 19140 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0))) 19141 (clobber (match_dup 0)) 19142 (clobber (reg:CC FLAGS_REG))])] 19143 "" 19144 "") 19145 19146(define_insn "allocate_stack_worker_rex64" 19147 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")] 19148 UNSPECV_STACK_PROBE) 19149 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0))) 19150 (clobber (match_scratch:DI 1 "=0")) 19151 (clobber (reg:CC FLAGS_REG))] 19152 "TARGET_64BIT && TARGET_STACK_PROBE" 19153 "call\t__alloca" 19154 [(set_attr "type" "multi") 19155 (set_attr "length" "5")]) 19156 19157(define_expand "allocate_stack_worker_rex64_postreload" 19158 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")] 19159 UNSPECV_STACK_PROBE) 19160 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0))) 19161 (clobber (match_dup 0)) 19162 (clobber (reg:CC FLAGS_REG))])] 19163 "" 19164 "") 19165 19166(define_expand "allocate_stack" 19167 [(parallel [(set (match_operand:SI 0 "register_operand" "=r") 19168 (minus:SI (reg:SI SP_REG) 19169 (match_operand:SI 1 "general_operand" ""))) 19170 (clobber (reg:CC FLAGS_REG))]) 19171 (parallel [(set (reg:SI SP_REG) 19172 (minus:SI (reg:SI SP_REG) (match_dup 1))) 19173 (clobber (reg:CC FLAGS_REG))])] 19174 "TARGET_STACK_PROBE" 19175{ 19176#ifdef CHECK_STACK_LIMIT 19177 if (GET_CODE (operands[1]) == CONST_INT 19178 && INTVAL (operands[1]) < CHECK_STACK_LIMIT) 19179 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, 19180 operands[1])); 19181 else 19182#endif 19183 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode, 19184 operands[1]))); 19185 19186 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 19187 DONE; 19188}) 19189 19190(define_expand "builtin_setjmp_receiver" 19191 [(label_ref (match_operand 0 "" ""))] 19192 "!TARGET_64BIT && flag_pic" 19193{ 19194 emit_insn (gen_set_got (pic_offset_table_rtx)); 19195 DONE; 19196}) 19197 19198;; Avoid redundant prefixes by splitting HImode arithmetic to SImode. 19199 19200(define_split 19201 [(set (match_operand 0 "register_operand" "") 19202 (match_operator 3 "promotable_binary_operator" 19203 [(match_operand 1 "register_operand" "") 19204 (match_operand 2 "aligned_operand" "")])) 19205 (clobber (reg:CC FLAGS_REG))] 19206 "! TARGET_PARTIAL_REG_STALL && reload_completed 19207 && ((GET_MODE (operands[0]) == HImode 19208 && ((!optimize_size && !TARGET_FAST_PREFIX) 19209 || GET_CODE (operands[2]) != CONST_INT 19210 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))) 19211 || (GET_MODE (operands[0]) == QImode 19212 && (TARGET_PROMOTE_QImode || optimize_size)))" 19213 [(parallel [(set (match_dup 0) 19214 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 19215 (clobber (reg:CC FLAGS_REG))])] 19216 "operands[0] = gen_lowpart (SImode, operands[0]); 19217 operands[1] = gen_lowpart (SImode, operands[1]); 19218 if (GET_CODE (operands[3]) != ASHIFT) 19219 operands[2] = gen_lowpart (SImode, operands[2]); 19220 PUT_MODE (operands[3], SImode);") 19221 19222; Promote the QImode tests, as i386 has encoding of the AND 19223; instruction with 32-bit sign-extended immediate and thus the 19224; instruction size is unchanged, except in the %eax case for 19225; which it is increased by one byte, hence the ! optimize_size. 19226(define_split 19227 [(set (match_operand 0 "flags_reg_operand" "") 19228 (match_operator 2 "compare_operator" 19229 [(and (match_operand 3 "aligned_operand" "") 19230 (match_operand 4 "const_int_operand" "")) 19231 (const_int 0)])) 19232 (set (match_operand 1 "register_operand" "") 19233 (and (match_dup 3) (match_dup 4)))] 19234 "! TARGET_PARTIAL_REG_STALL && reload_completed 19235 /* Ensure that the operand will remain sign-extended immediate. */ 19236 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode) 19237 && ! optimize_size 19238 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX) 19239 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))" 19240 [(parallel [(set (match_dup 0) 19241 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4)) 19242 (const_int 0)])) 19243 (set (match_dup 1) 19244 (and:SI (match_dup 3) (match_dup 4)))])] 19245{ 19246 operands[4] 19247 = gen_int_mode (INTVAL (operands[4]) 19248 & GET_MODE_MASK (GET_MODE (operands[1])), SImode); 19249 operands[1] = gen_lowpart (SImode, operands[1]); 19250 operands[3] = gen_lowpart (SImode, operands[3]); 19251}) 19252 19253; Don't promote the QImode tests, as i386 doesn't have encoding of 19254; the TEST instruction with 32-bit sign-extended immediate and thus 19255; the instruction size would at least double, which is not what we 19256; want even with ! optimize_size. 19257(define_split 19258 [(set (match_operand 0 "flags_reg_operand" "") 19259 (match_operator 1 "compare_operator" 19260 [(and (match_operand:HI 2 "aligned_operand" "") 19261 (match_operand:HI 3 "const_int_operand" "")) 19262 (const_int 0)]))] 19263 "! TARGET_PARTIAL_REG_STALL && reload_completed 19264 /* Ensure that the operand will remain sign-extended immediate. */ 19265 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode) 19266 && ! TARGET_FAST_PREFIX 19267 && ! optimize_size" 19268 [(set (match_dup 0) 19269 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 19270 (const_int 0)]))] 19271{ 19272 operands[3] 19273 = gen_int_mode (INTVAL (operands[3]) 19274 & GET_MODE_MASK (GET_MODE (operands[2])), SImode); 19275 operands[2] = gen_lowpart (SImode, operands[2]); 19276}) 19277 19278(define_split 19279 [(set (match_operand 0 "register_operand" "") 19280 (neg (match_operand 1 "register_operand" ""))) 19281 (clobber (reg:CC FLAGS_REG))] 19282 "! TARGET_PARTIAL_REG_STALL && reload_completed 19283 && (GET_MODE (operands[0]) == HImode 19284 || (GET_MODE (operands[0]) == QImode 19285 && (TARGET_PROMOTE_QImode || optimize_size)))" 19286 [(parallel [(set (match_dup 0) 19287 (neg:SI (match_dup 1))) 19288 (clobber (reg:CC FLAGS_REG))])] 19289 "operands[0] = gen_lowpart (SImode, operands[0]); 19290 operands[1] = gen_lowpart (SImode, operands[1]);") 19291 19292(define_split 19293 [(set (match_operand 0 "register_operand" "") 19294 (not (match_operand 1 "register_operand" "")))] 19295 "! TARGET_PARTIAL_REG_STALL && reload_completed 19296 && (GET_MODE (operands[0]) == HImode 19297 || (GET_MODE (operands[0]) == QImode 19298 && (TARGET_PROMOTE_QImode || optimize_size)))" 19299 [(set (match_dup 0) 19300 (not:SI (match_dup 1)))] 19301 "operands[0] = gen_lowpart (SImode, operands[0]); 19302 operands[1] = gen_lowpart (SImode, operands[1]);") 19303 19304(define_split 19305 [(set (match_operand 0 "register_operand" "") 19306 (if_then_else (match_operator 1 "comparison_operator" 19307 [(reg FLAGS_REG) (const_int 0)]) 19308 (match_operand 2 "register_operand" "") 19309 (match_operand 3 "register_operand" "")))] 19310 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE 19311 && (GET_MODE (operands[0]) == HImode 19312 || (GET_MODE (operands[0]) == QImode 19313 && (TARGET_PROMOTE_QImode || optimize_size)))" 19314 [(set (match_dup 0) 19315 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))] 19316 "operands[0] = gen_lowpart (SImode, operands[0]); 19317 operands[2] = gen_lowpart (SImode, operands[2]); 19318 operands[3] = gen_lowpart (SImode, operands[3]);") 19319 19320 19321;; RTL Peephole optimizations, run before sched2. These primarily look to 19322;; transform a complex memory operation into two memory to register operations. 19323 19324;; Don't push memory operands 19325(define_peephole2 19326 [(set (match_operand:SI 0 "push_operand" "") 19327 (match_operand:SI 1 "memory_operand" "")) 19328 (match_scratch:SI 2 "r")] 19329 "!optimize_size && !TARGET_PUSH_MEMORY 19330 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19331 [(set (match_dup 2) (match_dup 1)) 19332 (set (match_dup 0) (match_dup 2))] 19333 "") 19334 19335(define_peephole2 19336 [(set (match_operand:DI 0 "push_operand" "") 19337 (match_operand:DI 1 "memory_operand" "")) 19338 (match_scratch:DI 2 "r")] 19339 "!optimize_size && !TARGET_PUSH_MEMORY 19340 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19341 [(set (match_dup 2) (match_dup 1)) 19342 (set (match_dup 0) (match_dup 2))] 19343 "") 19344 19345;; We need to handle SFmode only, because DFmode and XFmode is split to 19346;; SImode pushes. 19347(define_peephole2 19348 [(set (match_operand:SF 0 "push_operand" "") 19349 (match_operand:SF 1 "memory_operand" "")) 19350 (match_scratch:SF 2 "r")] 19351 "!optimize_size && !TARGET_PUSH_MEMORY 19352 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19353 [(set (match_dup 2) (match_dup 1)) 19354 (set (match_dup 0) (match_dup 2))] 19355 "") 19356 19357(define_peephole2 19358 [(set (match_operand:HI 0 "push_operand" "") 19359 (match_operand:HI 1 "memory_operand" "")) 19360 (match_scratch:HI 2 "r")] 19361 "!optimize_size && !TARGET_PUSH_MEMORY 19362 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19363 [(set (match_dup 2) (match_dup 1)) 19364 (set (match_dup 0) (match_dup 2))] 19365 "") 19366 19367(define_peephole2 19368 [(set (match_operand:QI 0 "push_operand" "") 19369 (match_operand:QI 1 "memory_operand" "")) 19370 (match_scratch:QI 2 "q")] 19371 "!optimize_size && !TARGET_PUSH_MEMORY 19372 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19373 [(set (match_dup 2) (match_dup 1)) 19374 (set (match_dup 0) (match_dup 2))] 19375 "") 19376 19377;; Don't move an immediate directly to memory when the instruction 19378;; gets too big. 19379(define_peephole2 19380 [(match_scratch:SI 1 "r") 19381 (set (match_operand:SI 0 "memory_operand" "") 19382 (const_int 0))] 19383 "! optimize_size 19384 && ! TARGET_USE_MOV0 19385 && TARGET_SPLIT_LONG_MOVES 19386 && get_attr_length (insn) >= ix86_cost->large_insn 19387 && peep2_regno_dead_p (0, FLAGS_REG)" 19388 [(parallel [(set (match_dup 1) (const_int 0)) 19389 (clobber (reg:CC FLAGS_REG))]) 19390 (set (match_dup 0) (match_dup 1))] 19391 "") 19392 19393(define_peephole2 19394 [(match_scratch:HI 1 "r") 19395 (set (match_operand:HI 0 "memory_operand" "") 19396 (const_int 0))] 19397 "! optimize_size 19398 && ! TARGET_USE_MOV0 19399 && TARGET_SPLIT_LONG_MOVES 19400 && get_attr_length (insn) >= ix86_cost->large_insn 19401 && peep2_regno_dead_p (0, FLAGS_REG)" 19402 [(parallel [(set (match_dup 2) (const_int 0)) 19403 (clobber (reg:CC FLAGS_REG))]) 19404 (set (match_dup 0) (match_dup 1))] 19405 "operands[2] = gen_lowpart (SImode, operands[1]);") 19406 19407(define_peephole2 19408 [(match_scratch:QI 1 "q") 19409 (set (match_operand:QI 0 "memory_operand" "") 19410 (const_int 0))] 19411 "! optimize_size 19412 && ! TARGET_USE_MOV0 19413 && TARGET_SPLIT_LONG_MOVES 19414 && get_attr_length (insn) >= ix86_cost->large_insn 19415 && peep2_regno_dead_p (0, FLAGS_REG)" 19416 [(parallel [(set (match_dup 2) (const_int 0)) 19417 (clobber (reg:CC FLAGS_REG))]) 19418 (set (match_dup 0) (match_dup 1))] 19419 "operands[2] = gen_lowpart (SImode, operands[1]);") 19420 19421(define_peephole2 19422 [(match_scratch:SI 2 "r") 19423 (set (match_operand:SI 0 "memory_operand" "") 19424 (match_operand:SI 1 "immediate_operand" ""))] 19425 "! optimize_size 19426 && get_attr_length (insn) >= ix86_cost->large_insn 19427 && TARGET_SPLIT_LONG_MOVES" 19428 [(set (match_dup 2) (match_dup 1)) 19429 (set (match_dup 0) (match_dup 2))] 19430 "") 19431 19432(define_peephole2 19433 [(match_scratch:HI 2 "r") 19434 (set (match_operand:HI 0 "memory_operand" "") 19435 (match_operand:HI 1 "immediate_operand" ""))] 19436 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn 19437 && TARGET_SPLIT_LONG_MOVES" 19438 [(set (match_dup 2) (match_dup 1)) 19439 (set (match_dup 0) (match_dup 2))] 19440 "") 19441 19442(define_peephole2 19443 [(match_scratch:QI 2 "q") 19444 (set (match_operand:QI 0 "memory_operand" "") 19445 (match_operand:QI 1 "immediate_operand" ""))] 19446 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn 19447 && TARGET_SPLIT_LONG_MOVES" 19448 [(set (match_dup 2) (match_dup 1)) 19449 (set (match_dup 0) (match_dup 2))] 19450 "") 19451 19452;; Don't compare memory with zero, load and use a test instead. 19453(define_peephole2 19454 [(set (match_operand 0 "flags_reg_operand" "") 19455 (match_operator 1 "compare_operator" 19456 [(match_operand:SI 2 "memory_operand" "") 19457 (const_int 0)])) 19458 (match_scratch:SI 3 "r")] 19459 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size" 19460 [(set (match_dup 3) (match_dup 2)) 19461 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))] 19462 "") 19463 19464;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 19465;; Don't split NOTs with a displacement operand, because resulting XOR 19466;; will not be pairable anyway. 19467;; 19468;; On AMD K6, NOT is vector decoded with memory operand that cannot be 19469;; represented using a modRM byte. The XOR replacement is long decoded, 19470;; so this split helps here as well. 19471;; 19472;; Note: Can't do this as a regular split because we can't get proper 19473;; lifetime information then. 19474 19475(define_peephole2 19476 [(set (match_operand:SI 0 "nonimmediate_operand" "") 19477 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))] 19478 "!optimize_size 19479 && peep2_regno_dead_p (0, FLAGS_REG) 19480 && ((TARGET_PENTIUM 19481 && (GET_CODE (operands[0]) != MEM 19482 || !memory_displacement_operand (operands[0], SImode))) 19483 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))" 19484 [(parallel [(set (match_dup 0) 19485 (xor:SI (match_dup 1) (const_int -1))) 19486 (clobber (reg:CC FLAGS_REG))])] 19487 "") 19488 19489(define_peephole2 19490 [(set (match_operand:HI 0 "nonimmediate_operand" "") 19491 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))] 19492 "!optimize_size 19493 && peep2_regno_dead_p (0, FLAGS_REG) 19494 && ((TARGET_PENTIUM 19495 && (GET_CODE (operands[0]) != MEM 19496 || !memory_displacement_operand (operands[0], HImode))) 19497 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))" 19498 [(parallel [(set (match_dup 0) 19499 (xor:HI (match_dup 1) (const_int -1))) 19500 (clobber (reg:CC FLAGS_REG))])] 19501 "") 19502 19503(define_peephole2 19504 [(set (match_operand:QI 0 "nonimmediate_operand" "") 19505 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))] 19506 "!optimize_size 19507 && peep2_regno_dead_p (0, FLAGS_REG) 19508 && ((TARGET_PENTIUM 19509 && (GET_CODE (operands[0]) != MEM 19510 || !memory_displacement_operand (operands[0], QImode))) 19511 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))" 19512 [(parallel [(set (match_dup 0) 19513 (xor:QI (match_dup 1) (const_int -1))) 19514 (clobber (reg:CC FLAGS_REG))])] 19515 "") 19516 19517;; Non pairable "test imm, reg" instructions can be translated to 19518;; "and imm, reg" if reg dies. The "and" form is also shorter (one 19519;; byte opcode instead of two, have a short form for byte operands), 19520;; so do it for other CPUs as well. Given that the value was dead, 19521;; this should not create any new dependencies. Pass on the sub-word 19522;; versions if we're concerned about partial register stalls. 19523 19524(define_peephole2 19525 [(set (match_operand 0 "flags_reg_operand" "") 19526 (match_operator 1 "compare_operator" 19527 [(and:SI (match_operand:SI 2 "register_operand" "") 19528 (match_operand:SI 3 "immediate_operand" "")) 19529 (const_int 0)]))] 19530 "ix86_match_ccmode (insn, CCNOmode) 19531 && (true_regnum (operands[2]) != 0 19532 || (GET_CODE (operands[3]) == CONST_INT 19533 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K'))) 19534 && peep2_reg_dead_p (1, operands[2])" 19535 [(parallel 19536 [(set (match_dup 0) 19537 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 19538 (const_int 0)])) 19539 (set (match_dup 2) 19540 (and:SI (match_dup 2) (match_dup 3)))])] 19541 "") 19542 19543;; We don't need to handle HImode case, because it will be promoted to SImode 19544;; on ! TARGET_PARTIAL_REG_STALL 19545 19546(define_peephole2 19547 [(set (match_operand 0 "flags_reg_operand" "") 19548 (match_operator 1 "compare_operator" 19549 [(and:QI (match_operand:QI 2 "register_operand" "") 19550 (match_operand:QI 3 "immediate_operand" "")) 19551 (const_int 0)]))] 19552 "! TARGET_PARTIAL_REG_STALL 19553 && ix86_match_ccmode (insn, CCNOmode) 19554 && true_regnum (operands[2]) != 0 19555 && peep2_reg_dead_p (1, operands[2])" 19556 [(parallel 19557 [(set (match_dup 0) 19558 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 19559 (const_int 0)])) 19560 (set (match_dup 2) 19561 (and:QI (match_dup 2) (match_dup 3)))])] 19562 "") 19563 19564(define_peephole2 19565 [(set (match_operand 0 "flags_reg_operand" "") 19566 (match_operator 1 "compare_operator" 19567 [(and:SI 19568 (zero_extract:SI 19569 (match_operand 2 "ext_register_operand" "") 19570 (const_int 8) 19571 (const_int 8)) 19572 (match_operand 3 "const_int_operand" "")) 19573 (const_int 0)]))] 19574 "! TARGET_PARTIAL_REG_STALL 19575 && ix86_match_ccmode (insn, CCNOmode) 19576 && true_regnum (operands[2]) != 0 19577 && peep2_reg_dead_p (1, operands[2])" 19578 [(parallel [(set (match_dup 0) 19579 (match_op_dup 1 19580 [(and:SI 19581 (zero_extract:SI 19582 (match_dup 2) 19583 (const_int 8) 19584 (const_int 8)) 19585 (match_dup 3)) 19586 (const_int 0)])) 19587 (set (zero_extract:SI (match_dup 2) 19588 (const_int 8) 19589 (const_int 8)) 19590 (and:SI 19591 (zero_extract:SI 19592 (match_dup 2) 19593 (const_int 8) 19594 (const_int 8)) 19595 (match_dup 3)))])] 19596 "") 19597 19598;; Don't do logical operations with memory inputs. 19599(define_peephole2 19600 [(match_scratch:SI 2 "r") 19601 (parallel [(set (match_operand:SI 0 "register_operand" "") 19602 (match_operator:SI 3 "arith_or_logical_operator" 19603 [(match_dup 0) 19604 (match_operand:SI 1 "memory_operand" "")])) 19605 (clobber (reg:CC FLAGS_REG))])] 19606 "! optimize_size && ! TARGET_READ_MODIFY" 19607 [(set (match_dup 2) (match_dup 1)) 19608 (parallel [(set (match_dup 0) 19609 (match_op_dup 3 [(match_dup 0) (match_dup 2)])) 19610 (clobber (reg:CC FLAGS_REG))])] 19611 "") 19612 19613(define_peephole2 19614 [(match_scratch:SI 2 "r") 19615 (parallel [(set (match_operand:SI 0 "register_operand" "") 19616 (match_operator:SI 3 "arith_or_logical_operator" 19617 [(match_operand:SI 1 "memory_operand" "") 19618 (match_dup 0)])) 19619 (clobber (reg:CC FLAGS_REG))])] 19620 "! optimize_size && ! TARGET_READ_MODIFY" 19621 [(set (match_dup 2) (match_dup 1)) 19622 (parallel [(set (match_dup 0) 19623 (match_op_dup 3 [(match_dup 2) (match_dup 0)])) 19624 (clobber (reg:CC FLAGS_REG))])] 19625 "") 19626 19627; Don't do logical operations with memory outputs 19628; 19629; These two don't make sense for PPro/PII -- we're expanding a 4-uop 19630; instruction into two 1-uop insns plus a 2-uop insn. That last has 19631; the same decoder scheduling characteristics as the original. 19632 19633(define_peephole2 19634 [(match_scratch:SI 2 "r") 19635 (parallel [(set (match_operand:SI 0 "memory_operand" "") 19636 (match_operator:SI 3 "arith_or_logical_operator" 19637 [(match_dup 0) 19638 (match_operand:SI 1 "nonmemory_operand" "")])) 19639 (clobber (reg:CC FLAGS_REG))])] 19640 "! optimize_size && ! TARGET_READ_MODIFY_WRITE" 19641 [(set (match_dup 2) (match_dup 0)) 19642 (parallel [(set (match_dup 2) 19643 (match_op_dup 3 [(match_dup 2) (match_dup 1)])) 19644 (clobber (reg:CC FLAGS_REG))]) 19645 (set (match_dup 0) (match_dup 2))] 19646 "") 19647 19648(define_peephole2 19649 [(match_scratch:SI 2 "r") 19650 (parallel [(set (match_operand:SI 0 "memory_operand" "") 19651 (match_operator:SI 3 "arith_or_logical_operator" 19652 [(match_operand:SI 1 "nonmemory_operand" "") 19653 (match_dup 0)])) 19654 (clobber (reg:CC FLAGS_REG))])] 19655 "! optimize_size && ! TARGET_READ_MODIFY_WRITE" 19656 [(set (match_dup 2) (match_dup 0)) 19657 (parallel [(set (match_dup 2) 19658 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 19659 (clobber (reg:CC FLAGS_REG))]) 19660 (set (match_dup 0) (match_dup 2))] 19661 "") 19662 19663;; Attempt to always use XOR for zeroing registers. 19664(define_peephole2 19665 [(set (match_operand 0 "register_operand" "") 19666 (match_operand 1 "const0_operand" ""))] 19667 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD 19668 && (! TARGET_USE_MOV0 || optimize_size) 19669 && GENERAL_REG_P (operands[0]) 19670 && peep2_regno_dead_p (0, FLAGS_REG)" 19671 [(parallel [(set (match_dup 0) (const_int 0)) 19672 (clobber (reg:CC FLAGS_REG))])] 19673{ 19674 operands[0] = gen_lowpart (word_mode, operands[0]); 19675}) 19676 19677(define_peephole2 19678 [(set (strict_low_part (match_operand 0 "register_operand" "")) 19679 (const_int 0))] 19680 "(GET_MODE (operands[0]) == QImode 19681 || GET_MODE (operands[0]) == HImode) 19682 && (! TARGET_USE_MOV0 || optimize_size) 19683 && peep2_regno_dead_p (0, FLAGS_REG)" 19684 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0)) 19685 (clobber (reg:CC FLAGS_REG))])]) 19686 19687;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg. 19688(define_peephole2 19689 [(set (match_operand 0 "register_operand" "") 19690 (const_int -1))] 19691 "(GET_MODE (operands[0]) == HImode 19692 || GET_MODE (operands[0]) == SImode 19693 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT)) 19694 && (optimize_size || TARGET_PENTIUM) 19695 && peep2_regno_dead_p (0, FLAGS_REG)" 19696 [(parallel [(set (match_dup 0) (const_int -1)) 19697 (clobber (reg:CC FLAGS_REG))])] 19698 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode, 19699 operands[0]);") 19700 19701;; Attempt to convert simple leas to adds. These can be created by 19702;; move expanders. 19703(define_peephole2 19704 [(set (match_operand:SI 0 "register_operand" "") 19705 (plus:SI (match_dup 0) 19706 (match_operand:SI 1 "nonmemory_operand" "")))] 19707 "peep2_regno_dead_p (0, FLAGS_REG)" 19708 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) 19709 (clobber (reg:CC FLAGS_REG))])] 19710 "") 19711 19712(define_peephole2 19713 [(set (match_operand:SI 0 "register_operand" "") 19714 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "") 19715 (match_operand:DI 2 "nonmemory_operand" "")) 0))] 19716 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])" 19717 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2))) 19718 (clobber (reg:CC FLAGS_REG))])] 19719 "operands[2] = gen_lowpart (SImode, operands[2]);") 19720 19721(define_peephole2 19722 [(set (match_operand:DI 0 "register_operand" "") 19723 (plus:DI (match_dup 0) 19724 (match_operand:DI 1 "x86_64_general_operand" "")))] 19725 "peep2_regno_dead_p (0, FLAGS_REG)" 19726 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1))) 19727 (clobber (reg:CC FLAGS_REG))])] 19728 "") 19729 19730(define_peephole2 19731 [(set (match_operand:SI 0 "register_operand" "") 19732 (mult:SI (match_dup 0) 19733 (match_operand:SI 1 "const_int_operand" "")))] 19734 "exact_log2 (INTVAL (operands[1])) >= 0 19735 && peep2_regno_dead_p (0, FLAGS_REG)" 19736 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) 19737 (clobber (reg:CC FLAGS_REG))])] 19738 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));") 19739 19740(define_peephole2 19741 [(set (match_operand:DI 0 "register_operand" "") 19742 (mult:DI (match_dup 0) 19743 (match_operand:DI 1 "const_int_operand" "")))] 19744 "exact_log2 (INTVAL (operands[1])) >= 0 19745 && peep2_regno_dead_p (0, FLAGS_REG)" 19746 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2))) 19747 (clobber (reg:CC FLAGS_REG))])] 19748 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));") 19749 19750(define_peephole2 19751 [(set (match_operand:SI 0 "register_operand" "") 19752 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "") 19753 (match_operand:DI 2 "const_int_operand" "")) 0))] 19754 "exact_log2 (INTVAL (operands[2])) >= 0 19755 && REGNO (operands[0]) == REGNO (operands[1]) 19756 && peep2_regno_dead_p (0, FLAGS_REG)" 19757 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) 19758 (clobber (reg:CC FLAGS_REG))])] 19759 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));") 19760 19761;; The ESP adjustments can be done by the push and pop instructions. Resulting 19762;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On 19763;; many CPUs it is also faster, since special hardware to avoid esp 19764;; dependencies is present. 19765 19766;; While some of these conversions may be done using splitters, we use peepholes 19767;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL. 19768 19769;; Convert prologue esp subtractions to push. 19770;; We need register to push. In order to keep verify_flow_info happy we have 19771;; two choices 19772;; - use scratch and clobber it in order to avoid dependencies 19773;; - use already live register 19774;; We can't use the second way right now, since there is no reliable way how to 19775;; verify that given register is live. First choice will also most likely in 19776;; fewer dependencies. On the place of esp adjustments it is very likely that 19777;; call clobbered registers are dead. We may want to use base pointer as an 19778;; alternative when no register is available later. 19779 19780(define_peephole2 19781 [(match_scratch:SI 0 "r") 19782 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) 19783 (clobber (reg:CC FLAGS_REG)) 19784 (clobber (mem:BLK (scratch)))])] 19785 "optimize_size || !TARGET_SUB_ESP_4" 19786 [(clobber (match_dup 0)) 19787 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 19788 (clobber (mem:BLK (scratch)))])]) 19789 19790(define_peephole2 19791 [(match_scratch:SI 0 "r") 19792 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 19793 (clobber (reg:CC FLAGS_REG)) 19794 (clobber (mem:BLK (scratch)))])] 19795 "optimize_size || !TARGET_SUB_ESP_8" 19796 [(clobber (match_dup 0)) 19797 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 19798 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 19799 (clobber (mem:BLK (scratch)))])]) 19800 19801;; Convert esp subtractions to push. 19802(define_peephole2 19803 [(match_scratch:SI 0 "r") 19804 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) 19805 (clobber (reg:CC FLAGS_REG))])] 19806 "optimize_size || !TARGET_SUB_ESP_4" 19807 [(clobber (match_dup 0)) 19808 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))]) 19809 19810(define_peephole2 19811 [(match_scratch:SI 0 "r") 19812 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 19813 (clobber (reg:CC FLAGS_REG))])] 19814 "optimize_size || !TARGET_SUB_ESP_8" 19815 [(clobber (match_dup 0)) 19816 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 19817 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))]) 19818 19819;; Convert epilogue deallocator to pop. 19820(define_peephole2 19821 [(match_scratch:SI 0 "r") 19822 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 19823 (clobber (reg:CC FLAGS_REG)) 19824 (clobber (mem:BLK (scratch)))])] 19825 "optimize_size || !TARGET_ADD_ESP_4" 19826 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 19827 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 19828 (clobber (mem:BLK (scratch)))])] 19829 "") 19830 19831;; Two pops case is tricky, since pop causes dependency on destination register. 19832;; We use two registers if available. 19833(define_peephole2 19834 [(match_scratch:SI 0 "r") 19835 (match_scratch:SI 1 "r") 19836 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 19837 (clobber (reg:CC FLAGS_REG)) 19838 (clobber (mem:BLK (scratch)))])] 19839 "optimize_size || !TARGET_ADD_ESP_8" 19840 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 19841 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 19842 (clobber (mem:BLK (scratch)))]) 19843 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG))) 19844 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 19845 "") 19846 19847(define_peephole2 19848 [(match_scratch:SI 0 "r") 19849 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 19850 (clobber (reg:CC FLAGS_REG)) 19851 (clobber (mem:BLK (scratch)))])] 19852 "optimize_size" 19853 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 19854 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 19855 (clobber (mem:BLK (scratch)))]) 19856 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 19857 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 19858 "") 19859 19860;; Convert esp additions to pop. 19861(define_peephole2 19862 [(match_scratch:SI 0 "r") 19863 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 19864 (clobber (reg:CC FLAGS_REG))])] 19865 "" 19866 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 19867 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 19868 "") 19869 19870;; Two pops case is tricky, since pop causes dependency on destination register. 19871;; We use two registers if available. 19872(define_peephole2 19873 [(match_scratch:SI 0 "r") 19874 (match_scratch:SI 1 "r") 19875 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 19876 (clobber (reg:CC FLAGS_REG))])] 19877 "" 19878 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 19879 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))]) 19880 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG))) 19881 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 19882 "") 19883 19884(define_peephole2 19885 [(match_scratch:SI 0 "r") 19886 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 19887 (clobber (reg:CC FLAGS_REG))])] 19888 "optimize_size" 19889 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 19890 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))]) 19891 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 19892 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 19893 "") 19894 19895;; Convert compares with 1 to shorter inc/dec operations when CF is not 19896;; required and register dies. Similarly for 128 to plus -128. 19897(define_peephole2 19898 [(set (match_operand 0 "flags_reg_operand" "") 19899 (match_operator 1 "compare_operator" 19900 [(match_operand 2 "register_operand" "") 19901 (match_operand 3 "const_int_operand" "")]))] 19902 "(INTVAL (operands[3]) == -1 19903 || INTVAL (operands[3]) == 1 19904 || INTVAL (operands[3]) == 128) 19905 && ix86_match_ccmode (insn, CCGCmode) 19906 && peep2_reg_dead_p (1, operands[2])" 19907 [(parallel [(set (match_dup 0) 19908 (match_op_dup 1 [(match_dup 2) (match_dup 3)])) 19909 (clobber (match_dup 2))])] 19910 "") 19911 19912(define_peephole2 19913 [(match_scratch:DI 0 "r") 19914 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 19915 (clobber (reg:CC FLAGS_REG)) 19916 (clobber (mem:BLK (scratch)))])] 19917 "optimize_size || !TARGET_SUB_ESP_4" 19918 [(clobber (match_dup 0)) 19919 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 19920 (clobber (mem:BLK (scratch)))])]) 19921 19922(define_peephole2 19923 [(match_scratch:DI 0 "r") 19924 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16))) 19925 (clobber (reg:CC FLAGS_REG)) 19926 (clobber (mem:BLK (scratch)))])] 19927 "optimize_size || !TARGET_SUB_ESP_8" 19928 [(clobber (match_dup 0)) 19929 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 19930 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 19931 (clobber (mem:BLK (scratch)))])]) 19932 19933;; Convert esp subtractions to push. 19934(define_peephole2 19935 [(match_scratch:DI 0 "r") 19936 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 19937 (clobber (reg:CC FLAGS_REG))])] 19938 "optimize_size || !TARGET_SUB_ESP_4" 19939 [(clobber (match_dup 0)) 19940 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))]) 19941 19942(define_peephole2 19943 [(match_scratch:DI 0 "r") 19944 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16))) 19945 (clobber (reg:CC FLAGS_REG))])] 19946 "optimize_size || !TARGET_SUB_ESP_8" 19947 [(clobber (match_dup 0)) 19948 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 19949 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))]) 19950 19951;; Convert epilogue deallocator to pop. 19952(define_peephole2 19953 [(match_scratch:DI 0 "r") 19954 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 19955 (clobber (reg:CC FLAGS_REG)) 19956 (clobber (mem:BLK (scratch)))])] 19957 "optimize_size || !TARGET_ADD_ESP_4" 19958 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 19959 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 19960 (clobber (mem:BLK (scratch)))])] 19961 "") 19962 19963;; Two pops case is tricky, since pop causes dependency on destination register. 19964;; We use two registers if available. 19965(define_peephole2 19966 [(match_scratch:DI 0 "r") 19967 (match_scratch:DI 1 "r") 19968 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 19969 (clobber (reg:CC FLAGS_REG)) 19970 (clobber (mem:BLK (scratch)))])] 19971 "optimize_size || !TARGET_ADD_ESP_8" 19972 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 19973 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 19974 (clobber (mem:BLK (scratch)))]) 19975 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG))) 19976 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 19977 "") 19978 19979(define_peephole2 19980 [(match_scratch:DI 0 "r") 19981 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 19982 (clobber (reg:CC FLAGS_REG)) 19983 (clobber (mem:BLK (scratch)))])] 19984 "optimize_size" 19985 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 19986 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 19987 (clobber (mem:BLK (scratch)))]) 19988 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 19989 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 19990 "") 19991 19992;; Convert esp additions to pop. 19993(define_peephole2 19994 [(match_scratch:DI 0 "r") 19995 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 19996 (clobber (reg:CC FLAGS_REG))])] 19997 "" 19998 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 19999 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20000 "") 20001 20002;; Two pops case is tricky, since pop causes dependency on destination register. 20003;; We use two registers if available. 20004(define_peephole2 20005 [(match_scratch:DI 0 "r") 20006 (match_scratch:DI 1 "r") 20007 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20008 (clobber (reg:CC FLAGS_REG))])] 20009 "" 20010 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20011 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))]) 20012 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG))) 20013 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20014 "") 20015 20016(define_peephole2 20017 [(match_scratch:DI 0 "r") 20018 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20019 (clobber (reg:CC FLAGS_REG))])] 20020 "optimize_size" 20021 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20022 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))]) 20023 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20024 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20025 "") 20026 20027;; Convert imul by three, five and nine into lea 20028(define_peephole2 20029 [(parallel 20030 [(set (match_operand:SI 0 "register_operand" "") 20031 (mult:SI (match_operand:SI 1 "register_operand" "") 20032 (match_operand:SI 2 "const_int_operand" ""))) 20033 (clobber (reg:CC FLAGS_REG))])] 20034 "INTVAL (operands[2]) == 3 20035 || INTVAL (operands[2]) == 5 20036 || INTVAL (operands[2]) == 9" 20037 [(set (match_dup 0) 20038 (plus:SI (mult:SI (match_dup 1) (match_dup 2)) 20039 (match_dup 1)))] 20040 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20041 20042(define_peephole2 20043 [(parallel 20044 [(set (match_operand:SI 0 "register_operand" "") 20045 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "") 20046 (match_operand:SI 2 "const_int_operand" ""))) 20047 (clobber (reg:CC FLAGS_REG))])] 20048 "!optimize_size 20049 && (INTVAL (operands[2]) == 3 20050 || INTVAL (operands[2]) == 5 20051 || INTVAL (operands[2]) == 9)" 20052 [(set (match_dup 0) (match_dup 1)) 20053 (set (match_dup 0) 20054 (plus:SI (mult:SI (match_dup 0) (match_dup 2)) 20055 (match_dup 0)))] 20056 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20057 20058(define_peephole2 20059 [(parallel 20060 [(set (match_operand:DI 0 "register_operand" "") 20061 (mult:DI (match_operand:DI 1 "register_operand" "") 20062 (match_operand:DI 2 "const_int_operand" ""))) 20063 (clobber (reg:CC FLAGS_REG))])] 20064 "TARGET_64BIT 20065 && (INTVAL (operands[2]) == 3 20066 || INTVAL (operands[2]) == 5 20067 || INTVAL (operands[2]) == 9)" 20068 [(set (match_dup 0) 20069 (plus:DI (mult:DI (match_dup 1) (match_dup 2)) 20070 (match_dup 1)))] 20071 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20072 20073(define_peephole2 20074 [(parallel 20075 [(set (match_operand:DI 0 "register_operand" "") 20076 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "") 20077 (match_operand:DI 2 "const_int_operand" ""))) 20078 (clobber (reg:CC FLAGS_REG))])] 20079 "TARGET_64BIT 20080 && !optimize_size 20081 && (INTVAL (operands[2]) == 3 20082 || INTVAL (operands[2]) == 5 20083 || INTVAL (operands[2]) == 9)" 20084 [(set (match_dup 0) (match_dup 1)) 20085 (set (match_dup 0) 20086 (plus:DI (mult:DI (match_dup 0) (match_dup 2)) 20087 (match_dup 0)))] 20088 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20089 20090;; Imul $32bit_imm, mem, reg is vector decoded, while 20091;; imul $32bit_imm, reg, reg is direct decoded. 20092(define_peephole2 20093 [(match_scratch:DI 3 "r") 20094 (parallel [(set (match_operand:DI 0 "register_operand" "") 20095 (mult:DI (match_operand:DI 1 "memory_operand" "") 20096 (match_operand:DI 2 "immediate_operand" ""))) 20097 (clobber (reg:CC FLAGS_REG))])] 20098 "TARGET_K8 && !optimize_size 20099 && (GET_CODE (operands[2]) != CONST_INT 20100 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))" 20101 [(set (match_dup 3) (match_dup 1)) 20102 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2))) 20103 (clobber (reg:CC FLAGS_REG))])] 20104"") 20105 20106(define_peephole2 20107 [(match_scratch:SI 3 "r") 20108 (parallel [(set (match_operand:SI 0 "register_operand" "") 20109 (mult:SI (match_operand:SI 1 "memory_operand" "") 20110 (match_operand:SI 2 "immediate_operand" ""))) 20111 (clobber (reg:CC FLAGS_REG))])] 20112 "TARGET_K8 && !optimize_size 20113 && (GET_CODE (operands[2]) != CONST_INT 20114 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))" 20115 [(set (match_dup 3) (match_dup 1)) 20116 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2))) 20117 (clobber (reg:CC FLAGS_REG))])] 20118"") 20119 20120(define_peephole2 20121 [(match_scratch:SI 3 "r") 20122 (parallel [(set (match_operand:DI 0 "register_operand" "") 20123 (zero_extend:DI 20124 (mult:SI (match_operand:SI 1 "memory_operand" "") 20125 (match_operand:SI 2 "immediate_operand" "")))) 20126 (clobber (reg:CC FLAGS_REG))])] 20127 "TARGET_K8 && !optimize_size 20128 && (GET_CODE (operands[2]) != CONST_INT 20129 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))" 20130 [(set (match_dup 3) (match_dup 1)) 20131 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2)))) 20132 (clobber (reg:CC FLAGS_REG))])] 20133"") 20134 20135;; imul $8/16bit_imm, regmem, reg is vector decoded. 20136;; Convert it into imul reg, reg 20137;; It would be better to force assembler to encode instruction using long 20138;; immediate, but there is apparently no way to do so. 20139(define_peephole2 20140 [(parallel [(set (match_operand:DI 0 "register_operand" "") 20141 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "") 20142 (match_operand:DI 2 "const_int_operand" ""))) 20143 (clobber (reg:CC FLAGS_REG))]) 20144 (match_scratch:DI 3 "r")] 20145 "TARGET_K8 && !optimize_size 20146 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')" 20147 [(set (match_dup 3) (match_dup 2)) 20148 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3))) 20149 (clobber (reg:CC FLAGS_REG))])] 20150{ 20151 if (!rtx_equal_p (operands[0], operands[1])) 20152 emit_move_insn (operands[0], operands[1]); 20153}) 20154 20155(define_peephole2 20156 [(parallel [(set (match_operand:SI 0 "register_operand" "") 20157 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "") 20158 (match_operand:SI 2 "const_int_operand" ""))) 20159 (clobber (reg:CC FLAGS_REG))]) 20160 (match_scratch:SI 3 "r")] 20161 "TARGET_K8 && !optimize_size 20162 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')" 20163 [(set (match_dup 3) (match_dup 2)) 20164 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3))) 20165 (clobber (reg:CC FLAGS_REG))])] 20166{ 20167 if (!rtx_equal_p (operands[0], operands[1])) 20168 emit_move_insn (operands[0], operands[1]); 20169}) 20170 20171(define_peephole2 20172 [(parallel [(set (match_operand:HI 0 "register_operand" "") 20173 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "") 20174 (match_operand:HI 2 "immediate_operand" ""))) 20175 (clobber (reg:CC FLAGS_REG))]) 20176 (match_scratch:HI 3 "r")] 20177 "TARGET_K8 && !optimize_size" 20178 [(set (match_dup 3) (match_dup 2)) 20179 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3))) 20180 (clobber (reg:CC FLAGS_REG))])] 20181{ 20182 if (!rtx_equal_p (operands[0], operands[1])) 20183 emit_move_insn (operands[0], operands[1]); 20184}) 20185 20186;; After splitting up read-modify operations, array accesses with memory 20187;; operands might end up in form: 20188;; sall $2, %eax 20189;; movl 4(%esp), %edx 20190;; addl %edx, %eax 20191;; instead of pre-splitting: 20192;; sall $2, %eax 20193;; addl 4(%esp), %eax 20194;; Turn it into: 20195;; movl 4(%esp), %edx 20196;; leal (%edx,%eax,4), %eax 20197 20198(define_peephole2 20199 [(parallel [(set (match_operand 0 "register_operand" "") 20200 (ashift (match_operand 1 "register_operand" "") 20201 (match_operand 2 "const_int_operand" ""))) 20202 (clobber (reg:CC FLAGS_REG))]) 20203 (set (match_operand 3 "register_operand") 20204 (match_operand 4 "x86_64_general_operand" "")) 20205 (parallel [(set (match_operand 5 "register_operand" "") 20206 (plus (match_operand 6 "register_operand" "") 20207 (match_operand 7 "register_operand" ""))) 20208 (clobber (reg:CC FLAGS_REG))])] 20209 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3 20210 /* Validate MODE for lea. */ 20211 && ((!TARGET_PARTIAL_REG_STALL 20212 && (GET_MODE (operands[0]) == QImode 20213 || GET_MODE (operands[0]) == HImode)) 20214 || GET_MODE (operands[0]) == SImode 20215 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) 20216 /* We reorder load and the shift. */ 20217 && !rtx_equal_p (operands[1], operands[3]) 20218 && !reg_overlap_mentioned_p (operands[0], operands[4]) 20219 /* Last PLUS must consist of operand 0 and 3. */ 20220 && !rtx_equal_p (operands[0], operands[3]) 20221 && (rtx_equal_p (operands[3], operands[6]) 20222 || rtx_equal_p (operands[3], operands[7])) 20223 && (rtx_equal_p (operands[0], operands[6]) 20224 || rtx_equal_p (operands[0], operands[7])) 20225 /* The intermediate operand 0 must die or be same as output. */ 20226 && (rtx_equal_p (operands[0], operands[5]) 20227 || peep2_reg_dead_p (3, operands[0]))" 20228 [(set (match_dup 3) (match_dup 4)) 20229 (set (match_dup 0) (match_dup 1))] 20230{ 20231 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode; 20232 int scale = 1 << INTVAL (operands[2]); 20233 rtx index = gen_lowpart (Pmode, operands[1]); 20234 rtx base = gen_lowpart (Pmode, operands[3]); 20235 rtx dest = gen_lowpart (mode, operands[5]); 20236 20237 operands[1] = gen_rtx_PLUS (Pmode, base, 20238 gen_rtx_MULT (Pmode, index, GEN_INT (scale))); 20239 if (mode != Pmode) 20240 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); 20241 operands[0] = dest; 20242}) 20243 20244;; Call-value patterns last so that the wildcard operand does not 20245;; disrupt insn-recog's switch tables. 20246 20247(define_insn "*call_value_pop_0" 20248 [(set (match_operand 0 "" "") 20249 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) 20250 (match_operand:SI 2 "" ""))) 20251 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 20252 (match_operand:SI 3 "immediate_operand" "")))] 20253 "!TARGET_64BIT" 20254{ 20255 if (SIBLING_CALL_P (insn)) 20256 return "jmp\t%P1"; 20257 else 20258 return "call\t%P1"; 20259} 20260 [(set_attr "type" "callv")]) 20261 20262(define_insn "*call_value_pop_1" 20263 [(set (match_operand 0 "" "") 20264 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm")) 20265 (match_operand:SI 2 "" ""))) 20266 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 20267 (match_operand:SI 3 "immediate_operand" "i")))] 20268 "!TARGET_64BIT" 20269{ 20270 if (constant_call_address_operand (operands[1], Pmode)) 20271 { 20272 if (SIBLING_CALL_P (insn)) 20273 return "jmp\t%P1"; 20274 else 20275 return "call\t%P1"; 20276 } 20277 if (SIBLING_CALL_P (insn)) 20278 return "jmp\t%A1"; 20279 else 20280 return "call\t%A1"; 20281} 20282 [(set_attr "type" "callv")]) 20283 20284(define_insn "*call_value_0" 20285 [(set (match_operand 0 "" "") 20286 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) 20287 (match_operand:SI 2 "" "")))] 20288 "!TARGET_64BIT" 20289{ 20290 if (SIBLING_CALL_P (insn)) 20291 return "jmp\t%P1"; 20292 else 20293 return "call\t%P1"; 20294} 20295 [(set_attr "type" "callv")]) 20296 20297(define_insn "*call_value_0_rex64" 20298 [(set (match_operand 0 "" "") 20299 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) 20300 (match_operand:DI 2 "const_int_operand" "")))] 20301 "TARGET_64BIT" 20302{ 20303 if (SIBLING_CALL_P (insn)) 20304 return "jmp\t%P1"; 20305 else 20306 return "call\t%P1"; 20307} 20308 [(set_attr "type" "callv")]) 20309 20310(define_insn "*call_value_1" 20311 [(set (match_operand 0 "" "") 20312 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm")) 20313 (match_operand:SI 2 "" "")))] 20314 "!SIBLING_CALL_P (insn) && !TARGET_64BIT" 20315{ 20316 if (constant_call_address_operand (operands[1], Pmode)) 20317 return "call\t%P1"; 20318 return "call\t%A1"; 20319} 20320 [(set_attr "type" "callv")]) 20321 20322(define_insn "*sibcall_value_1" 20323 [(set (match_operand 0 "" "") 20324 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a")) 20325 (match_operand:SI 2 "" "")))] 20326 "SIBLING_CALL_P (insn) && !TARGET_64BIT" 20327{ 20328 if (constant_call_address_operand (operands[1], Pmode)) 20329 return "jmp\t%P1"; 20330 return "jmp\t%A1"; 20331} 20332 [(set_attr "type" "callv")]) 20333 20334(define_insn "*call_value_1_rex64" 20335 [(set (match_operand 0 "" "") 20336 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm")) 20337 (match_operand:DI 2 "" "")))] 20338 "!SIBLING_CALL_P (insn) && TARGET_64BIT" 20339{ 20340 if (constant_call_address_operand (operands[1], Pmode)) 20341 return "call\t%P1"; 20342 return "call\t%A1"; 20343} 20344 [(set_attr "type" "callv")]) 20345 20346(define_insn "*sibcall_value_1_rex64" 20347 [(set (match_operand 0 "" "") 20348 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) 20349 (match_operand:DI 2 "" "")))] 20350 "SIBLING_CALL_P (insn) && TARGET_64BIT" 20351 "jmp\t%P1" 20352 [(set_attr "type" "callv")]) 20353 20354(define_insn "*sibcall_value_1_rex64_v" 20355 [(set (match_operand 0 "" "") 20356 (call (mem:QI (reg:DI 40)) 20357 (match_operand:DI 1 "" "")))] 20358 "SIBLING_CALL_P (insn) && TARGET_64BIT" 20359 "jmp\t*%%r11" 20360 [(set_attr "type" "callv")]) 20361 20362;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5. 20363;; That, however, is usually mapped by the OS to SIGSEGV, which is often 20364;; caught for use by garbage collectors and the like. Using an insn that 20365;; maps to SIGILL makes it more likely the program will rightfully die. 20366;; Keeping with tradition, "6" is in honor of #UD. 20367(define_insn "trap" 20368 [(trap_if (const_int 1) (const_int 6))] 20369 "" 20370 { return ASM_SHORT "0x0b0f"; } 20371 [(set_attr "length" "2")]) 20372 20373(define_expand "sse_prologue_save" 20374 [(parallel [(set (match_operand:BLK 0 "" "") 20375 (unspec:BLK [(reg:DI 21) 20376 (reg:DI 22) 20377 (reg:DI 23) 20378 (reg:DI 24) 20379 (reg:DI 25) 20380 (reg:DI 26) 20381 (reg:DI 27) 20382 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE)) 20383 (use (match_operand:DI 1 "register_operand" "")) 20384 (use (match_operand:DI 2 "immediate_operand" "")) 20385 (use (label_ref:DI (match_operand 3 "" "")))])] 20386 "TARGET_64BIT" 20387 "") 20388 20389(define_insn "*sse_prologue_save_insn" 20390 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R") 20391 (match_operand:DI 4 "const_int_operand" "n"))) 20392 (unspec:BLK [(reg:DI 21) 20393 (reg:DI 22) 20394 (reg:DI 23) 20395 (reg:DI 24) 20396 (reg:DI 25) 20397 (reg:DI 26) 20398 (reg:DI 27) 20399 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE)) 20400 (use (match_operand:DI 1 "register_operand" "r")) 20401 (use (match_operand:DI 2 "const_int_operand" "i")) 20402 (use (label_ref:DI (match_operand 3 "" "X")))] 20403 "TARGET_64BIT 20404 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128 20405 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128" 20406 "* 20407{ 20408 int i; 20409 operands[0] = gen_rtx_MEM (Pmode, 20410 gen_rtx_PLUS (Pmode, operands[0], operands[4])); 20411 output_asm_insn (\"jmp\\t%A1\", operands); 20412 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--) 20413 { 20414 operands[4] = adjust_address (operands[0], DImode, i*16); 20415 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i)); 20416 PUT_MODE (operands[4], TImode); 20417 if (GET_CODE (XEXP (operands[0], 0)) != PLUS) 20418 output_asm_insn (\"rex\", operands); 20419 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands); 20420 } 20421 (*targetm.asm_out.internal_label) (asm_out_file, \"L\", 20422 CODE_LABEL_NUMBER (operands[3])); 20423 RET; 20424} 20425 " 20426 [(set_attr "type" "other") 20427 (set_attr "length_immediate" "0") 20428 (set_attr "length_address" "0") 20429 (set_attr "length" "135") 20430 (set_attr "memory" "store") 20431 (set_attr "modrm" "0") 20432 (set_attr "mode" "DI")]) 20433 20434(define_expand "prefetch" 20435 [(prefetch (match_operand 0 "address_operand" "") 20436 (match_operand:SI 1 "const_int_operand" "") 20437 (match_operand:SI 2 "const_int_operand" ""))] 20438 "TARGET_PREFETCH_SSE || TARGET_3DNOW" 20439{ 20440 int rw = INTVAL (operands[1]); 20441 int locality = INTVAL (operands[2]); 20442 20443 gcc_assert (rw == 0 || rw == 1); 20444 gcc_assert (locality >= 0 && locality <= 3); 20445 gcc_assert (GET_MODE (operands[0]) == Pmode 20446 || GET_MODE (operands[0]) == VOIDmode); 20447 20448 /* Use 3dNOW prefetch in case we are asking for write prefetch not 20449 supported by SSE counterpart or the SSE prefetch is not available 20450 (K6 machines). Otherwise use SSE prefetch as it allows specifying 20451 of locality. */ 20452 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw)) 20453 operands[2] = GEN_INT (3); 20454 else 20455 operands[1] = const0_rtx; 20456}) 20457 20458(define_insn "*prefetch_sse" 20459 [(prefetch (match_operand:SI 0 "address_operand" "p") 20460 (const_int 0) 20461 (match_operand:SI 1 "const_int_operand" ""))] 20462 "TARGET_PREFETCH_SSE && !TARGET_64BIT" 20463{ 20464 static const char * const patterns[4] = { 20465 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" 20466 }; 20467 20468 int locality = INTVAL (operands[1]); 20469 gcc_assert (locality >= 0 && locality <= 3); 20470 20471 return patterns[locality]; 20472} 20473 [(set_attr "type" "sse") 20474 (set_attr "memory" "none")]) 20475 20476(define_insn "*prefetch_sse_rex" 20477 [(prefetch (match_operand:DI 0 "address_operand" "p") 20478 (const_int 0) 20479 (match_operand:SI 1 "const_int_operand" ""))] 20480 "TARGET_PREFETCH_SSE && TARGET_64BIT" 20481{ 20482 static const char * const patterns[4] = { 20483 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" 20484 }; 20485 20486 int locality = INTVAL (operands[1]); 20487 gcc_assert (locality >= 0 && locality <= 3); 20488 20489 return patterns[locality]; 20490} 20491 [(set_attr "type" "sse") 20492 (set_attr "memory" "none")]) 20493 20494(define_insn "*prefetch_3dnow" 20495 [(prefetch (match_operand:SI 0 "address_operand" "p") 20496 (match_operand:SI 1 "const_int_operand" "n") 20497 (const_int 3))] 20498 "TARGET_3DNOW && !TARGET_64BIT" 20499{ 20500 if (INTVAL (operands[1]) == 0) 20501 return "prefetch\t%a0"; 20502 else 20503 return "prefetchw\t%a0"; 20504} 20505 [(set_attr "type" "mmx") 20506 (set_attr "memory" "none")]) 20507 20508(define_insn "*prefetch_3dnow_rex" 20509 [(prefetch (match_operand:DI 0 "address_operand" "p") 20510 (match_operand:SI 1 "const_int_operand" "n") 20511 (const_int 3))] 20512 "TARGET_3DNOW && TARGET_64BIT" 20513{ 20514 if (INTVAL (operands[1]) == 0) 20515 return "prefetch\t%a0"; 20516 else 20517 return "prefetchw\t%a0"; 20518} 20519 [(set_attr "type" "mmx") 20520 (set_attr "memory" "none")]) 20521 20522(define_expand "stack_protect_set" 20523 [(match_operand 0 "memory_operand" "") 20524 (match_operand 1 "memory_operand" "")] 20525 "" 20526{ 20527#ifdef TARGET_THREAD_SSP_OFFSET 20528 if (TARGET_64BIT) 20529 emit_insn (gen_stack_tls_protect_set_di (operands[0], 20530 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 20531 else 20532 emit_insn (gen_stack_tls_protect_set_si (operands[0], 20533 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 20534#else 20535 if (TARGET_64BIT) 20536 emit_insn (gen_stack_protect_set_di (operands[0], operands[1])); 20537 else 20538 emit_insn (gen_stack_protect_set_si (operands[0], operands[1])); 20539#endif 20540 DONE; 20541}) 20542 20543(define_insn "stack_protect_set_si" 20544 [(set (match_operand:SI 0 "memory_operand" "=m") 20545 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 20546 (set (match_scratch:SI 2 "=&r") (const_int 0)) 20547 (clobber (reg:CC FLAGS_REG))] 20548 "" 20549 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2" 20550 [(set_attr "type" "multi")]) 20551 20552(define_insn "stack_protect_set_di" 20553 [(set (match_operand:DI 0 "memory_operand" "=m") 20554 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 20555 (set (match_scratch:DI 2 "=&r") (const_int 0)) 20556 (clobber (reg:CC FLAGS_REG))] 20557 "TARGET_64BIT" 20558 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" 20559 [(set_attr "type" "multi")]) 20560 20561(define_insn "stack_tls_protect_set_si" 20562 [(set (match_operand:SI 0 "memory_operand" "=m") 20563 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET)) 20564 (set (match_scratch:SI 2 "=&r") (const_int 0)) 20565 (clobber (reg:CC FLAGS_REG))] 20566 "" 20567 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2" 20568 [(set_attr "type" "multi")]) 20569 20570(define_insn "stack_tls_protect_set_di" 20571 [(set (match_operand:DI 0 "memory_operand" "=m") 20572 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET)) 20573 (set (match_scratch:DI 2 "=&r") (const_int 0)) 20574 (clobber (reg:CC FLAGS_REG))] 20575 "TARGET_64BIT" 20576 "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" 20577 [(set_attr "type" "multi")]) 20578 20579(define_expand "stack_protect_test" 20580 [(match_operand 0 "memory_operand" "") 20581 (match_operand 1 "memory_operand" "") 20582 (match_operand 2 "" "")] 20583 "" 20584{ 20585 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG); 20586 ix86_compare_op0 = operands[0]; 20587 ix86_compare_op1 = operands[1]; 20588 ix86_compare_emitted = flags; 20589 20590#ifdef TARGET_THREAD_SSP_OFFSET 20591 if (TARGET_64BIT) 20592 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0], 20593 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 20594 else 20595 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0], 20596 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 20597#else 20598 if (TARGET_64BIT) 20599 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1])); 20600 else 20601 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1])); 20602#endif 20603 emit_jump_insn (gen_beq (operands[2])); 20604 DONE; 20605}) 20606 20607(define_insn "stack_protect_test_si" 20608 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 20609 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m") 20610 (match_operand:SI 2 "memory_operand" "m")] 20611 UNSPEC_SP_TEST)) 20612 (clobber (match_scratch:SI 3 "=&r"))] 20613 "" 20614 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}" 20615 [(set_attr "type" "multi")]) 20616 20617(define_insn "stack_protect_test_di" 20618 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 20619 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m") 20620 (match_operand:DI 2 "memory_operand" "m")] 20621 UNSPEC_SP_TEST)) 20622 (clobber (match_scratch:DI 3 "=&r"))] 20623 "TARGET_64BIT" 20624 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}" 20625 [(set_attr "type" "multi")]) 20626 20627(define_insn "stack_tls_protect_test_si" 20628 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 20629 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m") 20630 (match_operand:SI 2 "const_int_operand" "i")] 20631 UNSPEC_SP_TLS_TEST)) 20632 (clobber (match_scratch:SI 3 "=r"))] 20633 "" 20634 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}" 20635 [(set_attr "type" "multi")]) 20636 20637(define_insn "stack_tls_protect_test_di" 20638 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 20639 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m") 20640 (match_operand:DI 2 "const_int_operand" "i")] 20641 UNSPEC_SP_TLS_TEST)) 20642 (clobber (match_scratch:DI 3 "=r"))] 20643 "TARGET_64BIT" 20644 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}" 20645 [(set_attr "type" "multi")]) 20646 20647(include "sse.md") 20648(include "mmx.md") 20649(include "sync.md") 20650