i386.md revision 236962
1;; GCC machine description for IA-32 and x86-64. 2;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 3;; 2001, 2002, 2003, 2004, 2005, 2006 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 (UNSPEC_TLSDESC 19) 77 78 ; Other random patterns 79 (UNSPEC_SCAS 20) 80 (UNSPEC_FNSTSW 21) 81 (UNSPEC_SAHF 22) 82 (UNSPEC_FSTCW 23) 83 (UNSPEC_ADD_CARRY 24) 84 (UNSPEC_FLDCW 25) 85 (UNSPEC_REP 26) 86 (UNSPEC_EH_RETURN 27) 87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase 88 89 ; For SSE/MMX support: 90 (UNSPEC_FIX_NOTRUNC 30) 91 (UNSPEC_MASKMOV 31) 92 (UNSPEC_MOVMSK 32) 93 (UNSPEC_MOVNT 33) 94 (UNSPEC_MOVU 34) 95 (UNSPEC_RCP 35) 96 (UNSPEC_RSQRT 36) 97 (UNSPEC_SFENCE 37) 98 (UNSPEC_NOP 38) ; prevents combiner cleverness 99 (UNSPEC_PFRCP 39) 100 (UNSPEC_PFRCPIT1 40) 101 (UNSPEC_PFRCPIT2 41) 102 (UNSPEC_PFRSQRT 42) 103 (UNSPEC_PFRSQIT1 43) 104 (UNSPEC_MFENCE 44) 105 (UNSPEC_LFENCE 45) 106 (UNSPEC_PSADBW 46) 107 (UNSPEC_LDDQU 47) 108 109 ; Generic math support 110 (UNSPEC_COPYSIGN 50) 111 (UNSPEC_IEEE_MIN 51) ; not commutative 112 (UNSPEC_IEEE_MAX 52) ; not commutative 113 114 ; x87 Floating point 115 (UNSPEC_SIN 60) 116 (UNSPEC_COS 61) 117 (UNSPEC_FPATAN 62) 118 (UNSPEC_FYL2X 63) 119 (UNSPEC_FYL2XP1 64) 120 (UNSPEC_FRNDINT 65) 121 (UNSPEC_FIST 66) 122 (UNSPEC_F2XM1 67) 123 124 ; x87 Rounding 125 (UNSPEC_FRNDINT_FLOOR 70) 126 (UNSPEC_FRNDINT_CEIL 71) 127 (UNSPEC_FRNDINT_TRUNC 72) 128 (UNSPEC_FRNDINT_MASK_PM 73) 129 (UNSPEC_FIST_FLOOR 74) 130 (UNSPEC_FIST_CEIL 75) 131 132 ; x87 Double output FP 133 (UNSPEC_SINCOS_COS 80) 134 (UNSPEC_SINCOS_SIN 81) 135 (UNSPEC_TAN_ONE 82) 136 (UNSPEC_TAN_TAN 83) 137 (UNSPEC_XTRACT_FRACT 84) 138 (UNSPEC_XTRACT_EXP 85) 139 (UNSPEC_FSCALE_FRACT 86) 140 (UNSPEC_FSCALE_EXP 87) 141 (UNSPEC_FPREM_F 88) 142 (UNSPEC_FPREM_U 89) 143 (UNSPEC_FPREM1_F 90) 144 (UNSPEC_FPREM1_U 91) 145 146 ; SSP patterns 147 (UNSPEC_SP_SET 100) 148 (UNSPEC_SP_TEST 101) 149 (UNSPEC_SP_TLS_SET 102) 150 (UNSPEC_SP_TLS_TEST 103) 151 152 ; SSSE3 153 (UNSPEC_PSHUFB 120) 154 (UNSPEC_PSIGN 121) 155 (UNSPEC_PALIGNR 122) 156 157 ; For SSE4A support 158 (UNSPEC_EXTRQI 130) 159 (UNSPEC_EXTRQ 131) 160 (UNSPEC_INSERTQI 132) 161 (UNSPEC_INSERTQ 133) 162 ]) 163 164(define_constants 165 [(UNSPECV_BLOCKAGE 0) 166 (UNSPECV_STACK_PROBE 1) 167 (UNSPECV_EMMS 2) 168 (UNSPECV_LDMXCSR 3) 169 (UNSPECV_STMXCSR 4) 170 (UNSPECV_FEMMS 5) 171 (UNSPECV_CLFLUSH 6) 172 (UNSPECV_ALIGN 7) 173 (UNSPECV_MONITOR 8) 174 (UNSPECV_MWAIT 9) 175 (UNSPECV_CMPXCHG_1 10) 176 (UNSPECV_CMPXCHG_2 11) 177 (UNSPECV_XCHG 12) 178 (UNSPECV_LOCK 13) 179 ]) 180 181;; Registers by name. 182(define_constants 183 [(BP_REG 6) 184 (SP_REG 7) 185 (FLAGS_REG 17) 186 (FPSR_REG 18) 187 (FPCR_REG 19) 188 (DIRFLAG_REG 20) 189 (R11_REG 41) 190 ]) 191 192;; Insns whose names begin with "x86_" are emitted by gen_FOO calls 193;; from i386.c. 194 195;; In C guard expressions, put expressions which may be compile-time 196;; constants first. This allows for better optimization. For 197;; example, write "TARGET_64BIT && reload_completed", not 198;; "reload_completed && TARGET_64BIT". 199 200 201;; Processor type. This attribute must exactly match the processor_type 202;; enumeration in i386.h. 203(define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8, 204 nocona,core2,generic32,generic64,amdfam10" 205 (const (symbol_ref "ix86_tune"))) 206 207;; A basic instruction type. Refinements due to arguments to be 208;; provided in other attributes. 209(define_attr "type" 210 "other,multi, 211 alu,alu1,negnot,imov,imovx,lea, 212 incdec,ishift,ishift1,rotate,rotate1,imul,idiv, 213 icmp,test,ibr,setcc,icmov, 214 push,pop,call,callv,leave, 215 str,,bitmanip,cld, 216 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint, 217 sselog,sselog1,sseiadd,sseishft,sseimul, 218 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins, 219 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft" 220 (const_string "other")) 221 222;; Main data type used by the insn 223(define_attr "mode" 224 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF" 225 (const_string "unknown")) 226 227;; The CPU unit operations uses. 228(define_attr "unit" "integer,i387,sse,mmx,unknown" 229 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint") 230 (const_string "i387") 231 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul, 232 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins") 233 (const_string "sse") 234 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft") 235 (const_string "mmx") 236 (eq_attr "type" "other") 237 (const_string "unknown")] 238 (const_string "integer"))) 239 240;; The (bounding maximum) length of an instruction immediate. 241(define_attr "length_immediate" "" 242 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave, 243 bitmanip") 244 (const_int 0) 245 (eq_attr "unit" "i387,sse,mmx") 246 (const_int 0) 247 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1, 248 imul,icmp,push,pop") 249 (symbol_ref "ix86_attr_length_immediate_default(insn,1)") 250 (eq_attr "type" "imov,test") 251 (symbol_ref "ix86_attr_length_immediate_default(insn,0)") 252 (eq_attr "type" "call") 253 (if_then_else (match_operand 0 "constant_call_address_operand" "") 254 (const_int 4) 255 (const_int 0)) 256 (eq_attr "type" "callv") 257 (if_then_else (match_operand 1 "constant_call_address_operand" "") 258 (const_int 4) 259 (const_int 0)) 260 ;; We don't know the size before shorten_branches. Expect 261 ;; the instruction to fit for better scheduling. 262 (eq_attr "type" "ibr") 263 (const_int 1) 264 ] 265 (symbol_ref "/* Update immediate_length and other attributes! */ 266 gcc_unreachable (),1"))) 267 268;; The (bounding maximum) length of an instruction address. 269(define_attr "length_address" "" 270 (cond [(eq_attr "type" "str,cld,other,multi,fxch") 271 (const_int 0) 272 (and (eq_attr "type" "call") 273 (match_operand 0 "constant_call_address_operand" "")) 274 (const_int 0) 275 (and (eq_attr "type" "callv") 276 (match_operand 1 "constant_call_address_operand" "")) 277 (const_int 0) 278 ] 279 (symbol_ref "ix86_attr_length_address_default (insn)"))) 280 281;; Set when length prefix is used. 282(define_attr "prefix_data16" "" 283 (if_then_else (ior (eq_attr "mode" "HI") 284 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF"))) 285 (const_int 1) 286 (const_int 0))) 287 288;; Set when string REP prefix is used. 289(define_attr "prefix_rep" "" 290 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF")) 291 (const_int 1) 292 (const_int 0))) 293 294;; Set when 0f opcode prefix is used. 295(define_attr "prefix_0f" "" 296 (if_then_else 297 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip") 298 (eq_attr "unit" "sse,mmx")) 299 (const_int 1) 300 (const_int 0))) 301 302;; Set when REX opcode prefix is used. 303(define_attr "prefix_rex" "" 304 (cond [(and (eq_attr "mode" "DI") 305 (eq_attr "type" "!push,pop,call,callv,leave,ibr")) 306 (const_int 1) 307 (and (eq_attr "mode" "QI") 308 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)") 309 (const_int 0))) 310 (const_int 1) 311 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)") 312 (const_int 0)) 313 (const_int 1) 314 ] 315 (const_int 0))) 316 317;; Set when modrm byte is used. 318(define_attr "modrm" "" 319 (cond [(eq_attr "type" "str,cld,leave") 320 (const_int 0) 321 (eq_attr "unit" "i387") 322 (const_int 0) 323 (and (eq_attr "type" "incdec") 324 (ior (match_operand:SI 1 "register_operand" "") 325 (match_operand:HI 1 "register_operand" ""))) 326 (const_int 0) 327 (and (eq_attr "type" "push") 328 (not (match_operand 1 "memory_operand" ""))) 329 (const_int 0) 330 (and (eq_attr "type" "pop") 331 (not (match_operand 0 "memory_operand" ""))) 332 (const_int 0) 333 (and (eq_attr "type" "imov") 334 (ior (and (match_operand 0 "register_operand" "") 335 (match_operand 1 "immediate_operand" "")) 336 (ior (and (match_operand 0 "ax_reg_operand" "") 337 (match_operand 1 "memory_displacement_only_operand" "")) 338 (and (match_operand 0 "memory_displacement_only_operand" "") 339 (match_operand 1 "ax_reg_operand" ""))))) 340 (const_int 0) 341 (and (eq_attr "type" "call") 342 (match_operand 0 "constant_call_address_operand" "")) 343 (const_int 0) 344 (and (eq_attr "type" "callv") 345 (match_operand 1 "constant_call_address_operand" "")) 346 (const_int 0) 347 ] 348 (const_int 1))) 349 350;; The (bounding maximum) length of an instruction in bytes. 351;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences. 352;; Later we may want to split them and compute proper length as for 353;; other insns. 354(define_attr "length" "" 355 (cond [(eq_attr "type" "other,multi,fistp,frndint") 356 (const_int 16) 357 (eq_attr "type" "fcmp") 358 (const_int 4) 359 (eq_attr "unit" "i387") 360 (plus (const_int 2) 361 (plus (attr "prefix_data16") 362 (attr "length_address")))] 363 (plus (plus (attr "modrm") 364 (plus (attr "prefix_0f") 365 (plus (attr "prefix_rex") 366 (const_int 1)))) 367 (plus (attr "prefix_rep") 368 (plus (attr "prefix_data16") 369 (plus (attr "length_immediate") 370 (attr "length_address"))))))) 371 372;; The `memory' attribute is `none' if no memory is referenced, `load' or 373;; `store' if there is a simple memory reference therein, or `unknown' 374;; if the instruction is complex. 375 376(define_attr "memory" "none,load,store,both,unknown" 377 (cond [(eq_attr "type" "other,multi,str") 378 (const_string "unknown") 379 (eq_attr "type" "lea,fcmov,fpspc,cld") 380 (const_string "none") 381 (eq_attr "type" "fistp,leave") 382 (const_string "both") 383 (eq_attr "type" "frndint") 384 (const_string "load") 385 (eq_attr "type" "push") 386 (if_then_else (match_operand 1 "memory_operand" "") 387 (const_string "both") 388 (const_string "store")) 389 (eq_attr "type" "pop") 390 (if_then_else (match_operand 0 "memory_operand" "") 391 (const_string "both") 392 (const_string "load")) 393 (eq_attr "type" "setcc") 394 (if_then_else (match_operand 0 "memory_operand" "") 395 (const_string "store") 396 (const_string "none")) 397 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp") 398 (if_then_else (ior (match_operand 0 "memory_operand" "") 399 (match_operand 1 "memory_operand" "")) 400 (const_string "load") 401 (const_string "none")) 402 (eq_attr "type" "ibr") 403 (if_then_else (match_operand 0 "memory_operand" "") 404 (const_string "load") 405 (const_string "none")) 406 (eq_attr "type" "call") 407 (if_then_else (match_operand 0 "constant_call_address_operand" "") 408 (const_string "none") 409 (const_string "load")) 410 (eq_attr "type" "callv") 411 (if_then_else (match_operand 1 "constant_call_address_operand" "") 412 (const_string "none") 413 (const_string "load")) 414 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1") 415 (match_operand 1 "memory_operand" "")) 416 (const_string "both") 417 (and (match_operand 0 "memory_operand" "") 418 (match_operand 1 "memory_operand" "")) 419 (const_string "both") 420 (match_operand 0 "memory_operand" "") 421 (const_string "store") 422 (match_operand 1 "memory_operand" "") 423 (const_string "load") 424 (and (eq_attr "type" 425 "!alu1,negnot,ishift1, 426 imov,imovx,icmp,test,bitmanip, 427 fmov,fcmp,fsgn, 428 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1, 429 mmx,mmxmov,mmxcmp,mmxcvt") 430 (match_operand 2 "memory_operand" "")) 431 (const_string "load") 432 (and (eq_attr "type" "icmov") 433 (match_operand 3 "memory_operand" "")) 434 (const_string "load") 435 ] 436 (const_string "none"))) 437 438;; Indicates if an instruction has both an immediate and a displacement. 439 440(define_attr "imm_disp" "false,true,unknown" 441 (cond [(eq_attr "type" "other,multi") 442 (const_string "unknown") 443 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1") 444 (and (match_operand 0 "memory_displacement_operand" "") 445 (match_operand 1 "immediate_operand" ""))) 446 (const_string "true") 447 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv") 448 (and (match_operand 0 "memory_displacement_operand" "") 449 (match_operand 2 "immediate_operand" ""))) 450 (const_string "true") 451 ] 452 (const_string "false"))) 453 454;; Indicates if an FP operation has an integer source. 455 456(define_attr "fp_int_src" "false,true" 457 (const_string "false")) 458 459;; Defines rounding mode of an FP operation. 460 461(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any" 462 (const_string "any")) 463 464;; Describe a user's asm statement. 465(define_asm_attributes 466 [(set_attr "length" "128") 467 (set_attr "type" "multi")]) 468 469;; All x87 floating point modes 470(define_mode_macro X87MODEF [SF DF XF]) 471 472;; All integer modes handled by x87 fisttp operator. 473(define_mode_macro X87MODEI [HI SI DI]) 474 475;; All integer modes handled by integer x87 operators. 476(define_mode_macro X87MODEI12 [HI SI]) 477 478;; All SSE floating point modes 479(define_mode_macro SSEMODEF [SF DF]) 480 481;; All integer modes handled by SSE cvtts?2si* operators. 482(define_mode_macro SSEMODEI24 [SI DI]) 483 484 485;; Scheduling descriptions 486 487(include "pentium.md") 488(include "ppro.md") 489(include "k6.md") 490(include "athlon.md") 491(include "geode.md") 492 493 494;; Operand and operator predicates and constraints 495 496(include "predicates.md") 497(include "constraints.md") 498 499 500;; Compare instructions. 501 502;; All compare insns have expanders that save the operands away without 503;; actually generating RTL. The bCOND or sCOND (emitted immediately 504;; after the cmp) will actually emit the cmpM. 505 506(define_expand "cmpti" 507 [(set (reg:CC FLAGS_REG) 508 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "") 509 (match_operand:TI 1 "x86_64_general_operand" "")))] 510 "TARGET_64BIT" 511{ 512 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 513 operands[0] = force_reg (TImode, operands[0]); 514 ix86_compare_op0 = operands[0]; 515 ix86_compare_op1 = operands[1]; 516 DONE; 517}) 518 519(define_expand "cmpdi" 520 [(set (reg:CC FLAGS_REG) 521 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "") 522 (match_operand:DI 1 "x86_64_general_operand" "")))] 523 "" 524{ 525 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 526 operands[0] = force_reg (DImode, operands[0]); 527 ix86_compare_op0 = operands[0]; 528 ix86_compare_op1 = operands[1]; 529 DONE; 530}) 531 532(define_expand "cmpsi" 533 [(set (reg:CC FLAGS_REG) 534 (compare:CC (match_operand:SI 0 "cmpsi_operand" "") 535 (match_operand:SI 1 "general_operand" "")))] 536 "" 537{ 538 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 539 operands[0] = force_reg (SImode, operands[0]); 540 ix86_compare_op0 = operands[0]; 541 ix86_compare_op1 = operands[1]; 542 DONE; 543}) 544 545(define_expand "cmphi" 546 [(set (reg:CC FLAGS_REG) 547 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "") 548 (match_operand:HI 1 "general_operand" "")))] 549 "" 550{ 551 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 552 operands[0] = force_reg (HImode, operands[0]); 553 ix86_compare_op0 = operands[0]; 554 ix86_compare_op1 = operands[1]; 555 DONE; 556}) 557 558(define_expand "cmpqi" 559 [(set (reg:CC FLAGS_REG) 560 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "") 561 (match_operand:QI 1 "general_operand" "")))] 562 "TARGET_QIMODE_MATH" 563{ 564 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 565 operands[0] = force_reg (QImode, operands[0]); 566 ix86_compare_op0 = operands[0]; 567 ix86_compare_op1 = operands[1]; 568 DONE; 569}) 570 571(define_insn "cmpdi_ccno_1_rex64" 572 [(set (reg FLAGS_REG) 573 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr") 574 (match_operand:DI 1 "const0_operand" "n,n")))] 575 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 576 "@ 577 test{q}\t{%0, %0|%0, %0} 578 cmp{q}\t{%1, %0|%0, %1}" 579 [(set_attr "type" "test,icmp") 580 (set_attr "length_immediate" "0,1") 581 (set_attr "mode" "DI")]) 582 583(define_insn "*cmpdi_minus_1_rex64" 584 [(set (reg FLAGS_REG) 585 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r") 586 (match_operand:DI 1 "x86_64_general_operand" "re,mr")) 587 (const_int 0)))] 588 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)" 589 "cmp{q}\t{%1, %0|%0, %1}" 590 [(set_attr "type" "icmp") 591 (set_attr "mode" "DI")]) 592 593(define_expand "cmpdi_1_rex64" 594 [(set (reg:CC FLAGS_REG) 595 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "") 596 (match_operand:DI 1 "general_operand" "")))] 597 "TARGET_64BIT" 598 "") 599 600(define_insn "cmpdi_1_insn_rex64" 601 [(set (reg FLAGS_REG) 602 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r") 603 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))] 604 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 605 "cmp{q}\t{%1, %0|%0, %1}" 606 [(set_attr "type" "icmp") 607 (set_attr "mode" "DI")]) 608 609 610(define_insn "*cmpsi_ccno_1" 611 [(set (reg FLAGS_REG) 612 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr") 613 (match_operand:SI 1 "const0_operand" "n,n")))] 614 "ix86_match_ccmode (insn, CCNOmode)" 615 "@ 616 test{l}\t{%0, %0|%0, %0} 617 cmp{l}\t{%1, %0|%0, %1}" 618 [(set_attr "type" "test,icmp") 619 (set_attr "length_immediate" "0,1") 620 (set_attr "mode" "SI")]) 621 622(define_insn "*cmpsi_minus_1" 623 [(set (reg FLAGS_REG) 624 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r") 625 (match_operand:SI 1 "general_operand" "ri,mr")) 626 (const_int 0)))] 627 "ix86_match_ccmode (insn, CCGOCmode)" 628 "cmp{l}\t{%1, %0|%0, %1}" 629 [(set_attr "type" "icmp") 630 (set_attr "mode" "SI")]) 631 632(define_expand "cmpsi_1" 633 [(set (reg:CC FLAGS_REG) 634 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r") 635 (match_operand:SI 1 "general_operand" "ri,mr")))] 636 "" 637 "") 638 639(define_insn "*cmpsi_1_insn" 640 [(set (reg FLAGS_REG) 641 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r") 642 (match_operand:SI 1 "general_operand" "ri,mr")))] 643 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 644 && ix86_match_ccmode (insn, CCmode)" 645 "cmp{l}\t{%1, %0|%0, %1}" 646 [(set_attr "type" "icmp") 647 (set_attr "mode" "SI")]) 648 649(define_insn "*cmphi_ccno_1" 650 [(set (reg FLAGS_REG) 651 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr") 652 (match_operand:HI 1 "const0_operand" "n,n")))] 653 "ix86_match_ccmode (insn, CCNOmode)" 654 "@ 655 test{w}\t{%0, %0|%0, %0} 656 cmp{w}\t{%1, %0|%0, %1}" 657 [(set_attr "type" "test,icmp") 658 (set_attr "length_immediate" "0,1") 659 (set_attr "mode" "HI")]) 660 661(define_insn "*cmphi_minus_1" 662 [(set (reg FLAGS_REG) 663 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r") 664 (match_operand:HI 1 "general_operand" "ri,mr")) 665 (const_int 0)))] 666 "ix86_match_ccmode (insn, CCGOCmode)" 667 "cmp{w}\t{%1, %0|%0, %1}" 668 [(set_attr "type" "icmp") 669 (set_attr "mode" "HI")]) 670 671(define_insn "*cmphi_1" 672 [(set (reg FLAGS_REG) 673 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r") 674 (match_operand:HI 1 "general_operand" "ri,mr")))] 675 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 676 && ix86_match_ccmode (insn, CCmode)" 677 "cmp{w}\t{%1, %0|%0, %1}" 678 [(set_attr "type" "icmp") 679 (set_attr "mode" "HI")]) 680 681(define_insn "*cmpqi_ccno_1" 682 [(set (reg FLAGS_REG) 683 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq") 684 (match_operand:QI 1 "const0_operand" "n,n")))] 685 "ix86_match_ccmode (insn, CCNOmode)" 686 "@ 687 test{b}\t{%0, %0|%0, %0} 688 cmp{b}\t{$0, %0|%0, 0}" 689 [(set_attr "type" "test,icmp") 690 (set_attr "length_immediate" "0,1") 691 (set_attr "mode" "QI")]) 692 693(define_insn "*cmpqi_1" 694 [(set (reg FLAGS_REG) 695 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q") 696 (match_operand:QI 1 "general_operand" "qi,mq")))] 697 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 698 && ix86_match_ccmode (insn, CCmode)" 699 "cmp{b}\t{%1, %0|%0, %1}" 700 [(set_attr "type" "icmp") 701 (set_attr "mode" "QI")]) 702 703(define_insn "*cmpqi_minus_1" 704 [(set (reg FLAGS_REG) 705 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q") 706 (match_operand:QI 1 "general_operand" "qi,mq")) 707 (const_int 0)))] 708 "ix86_match_ccmode (insn, CCGOCmode)" 709 "cmp{b}\t{%1, %0|%0, %1}" 710 [(set_attr "type" "icmp") 711 (set_attr "mode" "QI")]) 712 713(define_insn "*cmpqi_ext_1" 714 [(set (reg FLAGS_REG) 715 (compare 716 (match_operand:QI 0 "general_operand" "Qm") 717 (subreg:QI 718 (zero_extract:SI 719 (match_operand 1 "ext_register_operand" "Q") 720 (const_int 8) 721 (const_int 8)) 0)))] 722 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 723 "cmp{b}\t{%h1, %0|%0, %h1}" 724 [(set_attr "type" "icmp") 725 (set_attr "mode" "QI")]) 726 727(define_insn "*cmpqi_ext_1_rex64" 728 [(set (reg FLAGS_REG) 729 (compare 730 (match_operand:QI 0 "register_operand" "Q") 731 (subreg:QI 732 (zero_extract:SI 733 (match_operand 1 "ext_register_operand" "Q") 734 (const_int 8) 735 (const_int 8)) 0)))] 736 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 737 "cmp{b}\t{%h1, %0|%0, %h1}" 738 [(set_attr "type" "icmp") 739 (set_attr "mode" "QI")]) 740 741(define_insn "*cmpqi_ext_2" 742 [(set (reg FLAGS_REG) 743 (compare 744 (subreg:QI 745 (zero_extract:SI 746 (match_operand 0 "ext_register_operand" "Q") 747 (const_int 8) 748 (const_int 8)) 0) 749 (match_operand:QI 1 "const0_operand" "n")))] 750 "ix86_match_ccmode (insn, CCNOmode)" 751 "test{b}\t%h0, %h0" 752 [(set_attr "type" "test") 753 (set_attr "length_immediate" "0") 754 (set_attr "mode" "QI")]) 755 756(define_expand "cmpqi_ext_3" 757 [(set (reg:CC FLAGS_REG) 758 (compare:CC 759 (subreg:QI 760 (zero_extract:SI 761 (match_operand 0 "ext_register_operand" "") 762 (const_int 8) 763 (const_int 8)) 0) 764 (match_operand:QI 1 "general_operand" "")))] 765 "" 766 "") 767 768(define_insn "cmpqi_ext_3_insn" 769 [(set (reg FLAGS_REG) 770 (compare 771 (subreg:QI 772 (zero_extract:SI 773 (match_operand 0 "ext_register_operand" "Q") 774 (const_int 8) 775 (const_int 8)) 0) 776 (match_operand:QI 1 "general_operand" "Qmn")))] 777 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 778 "cmp{b}\t{%1, %h0|%h0, %1}" 779 [(set_attr "type" "icmp") 780 (set_attr "mode" "QI")]) 781 782(define_insn "cmpqi_ext_3_insn_rex64" 783 [(set (reg FLAGS_REG) 784 (compare 785 (subreg:QI 786 (zero_extract:SI 787 (match_operand 0 "ext_register_operand" "Q") 788 (const_int 8) 789 (const_int 8)) 0) 790 (match_operand:QI 1 "nonmemory_operand" "Qn")))] 791 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 792 "cmp{b}\t{%1, %h0|%h0, %1}" 793 [(set_attr "type" "icmp") 794 (set_attr "mode" "QI")]) 795 796(define_insn "*cmpqi_ext_4" 797 [(set (reg FLAGS_REG) 798 (compare 799 (subreg:QI 800 (zero_extract:SI 801 (match_operand 0 "ext_register_operand" "Q") 802 (const_int 8) 803 (const_int 8)) 0) 804 (subreg:QI 805 (zero_extract:SI 806 (match_operand 1 "ext_register_operand" "Q") 807 (const_int 8) 808 (const_int 8)) 0)))] 809 "ix86_match_ccmode (insn, CCmode)" 810 "cmp{b}\t{%h1, %h0|%h0, %h1}" 811 [(set_attr "type" "icmp") 812 (set_attr "mode" "QI")]) 813 814;; These implement float point compares. 815;; %%% See if we can get away with VOIDmode operands on the actual insns, 816;; which would allow mix and match FP modes on the compares. Which is what 817;; the old patterns did, but with many more of them. 818 819(define_expand "cmpxf" 820 [(set (reg:CC FLAGS_REG) 821 (compare:CC (match_operand:XF 0 "nonmemory_operand" "") 822 (match_operand:XF 1 "nonmemory_operand" "")))] 823 "TARGET_80387" 824{ 825 ix86_compare_op0 = operands[0]; 826 ix86_compare_op1 = operands[1]; 827 DONE; 828}) 829 830(define_expand "cmpdf" 831 [(set (reg:CC FLAGS_REG) 832 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "") 833 (match_operand:DF 1 "cmp_fp_expander_operand" "")))] 834 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 835{ 836 ix86_compare_op0 = operands[0]; 837 ix86_compare_op1 = operands[1]; 838 DONE; 839}) 840 841(define_expand "cmpsf" 842 [(set (reg:CC FLAGS_REG) 843 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "") 844 (match_operand:SF 1 "cmp_fp_expander_operand" "")))] 845 "TARGET_80387 || TARGET_SSE_MATH" 846{ 847 ix86_compare_op0 = operands[0]; 848 ix86_compare_op1 = operands[1]; 849 DONE; 850}) 851 852;; FP compares, step 1: 853;; Set the FP condition codes. 854;; 855;; CCFPmode compare with exceptions 856;; CCFPUmode compare with no exceptions 857 858;; We may not use "#" to split and emit these, since the REG_DEAD notes 859;; used to manage the reg stack popping would not be preserved. 860 861(define_insn "*cmpfp_0" 862 [(set (match_operand:HI 0 "register_operand" "=a") 863 (unspec:HI 864 [(compare:CCFP 865 (match_operand 1 "register_operand" "f") 866 (match_operand 2 "const0_operand" "X"))] 867 UNSPEC_FNSTSW))] 868 "TARGET_80387 869 && FLOAT_MODE_P (GET_MODE (operands[1])) 870 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 871 "* return output_fp_compare (insn, operands, 0, 0);" 872 [(set_attr "type" "multi") 873 (set_attr "unit" "i387") 874 (set (attr "mode") 875 (cond [(match_operand:SF 1 "" "") 876 (const_string "SF") 877 (match_operand:DF 1 "" "") 878 (const_string "DF") 879 ] 880 (const_string "XF")))]) 881 882(define_insn "*cmpfp_sf" 883 [(set (match_operand:HI 0 "register_operand" "=a") 884 (unspec:HI 885 [(compare:CCFP 886 (match_operand:SF 1 "register_operand" "f") 887 (match_operand:SF 2 "nonimmediate_operand" "fm"))] 888 UNSPEC_FNSTSW))] 889 "TARGET_80387" 890 "* return output_fp_compare (insn, operands, 0, 0);" 891 [(set_attr "type" "multi") 892 (set_attr "unit" "i387") 893 (set_attr "mode" "SF")]) 894 895(define_insn "*cmpfp_df" 896 [(set (match_operand:HI 0 "register_operand" "=a") 897 (unspec:HI 898 [(compare:CCFP 899 (match_operand:DF 1 "register_operand" "f") 900 (match_operand:DF 2 "nonimmediate_operand" "fm"))] 901 UNSPEC_FNSTSW))] 902 "TARGET_80387" 903 "* return output_fp_compare (insn, operands, 0, 0);" 904 [(set_attr "type" "multi") 905 (set_attr "unit" "i387") 906 (set_attr "mode" "DF")]) 907 908(define_insn "*cmpfp_xf" 909 [(set (match_operand:HI 0 "register_operand" "=a") 910 (unspec:HI 911 [(compare:CCFP 912 (match_operand:XF 1 "register_operand" "f") 913 (match_operand:XF 2 "register_operand" "f"))] 914 UNSPEC_FNSTSW))] 915 "TARGET_80387" 916 "* return output_fp_compare (insn, operands, 0, 0);" 917 [(set_attr "type" "multi") 918 (set_attr "unit" "i387") 919 (set_attr "mode" "XF")]) 920 921(define_insn "*cmpfp_u" 922 [(set (match_operand:HI 0 "register_operand" "=a") 923 (unspec:HI 924 [(compare:CCFPU 925 (match_operand 1 "register_operand" "f") 926 (match_operand 2 "register_operand" "f"))] 927 UNSPEC_FNSTSW))] 928 "TARGET_80387 929 && FLOAT_MODE_P (GET_MODE (operands[1])) 930 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 931 "* return output_fp_compare (insn, operands, 0, 1);" 932 [(set_attr "type" "multi") 933 (set_attr "unit" "i387") 934 (set (attr "mode") 935 (cond [(match_operand:SF 1 "" "") 936 (const_string "SF") 937 (match_operand:DF 1 "" "") 938 (const_string "DF") 939 ] 940 (const_string "XF")))]) 941 942(define_insn "*cmpfp_<mode>" 943 [(set (match_operand:HI 0 "register_operand" "=a") 944 (unspec:HI 945 [(compare:CCFP 946 (match_operand 1 "register_operand" "f") 947 (match_operator 3 "float_operator" 948 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))] 949 UNSPEC_FNSTSW))] 950 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 951 && FLOAT_MODE_P (GET_MODE (operands[1])) 952 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))" 953 "* return output_fp_compare (insn, operands, 0, 0);" 954 [(set_attr "type" "multi") 955 (set_attr "unit" "i387") 956 (set_attr "fp_int_src" "true") 957 (set_attr "mode" "<MODE>")]) 958 959;; FP compares, step 2 960;; Move the fpsw to ax. 961 962(define_insn "x86_fnstsw_1" 963 [(set (match_operand:HI 0 "register_operand" "=a") 964 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))] 965 "TARGET_80387" 966 "fnstsw\t%0" 967 [(set_attr "length" "2") 968 (set_attr "mode" "SI") 969 (set_attr "unit" "i387")]) 970 971;; FP compares, step 3 972;; Get ax into flags, general case. 973 974(define_insn "x86_sahf_1" 975 [(set (reg:CC FLAGS_REG) 976 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))] 977 "!TARGET_64BIT" 978 "sahf" 979 [(set_attr "length" "1") 980 (set_attr "athlon_decode" "vector") 981 (set_attr "amdfam10_decode" "direct") 982 (set_attr "mode" "SI")]) 983 984;; Pentium Pro can do steps 1 through 3 in one go. 985;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 986(define_insn "*cmpfp_i_mixed" 987 [(set (reg:CCFP FLAGS_REG) 988 (compare:CCFP (match_operand 0 "register_operand" "f,x") 989 (match_operand 1 "nonimmediate_operand" "f,xm")))] 990 "TARGET_MIX_SSE_I387 991 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 992 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 993 "* return output_fp_compare (insn, operands, 1, 0);" 994 [(set_attr "type" "fcmp,ssecomi") 995 (set (attr "mode") 996 (if_then_else (match_operand:SF 1 "" "") 997 (const_string "SF") 998 (const_string "DF"))) 999 (set_attr "athlon_decode" "vector") 1000 (set_attr "amdfam10_decode" "direct")]) 1001 1002(define_insn "*cmpfp_i_sse" 1003 [(set (reg:CCFP FLAGS_REG) 1004 (compare:CCFP (match_operand 0 "register_operand" "x") 1005 (match_operand 1 "nonimmediate_operand" "xm")))] 1006 "TARGET_SSE_MATH 1007 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1008 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1009 "* return output_fp_compare (insn, operands, 1, 0);" 1010 [(set_attr "type" "ssecomi") 1011 (set (attr "mode") 1012 (if_then_else (match_operand:SF 1 "" "") 1013 (const_string "SF") 1014 (const_string "DF"))) 1015 (set_attr "athlon_decode" "vector") 1016 (set_attr "amdfam10_decode" "direct")]) 1017 1018(define_insn "*cmpfp_i_i387" 1019 [(set (reg:CCFP FLAGS_REG) 1020 (compare:CCFP (match_operand 0 "register_operand" "f") 1021 (match_operand 1 "register_operand" "f")))] 1022 "TARGET_80387 && TARGET_CMOVE 1023 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))) 1024 && FLOAT_MODE_P (GET_MODE (operands[0])) 1025 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1026 "* return output_fp_compare (insn, operands, 1, 0);" 1027 [(set_attr "type" "fcmp") 1028 (set (attr "mode") 1029 (cond [(match_operand:SF 1 "" "") 1030 (const_string "SF") 1031 (match_operand:DF 1 "" "") 1032 (const_string "DF") 1033 ] 1034 (const_string "XF"))) 1035 (set_attr "athlon_decode" "vector") 1036 (set_attr "amdfam10_decode" "direct")]) 1037 1038(define_insn "*cmpfp_iu_mixed" 1039 [(set (reg:CCFPU FLAGS_REG) 1040 (compare:CCFPU (match_operand 0 "register_operand" "f,x") 1041 (match_operand 1 "nonimmediate_operand" "f,xm")))] 1042 "TARGET_MIX_SSE_I387 1043 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1044 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1045 "* return output_fp_compare (insn, operands, 1, 1);" 1046 [(set_attr "type" "fcmp,ssecomi") 1047 (set (attr "mode") 1048 (if_then_else (match_operand:SF 1 "" "") 1049 (const_string "SF") 1050 (const_string "DF"))) 1051 (set_attr "athlon_decode" "vector") 1052 (set_attr "amdfam10_decode" "direct")]) 1053 1054(define_insn "*cmpfp_iu_sse" 1055 [(set (reg:CCFPU FLAGS_REG) 1056 (compare:CCFPU (match_operand 0 "register_operand" "x") 1057 (match_operand 1 "nonimmediate_operand" "xm")))] 1058 "TARGET_SSE_MATH 1059 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1060 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1061 "* return output_fp_compare (insn, operands, 1, 1);" 1062 [(set_attr "type" "ssecomi") 1063 (set (attr "mode") 1064 (if_then_else (match_operand:SF 1 "" "") 1065 (const_string "SF") 1066 (const_string "DF"))) 1067 (set_attr "athlon_decode" "vector") 1068 (set_attr "amdfam10_decode" "direct")]) 1069 1070(define_insn "*cmpfp_iu_387" 1071 [(set (reg:CCFPU FLAGS_REG) 1072 (compare:CCFPU (match_operand 0 "register_operand" "f") 1073 (match_operand 1 "register_operand" "f")))] 1074 "TARGET_80387 && TARGET_CMOVE 1075 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))) 1076 && FLOAT_MODE_P (GET_MODE (operands[0])) 1077 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1078 "* return output_fp_compare (insn, operands, 1, 1);" 1079 [(set_attr "type" "fcmp") 1080 (set (attr "mode") 1081 (cond [(match_operand:SF 1 "" "") 1082 (const_string "SF") 1083 (match_operand:DF 1 "" "") 1084 (const_string "DF") 1085 ] 1086 (const_string "XF"))) 1087 (set_attr "athlon_decode" "vector") 1088 (set_attr "amdfam10_decode" "direct")]) 1089 1090;; Move instructions. 1091 1092;; General case of fullword move. 1093 1094(define_expand "movsi" 1095 [(set (match_operand:SI 0 "nonimmediate_operand" "") 1096 (match_operand:SI 1 "general_operand" ""))] 1097 "" 1098 "ix86_expand_move (SImode, operands); DONE;") 1099 1100;; Push/pop instructions. They are separate since autoinc/dec is not a 1101;; general_operand. 1102;; 1103;; %%% We don't use a post-inc memory reference because x86 is not a 1104;; general AUTO_INC_DEC host, which impacts how it is treated in flow. 1105;; Changing this impacts compiler performance on other non-AUTO_INC_DEC 1106;; targets without our curiosities, and it is just as easy to represent 1107;; this differently. 1108 1109(define_insn "*pushsi2" 1110 [(set (match_operand:SI 0 "push_operand" "=<") 1111 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))] 1112 "!TARGET_64BIT" 1113 "push{l}\t%1" 1114 [(set_attr "type" "push") 1115 (set_attr "mode" "SI")]) 1116 1117;; For 64BIT abi we always round up to 8 bytes. 1118(define_insn "*pushsi2_rex64" 1119 [(set (match_operand:SI 0 "push_operand" "=X") 1120 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))] 1121 "TARGET_64BIT" 1122 "push{q}\t%q1" 1123 [(set_attr "type" "push") 1124 (set_attr "mode" "SI")]) 1125 1126(define_insn "*pushsi2_prologue" 1127 [(set (match_operand:SI 0 "push_operand" "=<") 1128 (match_operand:SI 1 "general_no_elim_operand" "ri*m")) 1129 (clobber (mem:BLK (scratch)))] 1130 "!TARGET_64BIT" 1131 "push{l}\t%1" 1132 [(set_attr "type" "push") 1133 (set_attr "mode" "SI")]) 1134 1135(define_insn "*popsi1_epilogue" 1136 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m") 1137 (mem:SI (reg:SI SP_REG))) 1138 (set (reg:SI SP_REG) 1139 (plus:SI (reg:SI SP_REG) (const_int 4))) 1140 (clobber (mem:BLK (scratch)))] 1141 "!TARGET_64BIT" 1142 "pop{l}\t%0" 1143 [(set_attr "type" "pop") 1144 (set_attr "mode" "SI")]) 1145 1146(define_insn "popsi1" 1147 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m") 1148 (mem:SI (reg:SI SP_REG))) 1149 (set (reg:SI SP_REG) 1150 (plus:SI (reg:SI SP_REG) (const_int 4)))] 1151 "!TARGET_64BIT" 1152 "pop{l}\t%0" 1153 [(set_attr "type" "pop") 1154 (set_attr "mode" "SI")]) 1155 1156(define_insn "*movsi_xor" 1157 [(set (match_operand:SI 0 "register_operand" "=r") 1158 (match_operand:SI 1 "const0_operand" "i")) 1159 (clobber (reg:CC FLAGS_REG))] 1160 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)" 1161 "xor{l}\t{%0, %0|%0, %0}" 1162 [(set_attr "type" "alu1") 1163 (set_attr "mode" "SI") 1164 (set_attr "length_immediate" "0")]) 1165 1166(define_insn "*movsi_or" 1167 [(set (match_operand:SI 0 "register_operand" "=r") 1168 (match_operand:SI 1 "immediate_operand" "i")) 1169 (clobber (reg:CC FLAGS_REG))] 1170 "reload_completed 1171 && operands[1] == constm1_rtx 1172 && (TARGET_PENTIUM || optimize_size)" 1173{ 1174 operands[1] = constm1_rtx; 1175 return "or{l}\t{%1, %0|%0, %1}"; 1176} 1177 [(set_attr "type" "alu1") 1178 (set_attr "mode" "SI") 1179 (set_attr "length_immediate" "1")]) 1180 1181(define_insn "*movsi_1" 1182 [(set (match_operand:SI 0 "nonimmediate_operand" 1183 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x") 1184 (match_operand:SI 1 "general_operand" 1185 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))] 1186 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 1187{ 1188 switch (get_attr_type (insn)) 1189 { 1190 case TYPE_SSELOG1: 1191 if (get_attr_mode (insn) == MODE_TI) 1192 return "pxor\t%0, %0"; 1193 return "xorps\t%0, %0"; 1194 1195 case TYPE_SSEMOV: 1196 switch (get_attr_mode (insn)) 1197 { 1198 case MODE_TI: 1199 return "movdqa\t{%1, %0|%0, %1}"; 1200 case MODE_V4SF: 1201 return "movaps\t{%1, %0|%0, %1}"; 1202 case MODE_SI: 1203 return "movd\t{%1, %0|%0, %1}"; 1204 case MODE_SF: 1205 return "movss\t{%1, %0|%0, %1}"; 1206 default: 1207 gcc_unreachable (); 1208 } 1209 1210 case TYPE_MMXADD: 1211 return "pxor\t%0, %0"; 1212 1213 case TYPE_MMXMOV: 1214 if (get_attr_mode (insn) == MODE_DI) 1215 return "movq\t{%1, %0|%0, %1}"; 1216 return "movd\t{%1, %0|%0, %1}"; 1217 1218 case TYPE_LEA: 1219 return "lea{l}\t{%1, %0|%0, %1}"; 1220 1221 default: 1222 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 1223 return "mov{l}\t{%1, %0|%0, %1}"; 1224 } 1225} 1226 [(set (attr "type") 1227 (cond [(eq_attr "alternative" "2") 1228 (const_string "mmxadd") 1229 (eq_attr "alternative" "3,4,5") 1230 (const_string "mmxmov") 1231 (eq_attr "alternative" "6") 1232 (const_string "sselog1") 1233 (eq_attr "alternative" "7,8,9,10,11") 1234 (const_string "ssemov") 1235 (match_operand:DI 1 "pic_32bit_operand" "") 1236 (const_string "lea") 1237 ] 1238 (const_string "imov"))) 1239 (set (attr "mode") 1240 (cond [(eq_attr "alternative" "2,3") 1241 (const_string "DI") 1242 (eq_attr "alternative" "6,7") 1243 (if_then_else 1244 (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 1245 (const_string "V4SF") 1246 (const_string "TI")) 1247 (and (eq_attr "alternative" "8,9,10,11") 1248 (eq (symbol_ref "TARGET_SSE2") (const_int 0))) 1249 (const_string "SF") 1250 ] 1251 (const_string "SI")))]) 1252 1253;; Stores and loads of ax to arbitrary constant address. 1254;; We fake an second form of instruction to force reload to load address 1255;; into register when rax is not available 1256(define_insn "*movabssi_1_rex64" 1257 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 1258 (match_operand:SI 1 "nonmemory_operand" "a,er"))] 1259 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 1260 "@ 1261 movabs{l}\t{%1, %P0|%P0, %1} 1262 mov{l}\t{%1, %a0|%a0, %1}" 1263 [(set_attr "type" "imov") 1264 (set_attr "modrm" "0,*") 1265 (set_attr "length_address" "8,0") 1266 (set_attr "length_immediate" "0,*") 1267 (set_attr "memory" "store") 1268 (set_attr "mode" "SI")]) 1269 1270(define_insn "*movabssi_2_rex64" 1271 [(set (match_operand:SI 0 "register_operand" "=a,r") 1272 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 1273 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 1274 "@ 1275 movabs{l}\t{%P1, %0|%0, %P1} 1276 mov{l}\t{%a1, %0|%0, %a1}" 1277 [(set_attr "type" "imov") 1278 (set_attr "modrm" "0,*") 1279 (set_attr "length_address" "8,0") 1280 (set_attr "length_immediate" "0") 1281 (set_attr "memory" "load") 1282 (set_attr "mode" "SI")]) 1283 1284(define_insn "*swapsi" 1285 [(set (match_operand:SI 0 "register_operand" "+r") 1286 (match_operand:SI 1 "register_operand" "+r")) 1287 (set (match_dup 1) 1288 (match_dup 0))] 1289 "" 1290 "xchg{l}\t%1, %0" 1291 [(set_attr "type" "imov") 1292 (set_attr "mode" "SI") 1293 (set_attr "pent_pair" "np") 1294 (set_attr "athlon_decode" "vector") 1295 (set_attr "amdfam10_decode" "double")]) 1296 1297(define_expand "movhi" 1298 [(set (match_operand:HI 0 "nonimmediate_operand" "") 1299 (match_operand:HI 1 "general_operand" ""))] 1300 "" 1301 "ix86_expand_move (HImode, operands); DONE;") 1302 1303(define_insn "*pushhi2" 1304 [(set (match_operand:HI 0 "push_operand" "=X") 1305 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))] 1306 "!TARGET_64BIT" 1307 "push{l}\t%k1" 1308 [(set_attr "type" "push") 1309 (set_attr "mode" "SI")]) 1310 1311;; For 64BIT abi we always round up to 8 bytes. 1312(define_insn "*pushhi2_rex64" 1313 [(set (match_operand:HI 0 "push_operand" "=X") 1314 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))] 1315 "TARGET_64BIT" 1316 "push{q}\t%q1" 1317 [(set_attr "type" "push") 1318 (set_attr "mode" "DI")]) 1319 1320(define_insn "*movhi_1" 1321 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") 1322 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))] 1323 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 1324{ 1325 switch (get_attr_type (insn)) 1326 { 1327 case TYPE_IMOVX: 1328 /* movzwl is faster than movw on p2 due to partial word stalls, 1329 though not as fast as an aligned movl. */ 1330 return "movz{wl|x}\t{%1, %k0|%k0, %1}"; 1331 default: 1332 if (get_attr_mode (insn) == MODE_SI) 1333 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 1334 else 1335 return "mov{w}\t{%1, %0|%0, %1}"; 1336 } 1337} 1338 [(set (attr "type") 1339 (cond [(ne (symbol_ref "optimize_size") (const_int 0)) 1340 (const_string "imov") 1341 (and (eq_attr "alternative" "0") 1342 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1343 (const_int 0)) 1344 (eq (symbol_ref "TARGET_HIMODE_MATH") 1345 (const_int 0)))) 1346 (const_string "imov") 1347 (and (eq_attr "alternative" "1,2") 1348 (match_operand:HI 1 "aligned_operand" "")) 1349 (const_string "imov") 1350 (and (ne (symbol_ref "TARGET_MOVX") 1351 (const_int 0)) 1352 (eq_attr "alternative" "0,2")) 1353 (const_string "imovx") 1354 ] 1355 (const_string "imov"))) 1356 (set (attr "mode") 1357 (cond [(eq_attr "type" "imovx") 1358 (const_string "SI") 1359 (and (eq_attr "alternative" "1,2") 1360 (match_operand:HI 1 "aligned_operand" "")) 1361 (const_string "SI") 1362 (and (eq_attr "alternative" "0") 1363 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1364 (const_int 0)) 1365 (eq (symbol_ref "TARGET_HIMODE_MATH") 1366 (const_int 0)))) 1367 (const_string "SI") 1368 ] 1369 (const_string "HI")))]) 1370 1371;; Stores and loads of ax to arbitrary constant address. 1372;; We fake an second form of instruction to force reload to load address 1373;; into register when rax is not available 1374(define_insn "*movabshi_1_rex64" 1375 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 1376 (match_operand:HI 1 "nonmemory_operand" "a,er"))] 1377 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 1378 "@ 1379 movabs{w}\t{%1, %P0|%P0, %1} 1380 mov{w}\t{%1, %a0|%a0, %1}" 1381 [(set_attr "type" "imov") 1382 (set_attr "modrm" "0,*") 1383 (set_attr "length_address" "8,0") 1384 (set_attr "length_immediate" "0,*") 1385 (set_attr "memory" "store") 1386 (set_attr "mode" "HI")]) 1387 1388(define_insn "*movabshi_2_rex64" 1389 [(set (match_operand:HI 0 "register_operand" "=a,r") 1390 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 1391 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 1392 "@ 1393 movabs{w}\t{%P1, %0|%0, %P1} 1394 mov{w}\t{%a1, %0|%0, %a1}" 1395 [(set_attr "type" "imov") 1396 (set_attr "modrm" "0,*") 1397 (set_attr "length_address" "8,0") 1398 (set_attr "length_immediate" "0") 1399 (set_attr "memory" "load") 1400 (set_attr "mode" "HI")]) 1401 1402(define_insn "*swaphi_1" 1403 [(set (match_operand:HI 0 "register_operand" "+r") 1404 (match_operand:HI 1 "register_operand" "+r")) 1405 (set (match_dup 1) 1406 (match_dup 0))] 1407 "!TARGET_PARTIAL_REG_STALL || optimize_size" 1408 "xchg{l}\t%k1, %k0" 1409 [(set_attr "type" "imov") 1410 (set_attr "mode" "SI") 1411 (set_attr "pent_pair" "np") 1412 (set_attr "athlon_decode" "vector") 1413 (set_attr "amdfam10_decode" "double")]) 1414 1415;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10 1416(define_insn "*swaphi_2" 1417 [(set (match_operand:HI 0 "register_operand" "+r") 1418 (match_operand:HI 1 "register_operand" "+r")) 1419 (set (match_dup 1) 1420 (match_dup 0))] 1421 "TARGET_PARTIAL_REG_STALL" 1422 "xchg{w}\t%1, %0" 1423 [(set_attr "type" "imov") 1424 (set_attr "mode" "HI") 1425 (set_attr "pent_pair" "np") 1426 (set_attr "athlon_decode" "vector")]) 1427 1428(define_expand "movstricthi" 1429 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "")) 1430 (match_operand:HI 1 "general_operand" ""))] 1431 "! TARGET_PARTIAL_REG_STALL || optimize_size" 1432{ 1433 /* Don't generate memory->memory moves, go through a register */ 1434 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 1435 operands[1] = force_reg (HImode, operands[1]); 1436}) 1437 1438(define_insn "*movstricthi_1" 1439 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r")) 1440 (match_operand:HI 1 "general_operand" "rn,m"))] 1441 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 1442 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 1443 "mov{w}\t{%1, %0|%0, %1}" 1444 [(set_attr "type" "imov") 1445 (set_attr "mode" "HI")]) 1446 1447(define_insn "*movstricthi_xor" 1448 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) 1449 (match_operand:HI 1 "const0_operand" "i")) 1450 (clobber (reg:CC FLAGS_REG))] 1451 "reload_completed 1452 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)" 1453 "xor{w}\t{%0, %0|%0, %0}" 1454 [(set_attr "type" "alu1") 1455 (set_attr "mode" "HI") 1456 (set_attr "length_immediate" "0")]) 1457 1458(define_expand "movqi" 1459 [(set (match_operand:QI 0 "nonimmediate_operand" "") 1460 (match_operand:QI 1 "general_operand" ""))] 1461 "" 1462 "ix86_expand_move (QImode, operands); DONE;") 1463 1464;; emit_push_insn when it calls move_by_pieces requires an insn to 1465;; "push a byte". But actually we use pushl, which has the effect 1466;; of rounding the amount pushed up to a word. 1467 1468(define_insn "*pushqi2" 1469 [(set (match_operand:QI 0 "push_operand" "=X") 1470 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))] 1471 "!TARGET_64BIT" 1472 "push{l}\t%k1" 1473 [(set_attr "type" "push") 1474 (set_attr "mode" "SI")]) 1475 1476;; For 64BIT abi we always round up to 8 bytes. 1477(define_insn "*pushqi2_rex64" 1478 [(set (match_operand:QI 0 "push_operand" "=X") 1479 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))] 1480 "TARGET_64BIT" 1481 "push{q}\t%q1" 1482 [(set_attr "type" "push") 1483 (set_attr "mode" "DI")]) 1484 1485;; Situation is quite tricky about when to choose full sized (SImode) move 1486;; over QImode moves. For Q_REG -> Q_REG move we use full size only for 1487;; partial register dependency machines (such as AMD Athlon), where QImode 1488;; moves issue extra dependency and for partial register stalls machines 1489;; that don't use QImode patterns (and QImode move cause stall on the next 1490;; instruction). 1491;; 1492;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial 1493;; register stall machines with, where we use QImode instructions, since 1494;; partial register stall can be caused there. Then we use movzx. 1495(define_insn "*movqi_1" 1496 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m") 1497 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))] 1498 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 1499{ 1500 switch (get_attr_type (insn)) 1501 { 1502 case TYPE_IMOVX: 1503 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM); 1504 return "movz{bl|x}\t{%1, %k0|%k0, %1}"; 1505 default: 1506 if (get_attr_mode (insn) == MODE_SI) 1507 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 1508 else 1509 return "mov{b}\t{%1, %0|%0, %1}"; 1510 } 1511} 1512 [(set (attr "type") 1513 (cond [(and (eq_attr "alternative" "5") 1514 (not (match_operand:QI 1 "aligned_operand" ""))) 1515 (const_string "imovx") 1516 (ne (symbol_ref "optimize_size") (const_int 0)) 1517 (const_string "imov") 1518 (and (eq_attr "alternative" "3") 1519 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1520 (const_int 0)) 1521 (eq (symbol_ref "TARGET_QIMODE_MATH") 1522 (const_int 0)))) 1523 (const_string "imov") 1524 (eq_attr "alternative" "3,5") 1525 (const_string "imovx") 1526 (and (ne (symbol_ref "TARGET_MOVX") 1527 (const_int 0)) 1528 (eq_attr "alternative" "2")) 1529 (const_string "imovx") 1530 ] 1531 (const_string "imov"))) 1532 (set (attr "mode") 1533 (cond [(eq_attr "alternative" "3,4,5") 1534 (const_string "SI") 1535 (eq_attr "alternative" "6") 1536 (const_string "QI") 1537 (eq_attr "type" "imovx") 1538 (const_string "SI") 1539 (and (eq_attr "type" "imov") 1540 (and (eq_attr "alternative" "0,1") 1541 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY") 1542 (const_int 0)) 1543 (and (eq (symbol_ref "optimize_size") 1544 (const_int 0)) 1545 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1546 (const_int 0)))))) 1547 (const_string "SI") 1548 ;; Avoid partial register stalls when not using QImode arithmetic 1549 (and (eq_attr "type" "imov") 1550 (and (eq_attr "alternative" "0,1") 1551 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL") 1552 (const_int 0)) 1553 (eq (symbol_ref "TARGET_QIMODE_MATH") 1554 (const_int 0))))) 1555 (const_string "SI") 1556 ] 1557 (const_string "QI")))]) 1558 1559(define_expand "reload_outqi" 1560 [(parallel [(match_operand:QI 0 "" "=m") 1561 (match_operand:QI 1 "register_operand" "r") 1562 (match_operand:QI 2 "register_operand" "=&q")])] 1563 "" 1564{ 1565 rtx op0, op1, op2; 1566 op0 = operands[0]; op1 = operands[1]; op2 = operands[2]; 1567 1568 gcc_assert (!reg_overlap_mentioned_p (op2, op0)); 1569 if (! q_regs_operand (op1, QImode)) 1570 { 1571 emit_insn (gen_movqi (op2, op1)); 1572 op1 = op2; 1573 } 1574 emit_insn (gen_movqi (op0, op1)); 1575 DONE; 1576}) 1577 1578(define_insn "*swapqi_1" 1579 [(set (match_operand:QI 0 "register_operand" "+r") 1580 (match_operand:QI 1 "register_operand" "+r")) 1581 (set (match_dup 1) 1582 (match_dup 0))] 1583 "!TARGET_PARTIAL_REG_STALL || optimize_size" 1584 "xchg{l}\t%k1, %k0" 1585 [(set_attr "type" "imov") 1586 (set_attr "mode" "SI") 1587 (set_attr "pent_pair" "np") 1588 (set_attr "athlon_decode" "vector") 1589 (set_attr "amdfam10_decode" "vector")]) 1590 1591;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10 1592(define_insn "*swapqi_2" 1593 [(set (match_operand:QI 0 "register_operand" "+q") 1594 (match_operand:QI 1 "register_operand" "+q")) 1595 (set (match_dup 1) 1596 (match_dup 0))] 1597 "TARGET_PARTIAL_REG_STALL" 1598 "xchg{b}\t%1, %0" 1599 [(set_attr "type" "imov") 1600 (set_attr "mode" "QI") 1601 (set_attr "pent_pair" "np") 1602 (set_attr "athlon_decode" "vector")]) 1603 1604(define_expand "movstrictqi" 1605 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 1606 (match_operand:QI 1 "general_operand" ""))] 1607 "! TARGET_PARTIAL_REG_STALL || optimize_size" 1608{ 1609 /* Don't generate memory->memory moves, go through a register. */ 1610 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 1611 operands[1] = force_reg (QImode, operands[1]); 1612}) 1613 1614(define_insn "*movstrictqi_1" 1615 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 1616 (match_operand:QI 1 "general_operand" "*qn,m"))] 1617 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 1618 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 1619 "mov{b}\t{%1, %0|%0, %1}" 1620 [(set_attr "type" "imov") 1621 (set_attr "mode" "QI")]) 1622 1623(define_insn "*movstrictqi_xor" 1624 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q")) 1625 (match_operand:QI 1 "const0_operand" "i")) 1626 (clobber (reg:CC FLAGS_REG))] 1627 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)" 1628 "xor{b}\t{%0, %0|%0, %0}" 1629 [(set_attr "type" "alu1") 1630 (set_attr "mode" "QI") 1631 (set_attr "length_immediate" "0")]) 1632 1633(define_insn "*movsi_extv_1" 1634 [(set (match_operand:SI 0 "register_operand" "=R") 1635 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q") 1636 (const_int 8) 1637 (const_int 8)))] 1638 "" 1639 "movs{bl|x}\t{%h1, %0|%0, %h1}" 1640 [(set_attr "type" "imovx") 1641 (set_attr "mode" "SI")]) 1642 1643(define_insn "*movhi_extv_1" 1644 [(set (match_operand:HI 0 "register_operand" "=R") 1645 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q") 1646 (const_int 8) 1647 (const_int 8)))] 1648 "" 1649 "movs{bl|x}\t{%h1, %k0|%k0, %h1}" 1650 [(set_attr "type" "imovx") 1651 (set_attr "mode" "SI")]) 1652 1653(define_insn "*movqi_extv_1" 1654 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r") 1655 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") 1656 (const_int 8) 1657 (const_int 8)))] 1658 "!TARGET_64BIT" 1659{ 1660 switch (get_attr_type (insn)) 1661 { 1662 case TYPE_IMOVX: 1663 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; 1664 default: 1665 return "mov{b}\t{%h1, %0|%0, %h1}"; 1666 } 1667} 1668 [(set (attr "type") 1669 (if_then_else (and (match_operand:QI 0 "register_operand" "") 1670 (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1671 (ne (symbol_ref "TARGET_MOVX") 1672 (const_int 0)))) 1673 (const_string "imovx") 1674 (const_string "imov"))) 1675 (set (attr "mode") 1676 (if_then_else (eq_attr "type" "imovx") 1677 (const_string "SI") 1678 (const_string "QI")))]) 1679 1680(define_insn "*movqi_extv_1_rex64" 1681 [(set (match_operand:QI 0 "register_operand" "=Q,?R") 1682 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") 1683 (const_int 8) 1684 (const_int 8)))] 1685 "TARGET_64BIT" 1686{ 1687 switch (get_attr_type (insn)) 1688 { 1689 case TYPE_IMOVX: 1690 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; 1691 default: 1692 return "mov{b}\t{%h1, %0|%0, %h1}"; 1693 } 1694} 1695 [(set (attr "type") 1696 (if_then_else (and (match_operand:QI 0 "register_operand" "") 1697 (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1698 (ne (symbol_ref "TARGET_MOVX") 1699 (const_int 0)))) 1700 (const_string "imovx") 1701 (const_string "imov"))) 1702 (set (attr "mode") 1703 (if_then_else (eq_attr "type" "imovx") 1704 (const_string "SI") 1705 (const_string "QI")))]) 1706 1707;; Stores and loads of ax to arbitrary constant address. 1708;; We fake an second form of instruction to force reload to load address 1709;; into register when rax is not available 1710(define_insn "*movabsqi_1_rex64" 1711 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 1712 (match_operand:QI 1 "nonmemory_operand" "a,er"))] 1713 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 1714 "@ 1715 movabs{b}\t{%1, %P0|%P0, %1} 1716 mov{b}\t{%1, %a0|%a0, %1}" 1717 [(set_attr "type" "imov") 1718 (set_attr "modrm" "0,*") 1719 (set_attr "length_address" "8,0") 1720 (set_attr "length_immediate" "0,*") 1721 (set_attr "memory" "store") 1722 (set_attr "mode" "QI")]) 1723 1724(define_insn "*movabsqi_2_rex64" 1725 [(set (match_operand:QI 0 "register_operand" "=a,r") 1726 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 1727 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 1728 "@ 1729 movabs{b}\t{%P1, %0|%0, %P1} 1730 mov{b}\t{%a1, %0|%0, %a1}" 1731 [(set_attr "type" "imov") 1732 (set_attr "modrm" "0,*") 1733 (set_attr "length_address" "8,0") 1734 (set_attr "length_immediate" "0") 1735 (set_attr "memory" "load") 1736 (set_attr "mode" "QI")]) 1737 1738(define_insn "*movdi_extzv_1" 1739 [(set (match_operand:DI 0 "register_operand" "=R") 1740 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q") 1741 (const_int 8) 1742 (const_int 8)))] 1743 "TARGET_64BIT" 1744 "movz{bl|x}\t{%h1, %k0|%k0, %h1}" 1745 [(set_attr "type" "imovx") 1746 (set_attr "mode" "DI")]) 1747 1748(define_insn "*movsi_extzv_1" 1749 [(set (match_operand:SI 0 "register_operand" "=R") 1750 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q") 1751 (const_int 8) 1752 (const_int 8)))] 1753 "" 1754 "movz{bl|x}\t{%h1, %0|%0, %h1}" 1755 [(set_attr "type" "imovx") 1756 (set_attr "mode" "SI")]) 1757 1758(define_insn "*movqi_extzv_2" 1759 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R") 1760 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") 1761 (const_int 8) 1762 (const_int 8)) 0))] 1763 "!TARGET_64BIT" 1764{ 1765 switch (get_attr_type (insn)) 1766 { 1767 case TYPE_IMOVX: 1768 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 1769 default: 1770 return "mov{b}\t{%h1, %0|%0, %h1}"; 1771 } 1772} 1773 [(set (attr "type") 1774 (if_then_else (and (match_operand:QI 0 "register_operand" "") 1775 (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1776 (ne (symbol_ref "TARGET_MOVX") 1777 (const_int 0)))) 1778 (const_string "imovx") 1779 (const_string "imov"))) 1780 (set (attr "mode") 1781 (if_then_else (eq_attr "type" "imovx") 1782 (const_string "SI") 1783 (const_string "QI")))]) 1784 1785(define_insn "*movqi_extzv_2_rex64" 1786 [(set (match_operand:QI 0 "register_operand" "=Q,?R") 1787 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") 1788 (const_int 8) 1789 (const_int 8)) 0))] 1790 "TARGET_64BIT" 1791{ 1792 switch (get_attr_type (insn)) 1793 { 1794 case TYPE_IMOVX: 1795 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 1796 default: 1797 return "mov{b}\t{%h1, %0|%0, %h1}"; 1798 } 1799} 1800 [(set (attr "type") 1801 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1802 (ne (symbol_ref "TARGET_MOVX") 1803 (const_int 0))) 1804 (const_string "imovx") 1805 (const_string "imov"))) 1806 (set (attr "mode") 1807 (if_then_else (eq_attr "type" "imovx") 1808 (const_string "SI") 1809 (const_string "QI")))]) 1810 1811(define_insn "movsi_insv_1" 1812 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 1813 (const_int 8) 1814 (const_int 8)) 1815 (match_operand:SI 1 "general_operand" "Qmn"))] 1816 "!TARGET_64BIT" 1817 "mov{b}\t{%b1, %h0|%h0, %b1}" 1818 [(set_attr "type" "imov") 1819 (set_attr "mode" "QI")]) 1820 1821(define_insn "movdi_insv_1_rex64" 1822 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q") 1823 (const_int 8) 1824 (const_int 8)) 1825 (match_operand:DI 1 "nonmemory_operand" "Qn"))] 1826 "TARGET_64BIT" 1827 "mov{b}\t{%b1, %h0|%h0, %b1}" 1828 [(set_attr "type" "imov") 1829 (set_attr "mode" "QI")]) 1830 1831(define_insn "*movqi_insv_2" 1832 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 1833 (const_int 8) 1834 (const_int 8)) 1835 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q") 1836 (const_int 8)))] 1837 "" 1838 "mov{b}\t{%h1, %h0|%h0, %h1}" 1839 [(set_attr "type" "imov") 1840 (set_attr "mode" "QI")]) 1841 1842(define_expand "movdi" 1843 [(set (match_operand:DI 0 "nonimmediate_operand" "") 1844 (match_operand:DI 1 "general_operand" ""))] 1845 "" 1846 "ix86_expand_move (DImode, operands); DONE;") 1847 1848(define_insn "*pushdi" 1849 [(set (match_operand:DI 0 "push_operand" "=<") 1850 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))] 1851 "!TARGET_64BIT" 1852 "#") 1853 1854(define_insn "*pushdi2_rex64" 1855 [(set (match_operand:DI 0 "push_operand" "=<,!<") 1856 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))] 1857 "TARGET_64BIT" 1858 "@ 1859 push{q}\t%1 1860 #" 1861 [(set_attr "type" "push,multi") 1862 (set_attr "mode" "DI")]) 1863 1864;; Convert impossible pushes of immediate to existing instructions. 1865;; First try to get scratch register and go through it. In case this 1866;; fails, push sign extended lower part first and then overwrite 1867;; upper part by 32bit move. 1868(define_peephole2 1869 [(match_scratch:DI 2 "r") 1870 (set (match_operand:DI 0 "push_operand" "") 1871 (match_operand:DI 1 "immediate_operand" ""))] 1872 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1873 && !x86_64_immediate_operand (operands[1], DImode)" 1874 [(set (match_dup 2) (match_dup 1)) 1875 (set (match_dup 0) (match_dup 2))] 1876 "") 1877 1878;; We need to define this as both peepholer and splitter for case 1879;; peephole2 pass is not run. 1880;; "&& 1" is needed to keep it from matching the previous pattern. 1881(define_peephole2 1882 [(set (match_operand:DI 0 "push_operand" "") 1883 (match_operand:DI 1 "immediate_operand" ""))] 1884 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1885 && !x86_64_immediate_operand (operands[1], DImode) && 1" 1886 [(set (match_dup 0) (match_dup 1)) 1887 (set (match_dup 2) (match_dup 3))] 1888 "split_di (operands + 1, 1, operands + 2, operands + 3); 1889 operands[1] = gen_lowpart (DImode, operands[2]); 1890 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, 1891 GEN_INT (4))); 1892 ") 1893 1894(define_split 1895 [(set (match_operand:DI 0 "push_operand" "") 1896 (match_operand:DI 1 "immediate_operand" ""))] 1897 "TARGET_64BIT && ((optimize > 0 && flag_peephole2) 1898 ? flow2_completed : reload_completed) 1899 && !symbolic_operand (operands[1], DImode) 1900 && !x86_64_immediate_operand (operands[1], DImode)" 1901 [(set (match_dup 0) (match_dup 1)) 1902 (set (match_dup 2) (match_dup 3))] 1903 "split_di (operands + 1, 1, operands + 2, operands + 3); 1904 operands[1] = gen_lowpart (DImode, operands[2]); 1905 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, 1906 GEN_INT (4))); 1907 ") 1908 1909(define_insn "*pushdi2_prologue_rex64" 1910 [(set (match_operand:DI 0 "push_operand" "=<") 1911 (match_operand:DI 1 "general_no_elim_operand" "re*m")) 1912 (clobber (mem:BLK (scratch)))] 1913 "TARGET_64BIT" 1914 "push{q}\t%1" 1915 [(set_attr "type" "push") 1916 (set_attr "mode" "DI")]) 1917 1918(define_insn "*popdi1_epilogue_rex64" 1919 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m") 1920 (mem:DI (reg:DI SP_REG))) 1921 (set (reg:DI SP_REG) 1922 (plus:DI (reg:DI SP_REG) (const_int 8))) 1923 (clobber (mem:BLK (scratch)))] 1924 "TARGET_64BIT" 1925 "pop{q}\t%0" 1926 [(set_attr "type" "pop") 1927 (set_attr "mode" "DI")]) 1928 1929(define_insn "popdi1" 1930 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m") 1931 (mem:DI (reg:DI SP_REG))) 1932 (set (reg:DI SP_REG) 1933 (plus:DI (reg:DI SP_REG) (const_int 8)))] 1934 "TARGET_64BIT" 1935 "pop{q}\t%0" 1936 [(set_attr "type" "pop") 1937 (set_attr "mode" "DI")]) 1938 1939(define_insn "*movdi_xor_rex64" 1940 [(set (match_operand:DI 0 "register_operand" "=r") 1941 (match_operand:DI 1 "const0_operand" "i")) 1942 (clobber (reg:CC FLAGS_REG))] 1943 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size) 1944 && reload_completed" 1945 "xor{l}\t{%k0, %k0|%k0, %k0}" 1946 [(set_attr "type" "alu1") 1947 (set_attr "mode" "SI") 1948 (set_attr "length_immediate" "0")]) 1949 1950(define_insn "*movdi_or_rex64" 1951 [(set (match_operand:DI 0 "register_operand" "=r") 1952 (match_operand:DI 1 "const_int_operand" "i")) 1953 (clobber (reg:CC FLAGS_REG))] 1954 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size) 1955 && reload_completed 1956 && operands[1] == constm1_rtx" 1957{ 1958 operands[1] = constm1_rtx; 1959 return "or{q}\t{%1, %0|%0, %1}"; 1960} 1961 [(set_attr "type" "alu1") 1962 (set_attr "mode" "DI") 1963 (set_attr "length_immediate" "1")]) 1964 1965(define_insn "*movdi_2" 1966 [(set (match_operand:DI 0 "nonimmediate_operand" 1967 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x") 1968 (match_operand:DI 1 "general_operand" 1969 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))] 1970 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1971 "@ 1972 # 1973 # 1974 pxor\t%0, %0 1975 movq\t{%1, %0|%0, %1} 1976 movq\t{%1, %0|%0, %1} 1977 pxor\t%0, %0 1978 movq\t{%1, %0|%0, %1} 1979 movdqa\t{%1, %0|%0, %1} 1980 movq\t{%1, %0|%0, %1} 1981 xorps\t%0, %0 1982 movlps\t{%1, %0|%0, %1} 1983 movaps\t{%1, %0|%0, %1} 1984 movlps\t{%1, %0|%0, %1}" 1985 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov") 1986 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")]) 1987 1988(define_split 1989 [(set (match_operand:DI 0 "push_operand" "") 1990 (match_operand:DI 1 "general_operand" ""))] 1991 "!TARGET_64BIT && reload_completed 1992 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))" 1993 [(const_int 0)] 1994 "ix86_split_long_move (operands); DONE;") 1995 1996;; %%% This multiword shite has got to go. 1997(define_split 1998 [(set (match_operand:DI 0 "nonimmediate_operand" "") 1999 (match_operand:DI 1 "general_operand" ""))] 2000 "!TARGET_64BIT && reload_completed 2001 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0])) 2002 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))" 2003 [(const_int 0)] 2004 "ix86_split_long_move (operands); DONE;") 2005 2006(define_insn "*movdi_1_rex64" 2007 [(set (match_operand:DI 0 "nonimmediate_operand" 2008 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y") 2009 (match_operand:DI 1 "general_operand" 2010 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))] 2011 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 2012{ 2013 switch (get_attr_type (insn)) 2014 { 2015 case TYPE_SSECVT: 2016 if (which_alternative == 13) 2017 return "movq2dq\t{%1, %0|%0, %1}"; 2018 else 2019 return "movdq2q\t{%1, %0|%0, %1}"; 2020 case TYPE_SSEMOV: 2021 if (get_attr_mode (insn) == MODE_TI) 2022 return "movdqa\t{%1, %0|%0, %1}"; 2023 /* FALLTHRU */ 2024 case TYPE_MMXMOV: 2025 /* Moves from and into integer register is done using movd opcode with 2026 REX prefix. */ 2027 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])) 2028 return "movd\t{%1, %0|%0, %1}"; 2029 return "movq\t{%1, %0|%0, %1}"; 2030 case TYPE_SSELOG1: 2031 case TYPE_MMXADD: 2032 return "pxor\t%0, %0"; 2033 case TYPE_MULTI: 2034 return "#"; 2035 case TYPE_LEA: 2036 return "lea{q}\t{%a1, %0|%0, %a1}"; 2037 default: 2038 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 2039 if (get_attr_mode (insn) == MODE_SI) 2040 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2041 else if (which_alternative == 2) 2042 return "movabs{q}\t{%1, %0|%0, %1}"; 2043 else 2044 return "mov{q}\t{%1, %0|%0, %1}"; 2045 } 2046} 2047 [(set (attr "type") 2048 (cond [(eq_attr "alternative" "5") 2049 (const_string "mmxadd") 2050 (eq_attr "alternative" "6,7,8") 2051 (const_string "mmxmov") 2052 (eq_attr "alternative" "9") 2053 (const_string "sselog1") 2054 (eq_attr "alternative" "10,11,12") 2055 (const_string "ssemov") 2056 (eq_attr "alternative" "13,14") 2057 (const_string "ssecvt") 2058 (eq_attr "alternative" "4") 2059 (const_string "multi") 2060 (match_operand:DI 1 "pic_32bit_operand" "") 2061 (const_string "lea") 2062 ] 2063 (const_string "imov"))) 2064 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*") 2065 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*") 2066 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")]) 2067 2068;; Stores and loads of ax to arbitrary constant address. 2069;; We fake an second form of instruction to force reload to load address 2070;; into register when rax is not available 2071(define_insn "*movabsdi_1_rex64" 2072 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 2073 (match_operand:DI 1 "nonmemory_operand" "a,er"))] 2074 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 2075 "@ 2076 movabs{q}\t{%1, %P0|%P0, %1} 2077 mov{q}\t{%1, %a0|%a0, %1}" 2078 [(set_attr "type" "imov") 2079 (set_attr "modrm" "0,*") 2080 (set_attr "length_address" "8,0") 2081 (set_attr "length_immediate" "0,*") 2082 (set_attr "memory" "store") 2083 (set_attr "mode" "DI")]) 2084 2085(define_insn "*movabsdi_2_rex64" 2086 [(set (match_operand:DI 0 "register_operand" "=a,r") 2087 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 2088 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 2089 "@ 2090 movabs{q}\t{%P1, %0|%0, %P1} 2091 mov{q}\t{%a1, %0|%0, %a1}" 2092 [(set_attr "type" "imov") 2093 (set_attr "modrm" "0,*") 2094 (set_attr "length_address" "8,0") 2095 (set_attr "length_immediate" "0") 2096 (set_attr "memory" "load") 2097 (set_attr "mode" "DI")]) 2098 2099;; Convert impossible stores of immediate to existing instructions. 2100;; First try to get scratch register and go through it. In case this 2101;; fails, move by 32bit parts. 2102(define_peephole2 2103 [(match_scratch:DI 2 "r") 2104 (set (match_operand:DI 0 "memory_operand" "") 2105 (match_operand:DI 1 "immediate_operand" ""))] 2106 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 2107 && !x86_64_immediate_operand (operands[1], DImode)" 2108 [(set (match_dup 2) (match_dup 1)) 2109 (set (match_dup 0) (match_dup 2))] 2110 "") 2111 2112;; We need to define this as both peepholer and splitter for case 2113;; peephole2 pass is not run. 2114;; "&& 1" is needed to keep it from matching the previous pattern. 2115(define_peephole2 2116 [(set (match_operand:DI 0 "memory_operand" "") 2117 (match_operand:DI 1 "immediate_operand" ""))] 2118 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 2119 && !x86_64_immediate_operand (operands[1], DImode) && 1" 2120 [(set (match_dup 2) (match_dup 3)) 2121 (set (match_dup 4) (match_dup 5))] 2122 "split_di (operands, 2, operands + 2, operands + 4);") 2123 2124(define_split 2125 [(set (match_operand:DI 0 "memory_operand" "") 2126 (match_operand:DI 1 "immediate_operand" ""))] 2127 "TARGET_64BIT && ((optimize > 0 && flag_peephole2) 2128 ? flow2_completed : reload_completed) 2129 && !symbolic_operand (operands[1], DImode) 2130 && !x86_64_immediate_operand (operands[1], DImode)" 2131 [(set (match_dup 2) (match_dup 3)) 2132 (set (match_dup 4) (match_dup 5))] 2133 "split_di (operands, 2, operands + 2, operands + 4);") 2134 2135(define_insn "*swapdi_rex64" 2136 [(set (match_operand:DI 0 "register_operand" "+r") 2137 (match_operand:DI 1 "register_operand" "+r")) 2138 (set (match_dup 1) 2139 (match_dup 0))] 2140 "TARGET_64BIT" 2141 "xchg{q}\t%1, %0" 2142 [(set_attr "type" "imov") 2143 (set_attr "mode" "DI") 2144 (set_attr "pent_pair" "np") 2145 (set_attr "athlon_decode" "vector") 2146 (set_attr "amdfam10_decode" "double")]) 2147 2148(define_expand "movti" 2149 [(set (match_operand:TI 0 "nonimmediate_operand" "") 2150 (match_operand:TI 1 "nonimmediate_operand" ""))] 2151 "TARGET_SSE || TARGET_64BIT" 2152{ 2153 if (TARGET_64BIT) 2154 ix86_expand_move (TImode, operands); 2155 else 2156 ix86_expand_vector_move (TImode, operands); 2157 DONE; 2158}) 2159 2160(define_insn "*movti_internal" 2161 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m") 2162 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))] 2163 "TARGET_SSE && !TARGET_64BIT 2164 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 2165{ 2166 switch (which_alternative) 2167 { 2168 case 0: 2169 if (get_attr_mode (insn) == MODE_V4SF) 2170 return "xorps\t%0, %0"; 2171 else 2172 return "pxor\t%0, %0"; 2173 case 1: 2174 case 2: 2175 if (get_attr_mode (insn) == MODE_V4SF) 2176 return "movaps\t{%1, %0|%0, %1}"; 2177 else 2178 return "movdqa\t{%1, %0|%0, %1}"; 2179 default: 2180 gcc_unreachable (); 2181 } 2182} 2183 [(set_attr "type" "sselog1,ssemov,ssemov") 2184 (set (attr "mode") 2185 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 2186 (ne (symbol_ref "optimize_size") (const_int 0))) 2187 (const_string "V4SF") 2188 (and (eq_attr "alternative" "2") 2189 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") 2190 (const_int 0))) 2191 (const_string "V4SF")] 2192 (const_string "TI")))]) 2193 2194(define_insn "*movti_rex64" 2195 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm") 2196 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))] 2197 "TARGET_64BIT 2198 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 2199{ 2200 switch (which_alternative) 2201 { 2202 case 0: 2203 case 1: 2204 return "#"; 2205 case 2: 2206 if (get_attr_mode (insn) == MODE_V4SF) 2207 return "xorps\t%0, %0"; 2208 else 2209 return "pxor\t%0, %0"; 2210 case 3: 2211 case 4: 2212 if (get_attr_mode (insn) == MODE_V4SF) 2213 return "movaps\t{%1, %0|%0, %1}"; 2214 else 2215 return "movdqa\t{%1, %0|%0, %1}"; 2216 default: 2217 gcc_unreachable (); 2218 } 2219} 2220 [(set_attr "type" "*,*,sselog1,ssemov,ssemov") 2221 (set (attr "mode") 2222 (cond [(eq_attr "alternative" "2,3") 2223 (if_then_else 2224 (ne (symbol_ref "optimize_size") 2225 (const_int 0)) 2226 (const_string "V4SF") 2227 (const_string "TI")) 2228 (eq_attr "alternative" "4") 2229 (if_then_else 2230 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") 2231 (const_int 0)) 2232 (ne (symbol_ref "optimize_size") 2233 (const_int 0))) 2234 (const_string "V4SF") 2235 (const_string "TI"))] 2236 (const_string "DI")))]) 2237 2238(define_split 2239 [(set (match_operand:TI 0 "nonimmediate_operand" "") 2240 (match_operand:TI 1 "general_operand" ""))] 2241 "reload_completed && !SSE_REG_P (operands[0]) 2242 && !SSE_REG_P (operands[1])" 2243 [(const_int 0)] 2244 "ix86_split_long_move (operands); DONE;") 2245 2246(define_expand "movsf" 2247 [(set (match_operand:SF 0 "nonimmediate_operand" "") 2248 (match_operand:SF 1 "general_operand" ""))] 2249 "" 2250 "ix86_expand_move (SFmode, operands); DONE;") 2251 2252(define_insn "*pushsf" 2253 [(set (match_operand:SF 0 "push_operand" "=<,<,<") 2254 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))] 2255 "!TARGET_64BIT" 2256{ 2257 /* Anything else should be already split before reg-stack. */ 2258 gcc_assert (which_alternative == 1); 2259 return "push{l}\t%1"; 2260} 2261 [(set_attr "type" "multi,push,multi") 2262 (set_attr "unit" "i387,*,*") 2263 (set_attr "mode" "SF,SI,SF")]) 2264 2265(define_insn "*pushsf_rex64" 2266 [(set (match_operand:SF 0 "push_operand" "=X,X,X") 2267 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))] 2268 "TARGET_64BIT" 2269{ 2270 /* Anything else should be already split before reg-stack. */ 2271 gcc_assert (which_alternative == 1); 2272 return "push{q}\t%q1"; 2273} 2274 [(set_attr "type" "multi,push,multi") 2275 (set_attr "unit" "i387,*,*") 2276 (set_attr "mode" "SF,DI,SF")]) 2277 2278(define_split 2279 [(set (match_operand:SF 0 "push_operand" "") 2280 (match_operand:SF 1 "memory_operand" ""))] 2281 "reload_completed 2282 && GET_CODE (operands[1]) == MEM 2283 && constant_pool_reference_p (operands[1])" 2284 [(set (match_dup 0) 2285 (match_dup 1))] 2286 "operands[1] = avoid_constant_pool_reference (operands[1]);") 2287 2288 2289;; %%% Kill this when call knows how to work this out. 2290(define_split 2291 [(set (match_operand:SF 0 "push_operand" "") 2292 (match_operand:SF 1 "any_fp_register_operand" ""))] 2293 "!TARGET_64BIT" 2294 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) 2295 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))]) 2296 2297(define_split 2298 [(set (match_operand:SF 0 "push_operand" "") 2299 (match_operand:SF 1 "any_fp_register_operand" ""))] 2300 "TARGET_64BIT" 2301 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 2302 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))]) 2303 2304(define_insn "*movsf_1" 2305 [(set (match_operand:SF 0 "nonimmediate_operand" 2306 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y") 2307 (match_operand:SF 1 "general_operand" 2308 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))] 2309 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 2310 && (reload_in_progress || reload_completed 2311 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2312 || GET_CODE (operands[1]) != CONST_DOUBLE 2313 || memory_operand (operands[0], SFmode))" 2314{ 2315 switch (which_alternative) 2316 { 2317 case 0: 2318 return output_387_reg_move (insn, operands); 2319 2320 case 1: 2321 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2322 return "fstp%z0\t%y0"; 2323 else 2324 return "fst%z0\t%y0"; 2325 2326 case 2: 2327 return standard_80387_constant_opcode (operands[1]); 2328 2329 case 3: 2330 case 4: 2331 return "mov{l}\t{%1, %0|%0, %1}"; 2332 case 5: 2333 if (get_attr_mode (insn) == MODE_TI) 2334 return "pxor\t%0, %0"; 2335 else 2336 return "xorps\t%0, %0"; 2337 case 6: 2338 if (get_attr_mode (insn) == MODE_V4SF) 2339 return "movaps\t{%1, %0|%0, %1}"; 2340 else 2341 return "movss\t{%1, %0|%0, %1}"; 2342 case 7: 2343 case 8: 2344 return "movss\t{%1, %0|%0, %1}"; 2345 2346 case 9: 2347 case 10: 2348 return "movd\t{%1, %0|%0, %1}"; 2349 2350 case 11: 2351 return "movq\t{%1, %0|%0, %1}"; 2352 2353 default: 2354 gcc_unreachable (); 2355 } 2356} 2357 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov") 2358 (set (attr "mode") 2359 (cond [(eq_attr "alternative" "3,4,9,10") 2360 (const_string "SI") 2361 (eq_attr "alternative" "5") 2362 (if_then_else 2363 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") 2364 (const_int 0)) 2365 (ne (symbol_ref "TARGET_SSE2") 2366 (const_int 0))) 2367 (eq (symbol_ref "optimize_size") 2368 (const_int 0))) 2369 (const_string "TI") 2370 (const_string "V4SF")) 2371 /* For architectures resolving dependencies on 2372 whole SSE registers use APS move to break dependency 2373 chains, otherwise use short move to avoid extra work. 2374 2375 Do the same for architectures resolving dependencies on 2376 the parts. While in DF mode it is better to always handle 2377 just register parts, the SF mode is different due to lack 2378 of instructions to load just part of the register. It is 2379 better to maintain the whole registers in single format 2380 to avoid problems on using packed logical operations. */ 2381 (eq_attr "alternative" "6") 2382 (if_then_else 2383 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 2384 (const_int 0)) 2385 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") 2386 (const_int 0))) 2387 (const_string "V4SF") 2388 (const_string "SF")) 2389 (eq_attr "alternative" "11") 2390 (const_string "DI")] 2391 (const_string "SF")))]) 2392 2393(define_insn "*swapsf" 2394 [(set (match_operand:SF 0 "fp_register_operand" "+f") 2395 (match_operand:SF 1 "fp_register_operand" "+f")) 2396 (set (match_dup 1) 2397 (match_dup 0))] 2398 "reload_completed || TARGET_80387" 2399{ 2400 if (STACK_TOP_P (operands[0])) 2401 return "fxch\t%1"; 2402 else 2403 return "fxch\t%0"; 2404} 2405 [(set_attr "type" "fxch") 2406 (set_attr "mode" "SF")]) 2407 2408(define_expand "movdf" 2409 [(set (match_operand:DF 0 "nonimmediate_operand" "") 2410 (match_operand:DF 1 "general_operand" ""))] 2411 "" 2412 "ix86_expand_move (DFmode, operands); DONE;") 2413 2414;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. 2415;; Size of pushdf using integer instructions is 2+2*memory operand size 2416;; On the average, pushdf using integers can be still shorter. Allow this 2417;; pattern for optimize_size too. 2418 2419(define_insn "*pushdf_nointeger" 2420 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<") 2421 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))] 2422 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES" 2423{ 2424 /* This insn should be already split before reg-stack. */ 2425 gcc_unreachable (); 2426} 2427 [(set_attr "type" "multi") 2428 (set_attr "unit" "i387,*,*,*") 2429 (set_attr "mode" "DF,SI,SI,DF")]) 2430 2431(define_insn "*pushdf_integer" 2432 [(set (match_operand:DF 0 "push_operand" "=<,<,<") 2433 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))] 2434 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES" 2435{ 2436 /* This insn should be already split before reg-stack. */ 2437 gcc_unreachable (); 2438} 2439 [(set_attr "type" "multi") 2440 (set_attr "unit" "i387,*,*") 2441 (set_attr "mode" "DF,SI,DF")]) 2442 2443;; %%% Kill this when call knows how to work this out. 2444(define_split 2445 [(set (match_operand:DF 0 "push_operand" "") 2446 (match_operand:DF 1 "any_fp_register_operand" ""))] 2447 "!TARGET_64BIT && reload_completed" 2448 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 2449 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))] 2450 "") 2451 2452(define_split 2453 [(set (match_operand:DF 0 "push_operand" "") 2454 (match_operand:DF 1 "any_fp_register_operand" ""))] 2455 "TARGET_64BIT && reload_completed" 2456 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 2457 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))] 2458 "") 2459 2460(define_split 2461 [(set (match_operand:DF 0 "push_operand" "") 2462 (match_operand:DF 1 "general_operand" ""))] 2463 "reload_completed" 2464 [(const_int 0)] 2465 "ix86_split_long_move (operands); DONE;") 2466 2467;; Moving is usually shorter when only FP registers are used. This separate 2468;; movdf pattern avoids the use of integer registers for FP operations 2469;; when optimizing for size. 2470 2471(define_insn "*movdf_nointeger" 2472 [(set (match_operand:DF 0 "nonimmediate_operand" 2473 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ") 2474 (match_operand:DF 1 "general_operand" 2475 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))] 2476 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2477 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT) 2478 && (reload_in_progress || reload_completed 2479 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2480 || GET_CODE (operands[1]) != CONST_DOUBLE 2481 || memory_operand (operands[0], DFmode))" 2482{ 2483 switch (which_alternative) 2484 { 2485 case 0: 2486 return output_387_reg_move (insn, operands); 2487 2488 case 1: 2489 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2490 return "fstp%z0\t%y0"; 2491 else 2492 return "fst%z0\t%y0"; 2493 2494 case 2: 2495 return standard_80387_constant_opcode (operands[1]); 2496 2497 case 3: 2498 case 4: 2499 return "#"; 2500 case 5: 2501 switch (get_attr_mode (insn)) 2502 { 2503 case MODE_V4SF: 2504 return "xorps\t%0, %0"; 2505 case MODE_V2DF: 2506 return "xorpd\t%0, %0"; 2507 case MODE_TI: 2508 return "pxor\t%0, %0"; 2509 default: 2510 gcc_unreachable (); 2511 } 2512 case 6: 2513 case 7: 2514 case 8: 2515 switch (get_attr_mode (insn)) 2516 { 2517 case MODE_V4SF: 2518 return "movaps\t{%1, %0|%0, %1}"; 2519 case MODE_V2DF: 2520 return "movapd\t{%1, %0|%0, %1}"; 2521 case MODE_TI: 2522 return "movdqa\t{%1, %0|%0, %1}"; 2523 case MODE_DI: 2524 return "movq\t{%1, %0|%0, %1}"; 2525 case MODE_DF: 2526 return "movsd\t{%1, %0|%0, %1}"; 2527 case MODE_V1DF: 2528 return "movlpd\t{%1, %0|%0, %1}"; 2529 case MODE_V2SF: 2530 return "movlps\t{%1, %0|%0, %1}"; 2531 default: 2532 gcc_unreachable (); 2533 } 2534 2535 default: 2536 gcc_unreachable (); 2537 } 2538} 2539 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov") 2540 (set (attr "mode") 2541 (cond [(eq_attr "alternative" "0,1,2") 2542 (const_string "DF") 2543 (eq_attr "alternative" "3,4") 2544 (const_string "SI") 2545 2546 /* For SSE1, we have many fewer alternatives. */ 2547 (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 2548 (cond [(eq_attr "alternative" "5,6") 2549 (const_string "V4SF") 2550 ] 2551 (const_string "V2SF")) 2552 2553 /* xorps is one byte shorter. */ 2554 (eq_attr "alternative" "5") 2555 (cond [(ne (symbol_ref "optimize_size") 2556 (const_int 0)) 2557 (const_string "V4SF") 2558 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") 2559 (const_int 0)) 2560 (const_string "TI") 2561 ] 2562 (const_string "V2DF")) 2563 2564 /* For architectures resolving dependencies on 2565 whole SSE registers use APD move to break dependency 2566 chains, otherwise use short move to avoid extra work. 2567 2568 movaps encodes one byte shorter. */ 2569 (eq_attr "alternative" "6") 2570 (cond 2571 [(ne (symbol_ref "optimize_size") 2572 (const_int 0)) 2573 (const_string "V4SF") 2574 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 2575 (const_int 0)) 2576 (const_string "V2DF") 2577 ] 2578 (const_string "DF")) 2579 /* For architectures resolving dependencies on register 2580 parts we may avoid extra work to zero out upper part 2581 of register. */ 2582 (eq_attr "alternative" "7") 2583 (if_then_else 2584 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") 2585 (const_int 0)) 2586 (const_string "V1DF") 2587 (const_string "DF")) 2588 ] 2589 (const_string "DF")))]) 2590 2591(define_insn "*movdf_integer" 2592 [(set (match_operand:DF 0 "nonimmediate_operand" 2593 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ") 2594 (match_operand:DF 1 "general_operand" 2595 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))] 2596 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2597 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT) 2598 && (reload_in_progress || reload_completed 2599 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2600 || GET_CODE (operands[1]) != CONST_DOUBLE 2601 || memory_operand (operands[0], DFmode))" 2602{ 2603 switch (which_alternative) 2604 { 2605 case 0: 2606 return output_387_reg_move (insn, operands); 2607 2608 case 1: 2609 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2610 return "fstp%z0\t%y0"; 2611 else 2612 return "fst%z0\t%y0"; 2613 2614 case 2: 2615 return standard_80387_constant_opcode (operands[1]); 2616 2617 case 3: 2618 case 4: 2619 return "#"; 2620 2621 case 5: 2622 switch (get_attr_mode (insn)) 2623 { 2624 case MODE_V4SF: 2625 return "xorps\t%0, %0"; 2626 case MODE_V2DF: 2627 return "xorpd\t%0, %0"; 2628 case MODE_TI: 2629 return "pxor\t%0, %0"; 2630 default: 2631 gcc_unreachable (); 2632 } 2633 case 6: 2634 case 7: 2635 case 8: 2636 switch (get_attr_mode (insn)) 2637 { 2638 case MODE_V4SF: 2639 return "movaps\t{%1, %0|%0, %1}"; 2640 case MODE_V2DF: 2641 return "movapd\t{%1, %0|%0, %1}"; 2642 case MODE_TI: 2643 return "movdqa\t{%1, %0|%0, %1}"; 2644 case MODE_DI: 2645 return "movq\t{%1, %0|%0, %1}"; 2646 case MODE_DF: 2647 return "movsd\t{%1, %0|%0, %1}"; 2648 case MODE_V1DF: 2649 return "movlpd\t{%1, %0|%0, %1}"; 2650 case MODE_V2SF: 2651 return "movlps\t{%1, %0|%0, %1}"; 2652 default: 2653 gcc_unreachable (); 2654 } 2655 2656 default: 2657 gcc_unreachable(); 2658 } 2659} 2660 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov") 2661 (set (attr "mode") 2662 (cond [(eq_attr "alternative" "0,1,2") 2663 (const_string "DF") 2664 (eq_attr "alternative" "3,4") 2665 (const_string "SI") 2666 2667 /* For SSE1, we have many fewer alternatives. */ 2668 (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 2669 (cond [(eq_attr "alternative" "5,6") 2670 (const_string "V4SF") 2671 ] 2672 (const_string "V2SF")) 2673 2674 /* xorps is one byte shorter. */ 2675 (eq_attr "alternative" "5") 2676 (cond [(ne (symbol_ref "optimize_size") 2677 (const_int 0)) 2678 (const_string "V4SF") 2679 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") 2680 (const_int 0)) 2681 (const_string "TI") 2682 ] 2683 (const_string "V2DF")) 2684 2685 /* For architectures resolving dependencies on 2686 whole SSE registers use APD move to break dependency 2687 chains, otherwise use short move to avoid extra work. 2688 2689 movaps encodes one byte shorter. */ 2690 (eq_attr "alternative" "6") 2691 (cond 2692 [(ne (symbol_ref "optimize_size") 2693 (const_int 0)) 2694 (const_string "V4SF") 2695 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 2696 (const_int 0)) 2697 (const_string "V2DF") 2698 ] 2699 (const_string "DF")) 2700 /* For architectures resolving dependencies on register 2701 parts we may avoid extra work to zero out upper part 2702 of register. */ 2703 (eq_attr "alternative" "7") 2704 (if_then_else 2705 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") 2706 (const_int 0)) 2707 (const_string "V1DF") 2708 (const_string "DF")) 2709 ] 2710 (const_string "DF")))]) 2711 2712(define_split 2713 [(set (match_operand:DF 0 "nonimmediate_operand" "") 2714 (match_operand:DF 1 "general_operand" ""))] 2715 "reload_completed 2716 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2717 && ! (ANY_FP_REG_P (operands[0]) || 2718 (GET_CODE (operands[0]) == SUBREG 2719 && ANY_FP_REG_P (SUBREG_REG (operands[0])))) 2720 && ! (ANY_FP_REG_P (operands[1]) || 2721 (GET_CODE (operands[1]) == SUBREG 2722 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))" 2723 [(const_int 0)] 2724 "ix86_split_long_move (operands); DONE;") 2725 2726(define_insn "*swapdf" 2727 [(set (match_operand:DF 0 "fp_register_operand" "+f") 2728 (match_operand:DF 1 "fp_register_operand" "+f")) 2729 (set (match_dup 1) 2730 (match_dup 0))] 2731 "reload_completed || TARGET_80387" 2732{ 2733 if (STACK_TOP_P (operands[0])) 2734 return "fxch\t%1"; 2735 else 2736 return "fxch\t%0"; 2737} 2738 [(set_attr "type" "fxch") 2739 (set_attr "mode" "DF")]) 2740 2741(define_expand "movxf" 2742 [(set (match_operand:XF 0 "nonimmediate_operand" "") 2743 (match_operand:XF 1 "general_operand" ""))] 2744 "" 2745 "ix86_expand_move (XFmode, operands); DONE;") 2746 2747;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. 2748;; Size of pushdf using integer instructions is 3+3*memory operand size 2749;; Pushing using integer instructions is longer except for constants 2750;; and direct memory references. 2751;; (assuming that any given constant is pushed only once, but this ought to be 2752;; handled elsewhere). 2753 2754(define_insn "*pushxf_nointeger" 2755 [(set (match_operand:XF 0 "push_operand" "=X,X,X") 2756 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))] 2757 "optimize_size" 2758{ 2759 /* This insn should be already split before reg-stack. */ 2760 gcc_unreachable (); 2761} 2762 [(set_attr "type" "multi") 2763 (set_attr "unit" "i387,*,*") 2764 (set_attr "mode" "XF,SI,SI")]) 2765 2766(define_insn "*pushxf_integer" 2767 [(set (match_operand:XF 0 "push_operand" "=<,<") 2768 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))] 2769 "!optimize_size" 2770{ 2771 /* This insn should be already split before reg-stack. */ 2772 gcc_unreachable (); 2773} 2774 [(set_attr "type" "multi") 2775 (set_attr "unit" "i387,*") 2776 (set_attr "mode" "XF,SI")]) 2777 2778(define_split 2779 [(set (match_operand 0 "push_operand" "") 2780 (match_operand 1 "general_operand" ""))] 2781 "reload_completed 2782 && (GET_MODE (operands[0]) == XFmode 2783 || GET_MODE (operands[0]) == DFmode) 2784 && !ANY_FP_REG_P (operands[1])" 2785 [(const_int 0)] 2786 "ix86_split_long_move (operands); DONE;") 2787 2788(define_split 2789 [(set (match_operand:XF 0 "push_operand" "") 2790 (match_operand:XF 1 "any_fp_register_operand" ""))] 2791 "!TARGET_64BIT" 2792 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2))) 2793 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))] 2794 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 2795 2796(define_split 2797 [(set (match_operand:XF 0 "push_operand" "") 2798 (match_operand:XF 1 "any_fp_register_operand" ""))] 2799 "TARGET_64BIT" 2800 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2))) 2801 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))] 2802 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 2803 2804;; Do not use integer registers when optimizing for size 2805(define_insn "*movxf_nointeger" 2806 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o") 2807 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))] 2808 "optimize_size 2809 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2810 && (reload_in_progress || reload_completed 2811 || GET_CODE (operands[1]) != CONST_DOUBLE 2812 || memory_operand (operands[0], XFmode))" 2813{ 2814 switch (which_alternative) 2815 { 2816 case 0: 2817 return output_387_reg_move (insn, operands); 2818 2819 case 1: 2820 /* There is no non-popping store to memory for XFmode. So if 2821 we need one, follow the store with a load. */ 2822 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2823 return "fstp%z0\t%y0\;fld%z0\t%y0"; 2824 else 2825 return "fstp%z0\t%y0"; 2826 2827 case 2: 2828 return standard_80387_constant_opcode (operands[1]); 2829 2830 case 3: case 4: 2831 return "#"; 2832 default: 2833 gcc_unreachable (); 2834 } 2835} 2836 [(set_attr "type" "fmov,fmov,fmov,multi,multi") 2837 (set_attr "mode" "XF,XF,XF,SI,SI")]) 2838 2839(define_insn "*movxf_integer" 2840 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o") 2841 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))] 2842 "!optimize_size 2843 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2844 && (reload_in_progress || reload_completed 2845 || GET_CODE (operands[1]) != CONST_DOUBLE 2846 || memory_operand (operands[0], XFmode))" 2847{ 2848 switch (which_alternative) 2849 { 2850 case 0: 2851 return output_387_reg_move (insn, operands); 2852 2853 case 1: 2854 /* There is no non-popping store to memory for XFmode. So if 2855 we need one, follow the store with a load. */ 2856 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2857 return "fstp%z0\t%y0\;fld%z0\t%y0"; 2858 else 2859 return "fstp%z0\t%y0"; 2860 2861 case 2: 2862 return standard_80387_constant_opcode (operands[1]); 2863 2864 case 3: case 4: 2865 return "#"; 2866 2867 default: 2868 gcc_unreachable (); 2869 } 2870} 2871 [(set_attr "type" "fmov,fmov,fmov,multi,multi") 2872 (set_attr "mode" "XF,XF,XF,SI,SI")]) 2873 2874(define_split 2875 [(set (match_operand 0 "nonimmediate_operand" "") 2876 (match_operand 1 "general_operand" ""))] 2877 "reload_completed 2878 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2879 && GET_MODE (operands[0]) == XFmode 2880 && ! (ANY_FP_REG_P (operands[0]) || 2881 (GET_CODE (operands[0]) == SUBREG 2882 && ANY_FP_REG_P (SUBREG_REG (operands[0])))) 2883 && ! (ANY_FP_REG_P (operands[1]) || 2884 (GET_CODE (operands[1]) == SUBREG 2885 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))" 2886 [(const_int 0)] 2887 "ix86_split_long_move (operands); DONE;") 2888 2889(define_split 2890 [(set (match_operand 0 "register_operand" "") 2891 (match_operand 1 "memory_operand" ""))] 2892 "reload_completed 2893 && GET_CODE (operands[1]) == MEM 2894 && (GET_MODE (operands[0]) == XFmode 2895 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode) 2896 && constant_pool_reference_p (operands[1])" 2897 [(set (match_dup 0) (match_dup 1))] 2898{ 2899 rtx c = avoid_constant_pool_reference (operands[1]); 2900 rtx r = operands[0]; 2901 2902 if (GET_CODE (r) == SUBREG) 2903 r = SUBREG_REG (r); 2904 2905 if (SSE_REG_P (r)) 2906 { 2907 if (!standard_sse_constant_p (c)) 2908 FAIL; 2909 } 2910 else if (FP_REG_P (r)) 2911 { 2912 if (!standard_80387_constant_p (c)) 2913 FAIL; 2914 } 2915 else if (MMX_REG_P (r)) 2916 FAIL; 2917 2918 operands[1] = c; 2919}) 2920 2921(define_insn "swapxf" 2922 [(set (match_operand:XF 0 "register_operand" "+f") 2923 (match_operand:XF 1 "register_operand" "+f")) 2924 (set (match_dup 1) 2925 (match_dup 0))] 2926 "TARGET_80387" 2927{ 2928 if (STACK_TOP_P (operands[0])) 2929 return "fxch\t%1"; 2930 else 2931 return "fxch\t%0"; 2932} 2933 [(set_attr "type" "fxch") 2934 (set_attr "mode" "XF")]) 2935 2936(define_expand "movtf" 2937 [(set (match_operand:TF 0 "nonimmediate_operand" "") 2938 (match_operand:TF 1 "nonimmediate_operand" ""))] 2939 "TARGET_64BIT" 2940{ 2941 ix86_expand_move (TFmode, operands); 2942 DONE; 2943}) 2944 2945(define_insn "*movtf_internal" 2946 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm") 2947 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))] 2948 "TARGET_64BIT 2949 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 2950{ 2951 switch (which_alternative) 2952 { 2953 case 0: 2954 case 1: 2955 return "#"; 2956 case 2: 2957 if (get_attr_mode (insn) == MODE_V4SF) 2958 return "xorps\t%0, %0"; 2959 else 2960 return "pxor\t%0, %0"; 2961 case 3: 2962 case 4: 2963 if (get_attr_mode (insn) == MODE_V4SF) 2964 return "movaps\t{%1, %0|%0, %1}"; 2965 else 2966 return "movdqa\t{%1, %0|%0, %1}"; 2967 default: 2968 gcc_unreachable (); 2969 } 2970} 2971 [(set_attr "type" "*,*,sselog1,ssemov,ssemov") 2972 (set (attr "mode") 2973 (cond [(eq_attr "alternative" "2,3") 2974 (if_then_else 2975 (ne (symbol_ref "optimize_size") 2976 (const_int 0)) 2977 (const_string "V4SF") 2978 (const_string "TI")) 2979 (eq_attr "alternative" "4") 2980 (if_then_else 2981 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") 2982 (const_int 0)) 2983 (ne (symbol_ref "optimize_size") 2984 (const_int 0))) 2985 (const_string "V4SF") 2986 (const_string "TI"))] 2987 (const_string "DI")))]) 2988 2989(define_split 2990 [(set (match_operand:TF 0 "nonimmediate_operand" "") 2991 (match_operand:TF 1 "general_operand" ""))] 2992 "reload_completed && !SSE_REG_P (operands[0]) 2993 && !SSE_REG_P (operands[1])" 2994 [(const_int 0)] 2995 "ix86_split_long_move (operands); DONE;") 2996 2997;; Zero extension instructions 2998 2999(define_expand "zero_extendhisi2" 3000 [(set (match_operand:SI 0 "register_operand" "") 3001 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 3002 "" 3003{ 3004 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) 3005 { 3006 operands[1] = force_reg (HImode, operands[1]); 3007 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1])); 3008 DONE; 3009 } 3010}) 3011 3012(define_insn "zero_extendhisi2_and" 3013 [(set (match_operand:SI 0 "register_operand" "=r") 3014 (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))) 3015 (clobber (reg:CC FLAGS_REG))] 3016 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 3017 "#" 3018 [(set_attr "type" "alu1") 3019 (set_attr "mode" "SI")]) 3020 3021(define_split 3022 [(set (match_operand:SI 0 "register_operand" "") 3023 (zero_extend:SI (match_operand:HI 1 "register_operand" ""))) 3024 (clobber (reg:CC FLAGS_REG))] 3025 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 3026 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535))) 3027 (clobber (reg:CC FLAGS_REG))])] 3028 "") 3029 3030(define_insn "*zero_extendhisi2_movzwl" 3031 [(set (match_operand:SI 0 "register_operand" "=r") 3032 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3033 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" 3034 "movz{wl|x}\t{%1, %0|%0, %1}" 3035 [(set_attr "type" "imovx") 3036 (set_attr "mode" "SI")]) 3037 3038(define_expand "zero_extendqihi2" 3039 [(parallel 3040 [(set (match_operand:HI 0 "register_operand" "") 3041 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) 3042 (clobber (reg:CC FLAGS_REG))])] 3043 "" 3044 "") 3045 3046(define_insn "*zero_extendqihi2_and" 3047 [(set (match_operand:HI 0 "register_operand" "=r,?&q") 3048 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) 3049 (clobber (reg:CC FLAGS_REG))] 3050 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 3051 "#" 3052 [(set_attr "type" "alu1") 3053 (set_attr "mode" "HI")]) 3054 3055(define_insn "*zero_extendqihi2_movzbw_and" 3056 [(set (match_operand:HI 0 "register_operand" "=r,r") 3057 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) 3058 (clobber (reg:CC FLAGS_REG))] 3059 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" 3060 "#" 3061 [(set_attr "type" "imovx,alu1") 3062 (set_attr "mode" "HI")]) 3063 3064; zero extend to SImode here to avoid partial register stalls 3065(define_insn "*zero_extendqihi2_movzbl" 3066 [(set (match_operand:HI 0 "register_operand" "=r") 3067 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3068 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed" 3069 "movz{bl|x}\t{%1, %k0|%k0, %k1}" 3070 [(set_attr "type" "imovx") 3071 (set_attr "mode" "SI")]) 3072 3073;; For the movzbw case strip only the clobber 3074(define_split 3075 [(set (match_operand:HI 0 "register_operand" "") 3076 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) 3077 (clobber (reg:CC FLAGS_REG))] 3078 "reload_completed 3079 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) 3080 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" 3081 [(set (match_operand:HI 0 "register_operand" "") 3082 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]) 3083 3084;; When source and destination does not overlap, clear destination 3085;; first and then do the movb 3086(define_split 3087 [(set (match_operand:HI 0 "register_operand" "") 3088 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) 3089 (clobber (reg:CC FLAGS_REG))] 3090 "reload_completed 3091 && ANY_QI_REG_P (operands[0]) 3092 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) 3093 && !reg_overlap_mentioned_p (operands[0], operands[1])" 3094 [(set (match_dup 0) (const_int 0)) 3095 (set (strict_low_part (match_dup 2)) (match_dup 1))] 3096 "operands[2] = gen_lowpart (QImode, operands[0]);") 3097 3098;; Rest is handled by single and. 3099(define_split 3100 [(set (match_operand:HI 0 "register_operand" "") 3101 (zero_extend:HI (match_operand:QI 1 "register_operand" ""))) 3102 (clobber (reg:CC FLAGS_REG))] 3103 "reload_completed 3104 && true_regnum (operands[0]) == true_regnum (operands[1])" 3105 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255))) 3106 (clobber (reg:CC FLAGS_REG))])] 3107 "") 3108 3109(define_expand "zero_extendqisi2" 3110 [(parallel 3111 [(set (match_operand:SI 0 "register_operand" "") 3112 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) 3113 (clobber (reg:CC FLAGS_REG))])] 3114 "" 3115 "") 3116 3117(define_insn "*zero_extendqisi2_and" 3118 [(set (match_operand:SI 0 "register_operand" "=r,?&q") 3119 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) 3120 (clobber (reg:CC FLAGS_REG))] 3121 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 3122 "#" 3123 [(set_attr "type" "alu1") 3124 (set_attr "mode" "SI")]) 3125 3126(define_insn "*zero_extendqisi2_movzbw_and" 3127 [(set (match_operand:SI 0 "register_operand" "=r,r") 3128 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) 3129 (clobber (reg:CC FLAGS_REG))] 3130 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" 3131 "#" 3132 [(set_attr "type" "imovx,alu1") 3133 (set_attr "mode" "SI")]) 3134 3135(define_insn "*zero_extendqisi2_movzbw" 3136 [(set (match_operand:SI 0 "register_operand" "=r") 3137 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3138 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed" 3139 "movz{bl|x}\t{%1, %0|%0, %1}" 3140 [(set_attr "type" "imovx") 3141 (set_attr "mode" "SI")]) 3142 3143;; For the movzbl case strip only the clobber 3144(define_split 3145 [(set (match_operand:SI 0 "register_operand" "") 3146 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) 3147 (clobber (reg:CC FLAGS_REG))] 3148 "reload_completed 3149 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) 3150 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" 3151 [(set (match_dup 0) 3152 (zero_extend:SI (match_dup 1)))]) 3153 3154;; When source and destination does not overlap, clear destination 3155;; first and then do the movb 3156(define_split 3157 [(set (match_operand:SI 0 "register_operand" "") 3158 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) 3159 (clobber (reg:CC FLAGS_REG))] 3160 "reload_completed 3161 && ANY_QI_REG_P (operands[0]) 3162 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM) 3163 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) 3164 && !reg_overlap_mentioned_p (operands[0], operands[1])" 3165 [(set (match_dup 0) (const_int 0)) 3166 (set (strict_low_part (match_dup 2)) (match_dup 1))] 3167 "operands[2] = gen_lowpart (QImode, operands[0]);") 3168 3169;; Rest is handled by single and. 3170(define_split 3171 [(set (match_operand:SI 0 "register_operand" "") 3172 (zero_extend:SI (match_operand:QI 1 "register_operand" ""))) 3173 (clobber (reg:CC FLAGS_REG))] 3174 "reload_completed 3175 && true_regnum (operands[0]) == true_regnum (operands[1])" 3176 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255))) 3177 (clobber (reg:CC FLAGS_REG))])] 3178 "") 3179 3180;; %%% Kill me once multi-word ops are sane. 3181(define_expand "zero_extendsidi2" 3182 [(set (match_operand:DI 0 "register_operand" "=r") 3183 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))] 3184 "" 3185 "if (!TARGET_64BIT) 3186 { 3187 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1])); 3188 DONE; 3189 } 3190 ") 3191 3192(define_insn "zero_extendsidi2_32" 3193 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y") 3194 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm"))) 3195 (clobber (reg:CC FLAGS_REG))] 3196 "!TARGET_64BIT" 3197 "@ 3198 # 3199 # 3200 # 3201 movd\t{%1, %0|%0, %1} 3202 movd\t{%1, %0|%0, %1}" 3203 [(set_attr "mode" "SI,SI,SI,DI,TI") 3204 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")]) 3205 3206(define_insn "zero_extendsidi2_rex64" 3207 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y") 3208 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))] 3209 "TARGET_64BIT" 3210 "@ 3211 mov\t{%k1, %k0|%k0, %k1} 3212 # 3213 movd\t{%1, %0|%0, %1} 3214 movd\t{%1, %0|%0, %1}" 3215 [(set_attr "type" "imovx,imov,mmxmov,ssemov") 3216 (set_attr "mode" "SI,DI,SI,SI")]) 3217 3218(define_split 3219 [(set (match_operand:DI 0 "memory_operand" "") 3220 (zero_extend:DI (match_dup 0)))] 3221 "TARGET_64BIT" 3222 [(set (match_dup 4) (const_int 0))] 3223 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3224 3225(define_split 3226 [(set (match_operand:DI 0 "register_operand" "") 3227 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) 3228 (clobber (reg:CC FLAGS_REG))] 3229 "!TARGET_64BIT && reload_completed 3230 && true_regnum (operands[0]) == true_regnum (operands[1])" 3231 [(set (match_dup 4) (const_int 0))] 3232 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3233 3234(define_split 3235 [(set (match_operand:DI 0 "nonimmediate_operand" "") 3236 (zero_extend:DI (match_operand:SI 1 "general_operand" ""))) 3237 (clobber (reg:CC FLAGS_REG))] 3238 "!TARGET_64BIT && reload_completed 3239 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])" 3240 [(set (match_dup 3) (match_dup 1)) 3241 (set (match_dup 4) (const_int 0))] 3242 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3243 3244(define_insn "zero_extendhidi2" 3245 [(set (match_operand:DI 0 "register_operand" "=r") 3246 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3247 "TARGET_64BIT" 3248 "movz{wl|x}\t{%1, %k0|%k0, %1}" 3249 [(set_attr "type" "imovx") 3250 (set_attr "mode" "DI")]) 3251 3252(define_insn "zero_extendqidi2" 3253 [(set (match_operand:DI 0 "register_operand" "=r") 3254 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))] 3255 "TARGET_64BIT" 3256 "movz{bl|x}\t{%1, %k0|%k0, %1}" 3257 [(set_attr "type" "imovx") 3258 (set_attr "mode" "DI")]) 3259 3260;; Sign extension instructions 3261 3262(define_expand "extendsidi2" 3263 [(parallel [(set (match_operand:DI 0 "register_operand" "") 3264 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3265 (clobber (reg:CC FLAGS_REG)) 3266 (clobber (match_scratch:SI 2 ""))])] 3267 "" 3268{ 3269 if (TARGET_64BIT) 3270 { 3271 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1])); 3272 DONE; 3273 } 3274}) 3275 3276(define_insn "*extendsidi2_1" 3277 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o") 3278 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r"))) 3279 (clobber (reg:CC FLAGS_REG)) 3280 (clobber (match_scratch:SI 2 "=X,X,X,&r"))] 3281 "!TARGET_64BIT" 3282 "#") 3283 3284(define_insn "extendsidi2_rex64" 3285 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3286 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))] 3287 "TARGET_64BIT" 3288 "@ 3289 {cltq|cdqe} 3290 movs{lq|x}\t{%1,%0|%0, %1}" 3291 [(set_attr "type" "imovx") 3292 (set_attr "mode" "DI") 3293 (set_attr "prefix_0f" "0") 3294 (set_attr "modrm" "0,1")]) 3295 3296(define_insn "extendhidi2" 3297 [(set (match_operand:DI 0 "register_operand" "=r") 3298 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3299 "TARGET_64BIT" 3300 "movs{wq|x}\t{%1,%0|%0, %1}" 3301 [(set_attr "type" "imovx") 3302 (set_attr "mode" "DI")]) 3303 3304(define_insn "extendqidi2" 3305 [(set (match_operand:DI 0 "register_operand" "=r") 3306 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3307 "TARGET_64BIT" 3308 "movs{bq|x}\t{%1,%0|%0, %1}" 3309 [(set_attr "type" "imovx") 3310 (set_attr "mode" "DI")]) 3311 3312;; Extend to memory case when source register does die. 3313(define_split 3314 [(set (match_operand:DI 0 "memory_operand" "") 3315 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3316 (clobber (reg:CC FLAGS_REG)) 3317 (clobber (match_operand:SI 2 "register_operand" ""))] 3318 "(reload_completed 3319 && dead_or_set_p (insn, operands[1]) 3320 && !reg_mentioned_p (operands[1], operands[0]))" 3321 [(set (match_dup 3) (match_dup 1)) 3322 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) 3323 (clobber (reg:CC FLAGS_REG))]) 3324 (set (match_dup 4) (match_dup 1))] 3325 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3326 3327;; Extend to memory case when source register does not die. 3328(define_split 3329 [(set (match_operand:DI 0 "memory_operand" "") 3330 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3331 (clobber (reg:CC FLAGS_REG)) 3332 (clobber (match_operand:SI 2 "register_operand" ""))] 3333 "reload_completed" 3334 [(const_int 0)] 3335{ 3336 split_di (&operands[0], 1, &operands[3], &operands[4]); 3337 3338 emit_move_insn (operands[3], operands[1]); 3339 3340 /* Generate a cltd if possible and doing so it profitable. */ 3341 if (true_regnum (operands[1]) == 0 3342 && true_regnum (operands[2]) == 1 3343 && (optimize_size || TARGET_USE_CLTD)) 3344 { 3345 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31))); 3346 } 3347 else 3348 { 3349 emit_move_insn (operands[2], operands[1]); 3350 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31))); 3351 } 3352 emit_move_insn (operands[4], operands[2]); 3353 DONE; 3354}) 3355 3356;; Extend to register case. Optimize case where source and destination 3357;; registers match and cases where we can use cltd. 3358(define_split 3359 [(set (match_operand:DI 0 "register_operand" "") 3360 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3361 (clobber (reg:CC FLAGS_REG)) 3362 (clobber (match_scratch:SI 2 ""))] 3363 "reload_completed" 3364 [(const_int 0)] 3365{ 3366 split_di (&operands[0], 1, &operands[3], &operands[4]); 3367 3368 if (true_regnum (operands[3]) != true_regnum (operands[1])) 3369 emit_move_insn (operands[3], operands[1]); 3370 3371 /* Generate a cltd if possible and doing so it profitable. */ 3372 if (true_regnum (operands[3]) == 0 3373 && (optimize_size || TARGET_USE_CLTD)) 3374 { 3375 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31))); 3376 DONE; 3377 } 3378 3379 if (true_regnum (operands[4]) != true_regnum (operands[1])) 3380 emit_move_insn (operands[4], operands[1]); 3381 3382 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31))); 3383 DONE; 3384}) 3385 3386(define_insn "extendhisi2" 3387 [(set (match_operand:SI 0 "register_operand" "=*a,r") 3388 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))] 3389 "" 3390{ 3391 switch (get_attr_prefix_0f (insn)) 3392 { 3393 case 0: 3394 return "{cwtl|cwde}"; 3395 default: 3396 return "movs{wl|x}\t{%1,%0|%0, %1}"; 3397 } 3398} 3399 [(set_attr "type" "imovx") 3400 (set_attr "mode" "SI") 3401 (set (attr "prefix_0f") 3402 ;; movsx is short decodable while cwtl is vector decoded. 3403 (if_then_else (and (eq_attr "cpu" "!k6") 3404 (eq_attr "alternative" "0")) 3405 (const_string "0") 3406 (const_string "1"))) 3407 (set (attr "modrm") 3408 (if_then_else (eq_attr "prefix_0f" "0") 3409 (const_string "0") 3410 (const_string "1")))]) 3411 3412(define_insn "*extendhisi2_zext" 3413 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3414 (zero_extend:DI 3415 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))] 3416 "TARGET_64BIT" 3417{ 3418 switch (get_attr_prefix_0f (insn)) 3419 { 3420 case 0: 3421 return "{cwtl|cwde}"; 3422 default: 3423 return "movs{wl|x}\t{%1,%k0|%k0, %1}"; 3424 } 3425} 3426 [(set_attr "type" "imovx") 3427 (set_attr "mode" "SI") 3428 (set (attr "prefix_0f") 3429 ;; movsx is short decodable while cwtl is vector decoded. 3430 (if_then_else (and (eq_attr "cpu" "!k6") 3431 (eq_attr "alternative" "0")) 3432 (const_string "0") 3433 (const_string "1"))) 3434 (set (attr "modrm") 3435 (if_then_else (eq_attr "prefix_0f" "0") 3436 (const_string "0") 3437 (const_string "1")))]) 3438 3439(define_insn "extendqihi2" 3440 [(set (match_operand:HI 0 "register_operand" "=*a,r") 3441 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))] 3442 "" 3443{ 3444 switch (get_attr_prefix_0f (insn)) 3445 { 3446 case 0: 3447 return "{cbtw|cbw}"; 3448 default: 3449 return "movs{bw|x}\t{%1,%0|%0, %1}"; 3450 } 3451} 3452 [(set_attr "type" "imovx") 3453 (set_attr "mode" "HI") 3454 (set (attr "prefix_0f") 3455 ;; movsx is short decodable while cwtl is vector decoded. 3456 (if_then_else (and (eq_attr "cpu" "!k6") 3457 (eq_attr "alternative" "0")) 3458 (const_string "0") 3459 (const_string "1"))) 3460 (set (attr "modrm") 3461 (if_then_else (eq_attr "prefix_0f" "0") 3462 (const_string "0") 3463 (const_string "1")))]) 3464 3465(define_insn "extendqisi2" 3466 [(set (match_operand:SI 0 "register_operand" "=r") 3467 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3468 "" 3469 "movs{bl|x}\t{%1,%0|%0, %1}" 3470 [(set_attr "type" "imovx") 3471 (set_attr "mode" "SI")]) 3472 3473(define_insn "*extendqisi2_zext" 3474 [(set (match_operand:DI 0 "register_operand" "=r") 3475 (zero_extend:DI 3476 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))] 3477 "TARGET_64BIT" 3478 "movs{bl|x}\t{%1,%k0|%k0, %1}" 3479 [(set_attr "type" "imovx") 3480 (set_attr "mode" "SI")]) 3481 3482;; Conversions between float and double. 3483 3484;; These are all no-ops in the model used for the 80387. So just 3485;; emit moves. 3486 3487;; %%% Kill these when call knows how to work out a DFmode push earlier. 3488(define_insn "*dummy_extendsfdf2" 3489 [(set (match_operand:DF 0 "push_operand" "=<") 3490 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))] 3491 "0" 3492 "#") 3493 3494(define_split 3495 [(set (match_operand:DF 0 "push_operand" "") 3496 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))] 3497 "!TARGET_64BIT" 3498 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 3499 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))]) 3500 3501(define_split 3502 [(set (match_operand:DF 0 "push_operand" "") 3503 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))] 3504 "TARGET_64BIT" 3505 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 3506 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))]) 3507 3508(define_insn "*dummy_extendsfxf2" 3509 [(set (match_operand:XF 0 "push_operand" "=<") 3510 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))] 3511 "0" 3512 "#") 3513 3514(define_split 3515 [(set (match_operand:XF 0 "push_operand" "") 3516 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))] 3517 "" 3518 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2))) 3519 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))] 3520 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3521 3522(define_split 3523 [(set (match_operand:XF 0 "push_operand" "") 3524 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))] 3525 "TARGET_64BIT" 3526 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2))) 3527 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))] 3528 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3529 3530(define_split 3531 [(set (match_operand:XF 0 "push_operand" "") 3532 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))] 3533 "" 3534 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2))) 3535 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))] 3536 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3537 3538(define_split 3539 [(set (match_operand:XF 0 "push_operand" "") 3540 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))] 3541 "TARGET_64BIT" 3542 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2))) 3543 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))] 3544 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3545 3546(define_expand "extendsfdf2" 3547 [(set (match_operand:DF 0 "nonimmediate_operand" "") 3548 (float_extend:DF (match_operand:SF 1 "general_operand" "")))] 3549 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 3550{ 3551 /* ??? Needed for compress_float_constant since all fp constants 3552 are LEGITIMATE_CONSTANT_P. */ 3553 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3554 { 3555 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387) 3556 && standard_80387_constant_p (operands[1]) > 0) 3557 { 3558 operands[1] = simplify_const_unary_operation 3559 (FLOAT_EXTEND, DFmode, operands[1], SFmode); 3560 emit_move_insn_1 (operands[0], operands[1]); 3561 DONE; 3562 } 3563 operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 3564 } 3565 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 3566 operands[1] = force_reg (SFmode, operands[1]); 3567}) 3568 3569(define_insn "*extendsfdf2_mixed" 3570 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y") 3571 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))] 3572 "TARGET_SSE2 && TARGET_MIX_SSE_I387 3573 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3574{ 3575 switch (which_alternative) 3576 { 3577 case 0: 3578 return output_387_reg_move (insn, operands); 3579 3580 case 1: 3581 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3582 return "fstp%z0\t%y0"; 3583 else 3584 return "fst%z0\t%y0"; 3585 3586 case 2: 3587 return "cvtss2sd\t{%1, %0|%0, %1}"; 3588 3589 default: 3590 gcc_unreachable (); 3591 } 3592} 3593 [(set_attr "type" "fmov,fmov,ssecvt") 3594 (set_attr "mode" "SF,XF,DF")]) 3595 3596(define_insn "*extendsfdf2_sse" 3597 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y") 3598 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))] 3599 "TARGET_SSE2 && TARGET_SSE_MATH 3600 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3601 "cvtss2sd\t{%1, %0|%0, %1}" 3602 [(set_attr "type" "ssecvt") 3603 (set_attr "mode" "DF")]) 3604 3605(define_insn "*extendsfdf2_i387" 3606 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m") 3607 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 3608 "TARGET_80387 3609 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3610{ 3611 switch (which_alternative) 3612 { 3613 case 0: 3614 return output_387_reg_move (insn, operands); 3615 3616 case 1: 3617 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3618 return "fstp%z0\t%y0"; 3619 else 3620 return "fst%z0\t%y0"; 3621 3622 default: 3623 gcc_unreachable (); 3624 } 3625} 3626 [(set_attr "type" "fmov") 3627 (set_attr "mode" "SF,XF")]) 3628 3629(define_expand "extendsfxf2" 3630 [(set (match_operand:XF 0 "nonimmediate_operand" "") 3631 (float_extend:XF (match_operand:SF 1 "general_operand" "")))] 3632 "TARGET_80387" 3633{ 3634 /* ??? Needed for compress_float_constant since all fp constants 3635 are LEGITIMATE_CONSTANT_P. */ 3636 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3637 { 3638 if (standard_80387_constant_p (operands[1]) > 0) 3639 { 3640 operands[1] = simplify_const_unary_operation 3641 (FLOAT_EXTEND, XFmode, operands[1], SFmode); 3642 emit_move_insn_1 (operands[0], operands[1]); 3643 DONE; 3644 } 3645 operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 3646 } 3647 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 3648 operands[1] = force_reg (SFmode, operands[1]); 3649}) 3650 3651(define_insn "*extendsfxf2_i387" 3652 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 3653 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 3654 "TARGET_80387 3655 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3656{ 3657 switch (which_alternative) 3658 { 3659 case 0: 3660 return output_387_reg_move (insn, operands); 3661 3662 case 1: 3663 /* There is no non-popping store to memory for XFmode. So if 3664 we need one, follow the store with a load. */ 3665 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3666 return "fstp%z0\t%y0"; 3667 else 3668 return "fstp%z0\t%y0\n\tfld%z0\t%y0"; 3669 3670 default: 3671 gcc_unreachable (); 3672 } 3673} 3674 [(set_attr "type" "fmov") 3675 (set_attr "mode" "SF,XF")]) 3676 3677(define_expand "extenddfxf2" 3678 [(set (match_operand:XF 0 "nonimmediate_operand" "") 3679 (float_extend:XF (match_operand:DF 1 "general_operand" "")))] 3680 "TARGET_80387" 3681{ 3682 /* ??? Needed for compress_float_constant since all fp constants 3683 are LEGITIMATE_CONSTANT_P. */ 3684 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3685 { 3686 if (standard_80387_constant_p (operands[1]) > 0) 3687 { 3688 operands[1] = simplify_const_unary_operation 3689 (FLOAT_EXTEND, XFmode, operands[1], DFmode); 3690 emit_move_insn_1 (operands[0], operands[1]); 3691 DONE; 3692 } 3693 operands[1] = validize_mem (force_const_mem (DFmode, operands[1])); 3694 } 3695 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 3696 operands[1] = force_reg (DFmode, operands[1]); 3697}) 3698 3699(define_insn "*extenddfxf2_i387" 3700 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 3701 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))] 3702 "TARGET_80387 3703 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3704{ 3705 switch (which_alternative) 3706 { 3707 case 0: 3708 return output_387_reg_move (insn, operands); 3709 3710 case 1: 3711 /* There is no non-popping store to memory for XFmode. So if 3712 we need one, follow the store with a load. */ 3713 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3714 return "fstp%z0\t%y0\n\tfld%z0\t%y0"; 3715 else 3716 return "fstp%z0\t%y0"; 3717 3718 default: 3719 gcc_unreachable (); 3720 } 3721} 3722 [(set_attr "type" "fmov") 3723 (set_attr "mode" "DF,XF")]) 3724 3725;; %%% This seems bad bad news. 3726;; This cannot output into an f-reg because there is no way to be sure 3727;; of truncating in that case. Otherwise this is just like a simple move 3728;; insn. So we pretend we can output to a reg in order to get better 3729;; register preferencing, but we really use a stack slot. 3730 3731;; Conversion from DFmode to SFmode. 3732 3733(define_expand "truncdfsf2" 3734 [(set (match_operand:SF 0 "nonimmediate_operand" "") 3735 (float_truncate:SF 3736 (match_operand:DF 1 "nonimmediate_operand" "")))] 3737 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 3738{ 3739 if (MEM_P (operands[0]) && MEM_P (operands[1])) 3740 operands[1] = force_reg (DFmode, operands[1]); 3741 3742 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387) 3743 ; 3744 else if (flag_unsafe_math_optimizations) 3745 ; 3746 else 3747 { 3748 rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL); 3749 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp)); 3750 DONE; 3751 } 3752}) 3753 3754(define_expand "truncdfsf2_with_temp" 3755 [(parallel [(set (match_operand:SF 0 "" "") 3756 (float_truncate:SF (match_operand:DF 1 "" ""))) 3757 (clobber (match_operand:SF 2 "" ""))])] 3758 "") 3759 3760(define_insn "*truncdfsf_fast_mixed" 3761 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y") 3762 (float_truncate:SF 3763 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))] 3764 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations" 3765{ 3766 switch (which_alternative) 3767 { 3768 case 0: 3769 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3770 return "fstp%z0\t%y0"; 3771 else 3772 return "fst%z0\t%y0"; 3773 case 1: 3774 return output_387_reg_move (insn, operands); 3775 case 2: 3776 return "cvtsd2ss\t{%1, %0|%0, %1}"; 3777 default: 3778 gcc_unreachable (); 3779 } 3780} 3781 [(set_attr "type" "fmov,fmov,ssecvt") 3782 (set_attr "mode" "SF")]) 3783 3784;; Yes, this one doesn't depend on flag_unsafe_math_optimizations, 3785;; because nothing we do here is unsafe. 3786(define_insn "*truncdfsf_fast_sse" 3787 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y") 3788 (float_truncate:SF 3789 (match_operand:DF 1 "nonimmediate_operand" "Ym")))] 3790 "TARGET_SSE2 && TARGET_SSE_MATH" 3791 "cvtsd2ss\t{%1, %0|%0, %1}" 3792 [(set_attr "type" "ssecvt") 3793 (set_attr "mode" "SF")]) 3794 3795(define_insn "*truncdfsf_fast_i387" 3796 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm") 3797 (float_truncate:SF 3798 (match_operand:DF 1 "nonimmediate_operand" "f")))] 3799 "TARGET_80387 && flag_unsafe_math_optimizations" 3800 "* return output_387_reg_move (insn, operands);" 3801 [(set_attr "type" "fmov") 3802 (set_attr "mode" "SF")]) 3803 3804(define_insn "*truncdfsf_mixed" 3805 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y") 3806 (float_truncate:SF 3807 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym"))) 3808 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))] 3809 "TARGET_MIX_SSE_I387" 3810{ 3811 switch (which_alternative) 3812 { 3813 case 0: 3814 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3815 return "fstp%z0\t%y0"; 3816 else 3817 return "fst%z0\t%y0"; 3818 case 1: 3819 return "#"; 3820 case 2: 3821 return "cvtsd2ss\t{%1, %0|%0, %1}"; 3822 default: 3823 gcc_unreachable (); 3824 } 3825} 3826 [(set_attr "type" "fmov,multi,ssecvt") 3827 (set_attr "unit" "*,i387,*") 3828 (set_attr "mode" "SF")]) 3829 3830(define_insn "*truncdfsf_i387" 3831 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r") 3832 (float_truncate:SF 3833 (match_operand:DF 1 "nonimmediate_operand" "f,f"))) 3834 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))] 3835 "TARGET_80387" 3836{ 3837 switch (which_alternative) 3838 { 3839 case 0: 3840 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3841 return "fstp%z0\t%y0"; 3842 else 3843 return "fst%z0\t%y0"; 3844 case 1: 3845 return "#"; 3846 default: 3847 gcc_unreachable (); 3848 } 3849} 3850 [(set_attr "type" "fmov,multi") 3851 (set_attr "unit" "*,i387") 3852 (set_attr "mode" "SF")]) 3853 3854(define_insn "*truncdfsf2_i387_1" 3855 [(set (match_operand:SF 0 "memory_operand" "=m") 3856 (float_truncate:SF 3857 (match_operand:DF 1 "register_operand" "f")))] 3858 "TARGET_80387 3859 && !(TARGET_SSE2 && TARGET_SSE_MATH) 3860 && !TARGET_MIX_SSE_I387" 3861{ 3862 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3863 return "fstp%z0\t%y0"; 3864 else 3865 return "fst%z0\t%y0"; 3866} 3867 [(set_attr "type" "fmov") 3868 (set_attr "mode" "SF")]) 3869 3870(define_split 3871 [(set (match_operand:SF 0 "register_operand" "") 3872 (float_truncate:SF 3873 (match_operand:DF 1 "fp_register_operand" ""))) 3874 (clobber (match_operand 2 "" ""))] 3875 "reload_completed" 3876 [(set (match_dup 2) (match_dup 1)) 3877 (set (match_dup 0) (match_dup 2))] 3878{ 3879 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1])); 3880}) 3881 3882;; Conversion from XFmode to SFmode. 3883 3884(define_expand "truncxfsf2" 3885 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") 3886 (float_truncate:SF 3887 (match_operand:XF 1 "register_operand" ""))) 3888 (clobber (match_dup 2))])] 3889 "TARGET_80387" 3890{ 3891 if (flag_unsafe_math_optimizations) 3892 { 3893 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode); 3894 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1])); 3895 if (reg != operands[0]) 3896 emit_move_insn (operands[0], reg); 3897 DONE; 3898 } 3899 else 3900 operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL); 3901}) 3902 3903(define_insn "*truncxfsf2_mixed" 3904 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x") 3905 (float_truncate:SF 3906 (match_operand:XF 1 "register_operand" "f,f,f,f"))) 3907 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))] 3908 "TARGET_MIX_SSE_I387" 3909{ 3910 gcc_assert (!which_alternative); 3911 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3912 return "fstp%z0\t%y0"; 3913 else 3914 return "fst%z0\t%y0"; 3915} 3916 [(set_attr "type" "fmov,multi,multi,multi") 3917 (set_attr "unit" "*,i387,i387,i387") 3918 (set_attr "mode" "SF")]) 3919 3920(define_insn "truncxfsf2_i387_noop" 3921 [(set (match_operand:SF 0 "register_operand" "=f") 3922 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))] 3923 "TARGET_80387 && flag_unsafe_math_optimizations" 3924{ 3925 return output_387_reg_move (insn, operands); 3926} 3927 [(set_attr "type" "fmov") 3928 (set_attr "mode" "SF")]) 3929 3930(define_insn "*truncxfsf2_i387" 3931 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r") 3932 (float_truncate:SF 3933 (match_operand:XF 1 "register_operand" "f,f,f"))) 3934 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))] 3935 "TARGET_80387" 3936{ 3937 gcc_assert (!which_alternative); 3938 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3939 return "fstp%z0\t%y0"; 3940 else 3941 return "fst%z0\t%y0"; 3942} 3943 [(set_attr "type" "fmov,multi,multi") 3944 (set_attr "unit" "*,i387,i387") 3945 (set_attr "mode" "SF")]) 3946 3947(define_insn "*truncxfsf2_i387_1" 3948 [(set (match_operand:SF 0 "memory_operand" "=m") 3949 (float_truncate:SF 3950 (match_operand:XF 1 "register_operand" "f")))] 3951 "TARGET_80387" 3952{ 3953 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3954 return "fstp%z0\t%y0"; 3955 else 3956 return "fst%z0\t%y0"; 3957} 3958 [(set_attr "type" "fmov") 3959 (set_attr "mode" "SF")]) 3960 3961(define_split 3962 [(set (match_operand:SF 0 "register_operand" "") 3963 (float_truncate:SF 3964 (match_operand:XF 1 "register_operand" ""))) 3965 (clobber (match_operand:SF 2 "memory_operand" ""))] 3966 "TARGET_80387 && reload_completed" 3967 [(set (match_dup 2) (float_truncate:SF (match_dup 1))) 3968 (set (match_dup 0) (match_dup 2))] 3969 "") 3970 3971(define_split 3972 [(set (match_operand:SF 0 "memory_operand" "") 3973 (float_truncate:SF 3974 (match_operand:XF 1 "register_operand" ""))) 3975 (clobber (match_operand:SF 2 "memory_operand" ""))] 3976 "TARGET_80387" 3977 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))] 3978 "") 3979 3980;; Conversion from XFmode to DFmode. 3981 3982(define_expand "truncxfdf2" 3983 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "") 3984 (float_truncate:DF 3985 (match_operand:XF 1 "register_operand" ""))) 3986 (clobber (match_dup 2))])] 3987 "TARGET_80387" 3988{ 3989 if (flag_unsafe_math_optimizations) 3990 { 3991 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode); 3992 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1])); 3993 if (reg != operands[0]) 3994 emit_move_insn (operands[0], reg); 3995 DONE; 3996 } 3997 else 3998 operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL); 3999}) 4000 4001(define_insn "*truncxfdf2_mixed" 4002 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y") 4003 (float_truncate:DF 4004 (match_operand:XF 1 "register_operand" "f,f,f,f"))) 4005 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))] 4006 "TARGET_SSE2 && TARGET_MIX_SSE_I387" 4007{ 4008 gcc_assert (!which_alternative); 4009 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 4010 return "fstp%z0\t%y0"; 4011 else 4012 return "fst%z0\t%y0"; 4013} 4014 [(set_attr "type" "fmov,multi,multi,multi") 4015 (set_attr "unit" "*,i387,i387,i387") 4016 (set_attr "mode" "DF")]) 4017 4018(define_insn "truncxfdf2_i387_noop" 4019 [(set (match_operand:DF 0 "register_operand" "=f") 4020 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))] 4021 "TARGET_80387 && flag_unsafe_math_optimizations" 4022{ 4023 return output_387_reg_move (insn, operands); 4024} 4025 [(set_attr "type" "fmov") 4026 (set_attr "mode" "DF")]) 4027 4028(define_insn "*truncxfdf2_i387" 4029 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r") 4030 (float_truncate:DF 4031 (match_operand:XF 1 "register_operand" "f,f,f"))) 4032 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))] 4033 "TARGET_80387" 4034{ 4035 gcc_assert (!which_alternative); 4036 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 4037 return "fstp%z0\t%y0"; 4038 else 4039 return "fst%z0\t%y0"; 4040} 4041 [(set_attr "type" "fmov,multi,multi") 4042 (set_attr "unit" "*,i387,i387") 4043 (set_attr "mode" "DF")]) 4044 4045(define_insn "*truncxfdf2_i387_1" 4046 [(set (match_operand:DF 0 "memory_operand" "=m") 4047 (float_truncate:DF 4048 (match_operand:XF 1 "register_operand" "f")))] 4049 "TARGET_80387" 4050{ 4051 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 4052 return "fstp%z0\t%y0"; 4053 else 4054 return "fst%z0\t%y0"; 4055} 4056 [(set_attr "type" "fmov") 4057 (set_attr "mode" "DF")]) 4058 4059(define_split 4060 [(set (match_operand:DF 0 "register_operand" "") 4061 (float_truncate:DF 4062 (match_operand:XF 1 "register_operand" ""))) 4063 (clobber (match_operand:DF 2 "memory_operand" ""))] 4064 "TARGET_80387 && reload_completed" 4065 [(set (match_dup 2) (float_truncate:DF (match_dup 1))) 4066 (set (match_dup 0) (match_dup 2))] 4067 "") 4068 4069(define_split 4070 [(set (match_operand:DF 0 "memory_operand" "") 4071 (float_truncate:DF 4072 (match_operand:XF 1 "register_operand" ""))) 4073 (clobber (match_operand:DF 2 "memory_operand" ""))] 4074 "TARGET_80387" 4075 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))] 4076 "") 4077 4078;; Signed conversion to DImode. 4079 4080(define_expand "fix_truncxfdi2" 4081 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 4082 (fix:DI (match_operand:XF 1 "register_operand" ""))) 4083 (clobber (reg:CC FLAGS_REG))])] 4084 "TARGET_80387" 4085{ 4086 if (TARGET_FISTTP) 4087 { 4088 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4089 DONE; 4090 } 4091}) 4092 4093(define_expand "fix_trunc<mode>di2" 4094 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 4095 (fix:DI (match_operand:SSEMODEF 1 "register_operand" ""))) 4096 (clobber (reg:CC FLAGS_REG))])] 4097 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))" 4098{ 4099 if (TARGET_FISTTP 4100 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4101 { 4102 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4103 DONE; 4104 } 4105 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)) 4106 { 4107 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode); 4108 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1])); 4109 if (out != operands[0]) 4110 emit_move_insn (operands[0], out); 4111 DONE; 4112 } 4113}) 4114 4115;; Signed conversion to SImode. 4116 4117(define_expand "fix_truncxfsi2" 4118 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4119 (fix:SI (match_operand:XF 1 "register_operand" ""))) 4120 (clobber (reg:CC FLAGS_REG))])] 4121 "TARGET_80387" 4122{ 4123 if (TARGET_FISTTP) 4124 { 4125 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4126 DONE; 4127 } 4128}) 4129 4130(define_expand "fix_trunc<mode>si2" 4131 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4132 (fix:SI (match_operand:SSEMODEF 1 "register_operand" ""))) 4133 (clobber (reg:CC FLAGS_REG))])] 4134 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)" 4135{ 4136 if (TARGET_FISTTP 4137 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4138 { 4139 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4140 DONE; 4141 } 4142 if (SSE_FLOAT_MODE_P (<MODE>mode)) 4143 { 4144 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode); 4145 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1])); 4146 if (out != operands[0]) 4147 emit_move_insn (operands[0], out); 4148 DONE; 4149 } 4150}) 4151 4152;; Signed conversion to HImode. 4153 4154(define_expand "fix_trunc<mode>hi2" 4155 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 4156 (fix:HI (match_operand:X87MODEF 1 "register_operand" ""))) 4157 (clobber (reg:CC FLAGS_REG))])] 4158 "TARGET_80387 4159 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))" 4160{ 4161 if (TARGET_FISTTP) 4162 { 4163 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1])); 4164 DONE; 4165 } 4166}) 4167 4168;; When SSE is available, it is always faster to use it! 4169(define_insn "fix_truncsfdi_sse" 4170 [(set (match_operand:DI 0 "register_operand" "=r,r") 4171 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))] 4172 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4173 "cvttss2si{q}\t{%1, %0|%0, %1}" 4174 [(set_attr "type" "sseicvt") 4175 (set_attr "mode" "SF") 4176 (set_attr "athlon_decode" "double,vector") 4177 (set_attr "amdfam10_decode" "double,double")]) 4178 4179(define_insn "fix_truncdfdi_sse" 4180 [(set (match_operand:DI 0 "register_operand" "=r,r") 4181 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))] 4182 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4183 "cvttsd2si{q}\t{%1, %0|%0, %1}" 4184 [(set_attr "type" "sseicvt") 4185 (set_attr "mode" "DF") 4186 (set_attr "athlon_decode" "double,vector") 4187 (set_attr "amdfam10_decode" "double,double")]) 4188 4189(define_insn "fix_truncsfsi_sse" 4190 [(set (match_operand:SI 0 "register_operand" "=r,r") 4191 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))] 4192 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4193 "cvttss2si\t{%1, %0|%0, %1}" 4194 [(set_attr "type" "sseicvt") 4195 (set_attr "mode" "DF") 4196 (set_attr "athlon_decode" "double,vector") 4197 (set_attr "amdfam10_decode" "double,double")]) 4198 4199(define_insn "fix_truncdfsi_sse" 4200 [(set (match_operand:SI 0 "register_operand" "=r,r") 4201 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))] 4202 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4203 "cvttsd2si\t{%1, %0|%0, %1}" 4204 [(set_attr "type" "sseicvt") 4205 (set_attr "mode" "DF") 4206 (set_attr "athlon_decode" "double,vector") 4207 (set_attr "amdfam10_decode" "double,double")]) 4208 4209;; Avoid vector decoded forms of the instruction. 4210(define_peephole2 4211 [(match_scratch:DF 2 "Y") 4212 (set (match_operand:SSEMODEI24 0 "register_operand" "") 4213 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))] 4214 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size" 4215 [(set (match_dup 2) (match_dup 1)) 4216 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))] 4217 "") 4218 4219(define_peephole2 4220 [(match_scratch:SF 2 "x") 4221 (set (match_operand:SSEMODEI24 0 "register_operand" "") 4222 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))] 4223 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size" 4224 [(set (match_dup 2) (match_dup 1)) 4225 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))] 4226 "") 4227 4228(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1" 4229 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 4230 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))] 4231 "TARGET_FISTTP 4232 && FLOAT_MODE_P (GET_MODE (operands[1])) 4233 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4234 && (TARGET_64BIT || <MODE>mode != DImode)) 4235 && TARGET_SSE_MATH) 4236 && !(reload_completed || reload_in_progress)" 4237 "#" 4238 "&& 1" 4239 [(const_int 0)] 4240{ 4241 if (memory_operand (operands[0], VOIDmode)) 4242 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1])); 4243 else 4244 { 4245 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4246 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0], 4247 operands[1], 4248 operands[2])); 4249 } 4250 DONE; 4251} 4252 [(set_attr "type" "fisttp") 4253 (set_attr "mode" "<MODE>")]) 4254 4255(define_insn "fix_trunc<mode>_i387_fisttp" 4256 [(set (match_operand:X87MODEI 0 "memory_operand" "=m") 4257 (fix:X87MODEI (match_operand 1 "register_operand" "f"))) 4258 (clobber (match_scratch:XF 2 "=&1f"))] 4259 "TARGET_FISTTP 4260 && FLOAT_MODE_P (GET_MODE (operands[1])) 4261 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4262 && (TARGET_64BIT || <MODE>mode != DImode)) 4263 && TARGET_SSE_MATH)" 4264 "* return output_fix_trunc (insn, operands, 1);" 4265 [(set_attr "type" "fisttp") 4266 (set_attr "mode" "<MODE>")]) 4267 4268(define_insn "fix_trunc<mode>_i387_fisttp_with_temp" 4269 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 4270 (fix:X87MODEI (match_operand 1 "register_operand" "f,f"))) 4271 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m")) 4272 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 4273 "TARGET_FISTTP 4274 && FLOAT_MODE_P (GET_MODE (operands[1])) 4275 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4276 && (TARGET_64BIT || <MODE>mode != DImode)) 4277 && TARGET_SSE_MATH)" 4278 "#" 4279 [(set_attr "type" "fisttp") 4280 (set_attr "mode" "<MODE>")]) 4281 4282(define_split 4283 [(set (match_operand:X87MODEI 0 "register_operand" "") 4284 (fix:X87MODEI (match_operand 1 "register_operand" ""))) 4285 (clobber (match_operand:X87MODEI 2 "memory_operand" "")) 4286 (clobber (match_scratch 3 ""))] 4287 "reload_completed" 4288 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1))) 4289 (clobber (match_dup 3))]) 4290 (set (match_dup 0) (match_dup 2))] 4291 "") 4292 4293(define_split 4294 [(set (match_operand:X87MODEI 0 "memory_operand" "") 4295 (fix:X87MODEI (match_operand 1 "register_operand" ""))) 4296 (clobber (match_operand:X87MODEI 2 "memory_operand" "")) 4297 (clobber (match_scratch 3 ""))] 4298 "reload_completed" 4299 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1))) 4300 (clobber (match_dup 3))])] 4301 "") 4302 4303;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description 4304;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control 4305;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG 4306;; clobbering insns can be used. Look at emit_i387_cw_initialization () 4307;; function in i386.c. 4308(define_insn_and_split "*fix_trunc<mode>_i387_1" 4309 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 4310 (fix:X87MODEI (match_operand 1 "register_operand" "f,f"))) 4311 (clobber (reg:CC FLAGS_REG))] 4312 "TARGET_80387 && !TARGET_FISTTP 4313 && FLOAT_MODE_P (GET_MODE (operands[1])) 4314 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4315 && (TARGET_64BIT || <MODE>mode != DImode)) 4316 && !(reload_completed || reload_in_progress)" 4317 "#" 4318 "&& 1" 4319 [(const_int 0)] 4320{ 4321 ix86_optimize_mode_switching[I387_TRUNC] = 1; 4322 4323 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 4324 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 4325 if (memory_operand (operands[0], VOIDmode)) 4326 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1], 4327 operands[2], operands[3])); 4328 else 4329 { 4330 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4331 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1], 4332 operands[2], operands[3], 4333 operands[4])); 4334 } 4335 DONE; 4336} 4337 [(set_attr "type" "fistp") 4338 (set_attr "i387_cw" "trunc") 4339 (set_attr "mode" "<MODE>")]) 4340 4341(define_insn "fix_truncdi_i387" 4342 [(set (match_operand:DI 0 "memory_operand" "=m") 4343 (fix:DI (match_operand 1 "register_operand" "f"))) 4344 (use (match_operand:HI 2 "memory_operand" "m")) 4345 (use (match_operand:HI 3 "memory_operand" "m")) 4346 (clobber (match_scratch:XF 4 "=&1f"))] 4347 "TARGET_80387 && !TARGET_FISTTP 4348 && FLOAT_MODE_P (GET_MODE (operands[1])) 4349 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4350 "* return output_fix_trunc (insn, operands, 0);" 4351 [(set_attr "type" "fistp") 4352 (set_attr "i387_cw" "trunc") 4353 (set_attr "mode" "DI")]) 4354 4355(define_insn "fix_truncdi_i387_with_temp" 4356 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 4357 (fix:DI (match_operand 1 "register_operand" "f,f"))) 4358 (use (match_operand:HI 2 "memory_operand" "m,m")) 4359 (use (match_operand:HI 3 "memory_operand" "m,m")) 4360 (clobber (match_operand:DI 4 "memory_operand" "=m,m")) 4361 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 4362 "TARGET_80387 && !TARGET_FISTTP 4363 && FLOAT_MODE_P (GET_MODE (operands[1])) 4364 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4365 "#" 4366 [(set_attr "type" "fistp") 4367 (set_attr "i387_cw" "trunc") 4368 (set_attr "mode" "DI")]) 4369 4370(define_split 4371 [(set (match_operand:DI 0 "register_operand" "") 4372 (fix:DI (match_operand 1 "register_operand" ""))) 4373 (use (match_operand:HI 2 "memory_operand" "")) 4374 (use (match_operand:HI 3 "memory_operand" "")) 4375 (clobber (match_operand:DI 4 "memory_operand" "")) 4376 (clobber (match_scratch 5 ""))] 4377 "reload_completed" 4378 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1))) 4379 (use (match_dup 2)) 4380 (use (match_dup 3)) 4381 (clobber (match_dup 5))]) 4382 (set (match_dup 0) (match_dup 4))] 4383 "") 4384 4385(define_split 4386 [(set (match_operand:DI 0 "memory_operand" "") 4387 (fix:DI (match_operand 1 "register_operand" ""))) 4388 (use (match_operand:HI 2 "memory_operand" "")) 4389 (use (match_operand:HI 3 "memory_operand" "")) 4390 (clobber (match_operand:DI 4 "memory_operand" "")) 4391 (clobber (match_scratch 5 ""))] 4392 "reload_completed" 4393 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1))) 4394 (use (match_dup 2)) 4395 (use (match_dup 3)) 4396 (clobber (match_dup 5))])] 4397 "") 4398 4399(define_insn "fix_trunc<mode>_i387" 4400 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 4401 (fix:X87MODEI12 (match_operand 1 "register_operand" "f"))) 4402 (use (match_operand:HI 2 "memory_operand" "m")) 4403 (use (match_operand:HI 3 "memory_operand" "m"))] 4404 "TARGET_80387 && !TARGET_FISTTP 4405 && FLOAT_MODE_P (GET_MODE (operands[1])) 4406 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4407 "* return output_fix_trunc (insn, operands, 0);" 4408 [(set_attr "type" "fistp") 4409 (set_attr "i387_cw" "trunc") 4410 (set_attr "mode" "<MODE>")]) 4411 4412(define_insn "fix_trunc<mode>_i387_with_temp" 4413 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") 4414 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f"))) 4415 (use (match_operand:HI 2 "memory_operand" "m,m")) 4416 (use (match_operand:HI 3 "memory_operand" "m,m")) 4417 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))] 4418 "TARGET_80387 && !TARGET_FISTTP 4419 && FLOAT_MODE_P (GET_MODE (operands[1])) 4420 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4421 "#" 4422 [(set_attr "type" "fistp") 4423 (set_attr "i387_cw" "trunc") 4424 (set_attr "mode" "<MODE>")]) 4425 4426(define_split 4427 [(set (match_operand:X87MODEI12 0 "register_operand" "") 4428 (fix:X87MODEI12 (match_operand 1 "register_operand" ""))) 4429 (use (match_operand:HI 2 "memory_operand" "")) 4430 (use (match_operand:HI 3 "memory_operand" "")) 4431 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 4432 "reload_completed" 4433 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1))) 4434 (use (match_dup 2)) 4435 (use (match_dup 3))]) 4436 (set (match_dup 0) (match_dup 4))] 4437 "") 4438 4439(define_split 4440 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 4441 (fix:X87MODEI12 (match_operand 1 "register_operand" ""))) 4442 (use (match_operand:HI 2 "memory_operand" "")) 4443 (use (match_operand:HI 3 "memory_operand" "")) 4444 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 4445 "reload_completed" 4446 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1))) 4447 (use (match_dup 2)) 4448 (use (match_dup 3))])] 4449 "") 4450 4451(define_insn "x86_fnstcw_1" 4452 [(set (match_operand:HI 0 "memory_operand" "=m") 4453 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))] 4454 "TARGET_80387" 4455 "fnstcw\t%0" 4456 [(set_attr "length" "2") 4457 (set_attr "mode" "HI") 4458 (set_attr "unit" "i387")]) 4459 4460(define_insn "x86_fldcw_1" 4461 [(set (reg:HI FPCR_REG) 4462 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))] 4463 "TARGET_80387" 4464 "fldcw\t%0" 4465 [(set_attr "length" "2") 4466 (set_attr "mode" "HI") 4467 (set_attr "unit" "i387") 4468 (set_attr "athlon_decode" "vector") 4469 (set_attr "amdfam10_decode" "vector")]) 4470 4471;; Conversion between fixed point and floating point. 4472 4473;; Even though we only accept memory inputs, the backend _really_ 4474;; wants to be able to do this between registers. 4475 4476(define_expand "floathisf2" 4477 [(set (match_operand:SF 0 "register_operand" "") 4478 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))] 4479 "TARGET_80387 || TARGET_SSE_MATH" 4480{ 4481 if (TARGET_SSE_MATH) 4482 { 4483 emit_insn (gen_floatsisf2 (operands[0], 4484 convert_to_mode (SImode, operands[1], 0))); 4485 DONE; 4486 } 4487}) 4488 4489(define_insn "*floathisf2_i387" 4490 [(set (match_operand:SF 0 "register_operand" "=f,f") 4491 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))] 4492 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 4493 "@ 4494 fild%z1\t%1 4495 #" 4496 [(set_attr "type" "fmov,multi") 4497 (set_attr "mode" "SF") 4498 (set_attr "unit" "*,i387") 4499 (set_attr "fp_int_src" "true")]) 4500 4501(define_expand "floatsisf2" 4502 [(set (match_operand:SF 0 "register_operand" "") 4503 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))] 4504 "TARGET_80387 || TARGET_SSE_MATH" 4505 "") 4506 4507(define_insn "*floatsisf2_mixed" 4508 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x") 4509 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))] 4510 "TARGET_MIX_SSE_I387" 4511 "@ 4512 fild%z1\t%1 4513 # 4514 cvtsi2ss\t{%1, %0|%0, %1} 4515 cvtsi2ss\t{%1, %0|%0, %1}" 4516 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4517 (set_attr "mode" "SF") 4518 (set_attr "unit" "*,i387,*,*") 4519 (set_attr "athlon_decode" "*,*,vector,double") 4520 (set_attr "amdfam10_decode" "*,*,vector,double") 4521 (set_attr "fp_int_src" "true")]) 4522 4523(define_insn "*floatsisf2_sse" 4524 [(set (match_operand:SF 0 "register_operand" "=x,x") 4525 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))] 4526 "TARGET_SSE_MATH" 4527 "cvtsi2ss\t{%1, %0|%0, %1}" 4528 [(set_attr "type" "sseicvt") 4529 (set_attr "mode" "SF") 4530 (set_attr "athlon_decode" "vector,double") 4531 (set_attr "amdfam10_decode" "vector,double") 4532 (set_attr "fp_int_src" "true")]) 4533 4534(define_insn "*floatsisf2_i387" 4535 [(set (match_operand:SF 0 "register_operand" "=f,f") 4536 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))] 4537 "TARGET_80387" 4538 "@ 4539 fild%z1\t%1 4540 #" 4541 [(set_attr "type" "fmov,multi") 4542 (set_attr "mode" "SF") 4543 (set_attr "unit" "*,i387") 4544 (set_attr "fp_int_src" "true")]) 4545 4546(define_expand "floatdisf2" 4547 [(set (match_operand:SF 0 "register_operand" "") 4548 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))] 4549 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)" 4550 "") 4551 4552(define_insn "*floatdisf2_mixed" 4553 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x") 4554 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))] 4555 "TARGET_64BIT && TARGET_MIX_SSE_I387" 4556 "@ 4557 fild%z1\t%1 4558 # 4559 cvtsi2ss{q}\t{%1, %0|%0, %1} 4560 cvtsi2ss{q}\t{%1, %0|%0, %1}" 4561 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4562 (set_attr "mode" "SF") 4563 (set_attr "unit" "*,i387,*,*") 4564 (set_attr "athlon_decode" "*,*,vector,double") 4565 (set_attr "amdfam10_decode" "*,*,vector,double") 4566 (set_attr "fp_int_src" "true")]) 4567 4568(define_insn "*floatdisf2_sse" 4569 [(set (match_operand:SF 0 "register_operand" "=x,x") 4570 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))] 4571 "TARGET_64BIT && TARGET_SSE_MATH" 4572 "cvtsi2ss{q}\t{%1, %0|%0, %1}" 4573 [(set_attr "type" "sseicvt") 4574 (set_attr "mode" "SF") 4575 (set_attr "athlon_decode" "vector,double") 4576 (set_attr "amdfam10_decode" "vector,double") 4577 (set_attr "fp_int_src" "true")]) 4578 4579(define_insn "*floatdisf2_i387" 4580 [(set (match_operand:SF 0 "register_operand" "=f,f") 4581 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))] 4582 "TARGET_80387" 4583 "@ 4584 fild%z1\t%1 4585 #" 4586 [(set_attr "type" "fmov,multi") 4587 (set_attr "mode" "SF") 4588 (set_attr "unit" "*,i387") 4589 (set_attr "fp_int_src" "true")]) 4590 4591(define_expand "floathidf2" 4592 [(set (match_operand:DF 0 "register_operand" "") 4593 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))] 4594 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4595{ 4596 if (TARGET_SSE2 && TARGET_SSE_MATH) 4597 { 4598 emit_insn (gen_floatsidf2 (operands[0], 4599 convert_to_mode (SImode, operands[1], 0))); 4600 DONE; 4601 } 4602}) 4603 4604(define_insn "*floathidf2_i387" 4605 [(set (match_operand:DF 0 "register_operand" "=f,f") 4606 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))] 4607 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)" 4608 "@ 4609 fild%z1\t%1 4610 #" 4611 [(set_attr "type" "fmov,multi") 4612 (set_attr "mode" "DF") 4613 (set_attr "unit" "*,i387") 4614 (set_attr "fp_int_src" "true")]) 4615 4616(define_expand "floatsidf2" 4617 [(set (match_operand:DF 0 "register_operand" "") 4618 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))] 4619 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4620 "") 4621 4622(define_insn "*floatsidf2_mixed" 4623 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y") 4624 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))] 4625 "TARGET_SSE2 && TARGET_MIX_SSE_I387" 4626 "@ 4627 fild%z1\t%1 4628 # 4629 cvtsi2sd\t{%1, %0|%0, %1} 4630 cvtsi2sd\t{%1, %0|%0, %1}" 4631 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4632 (set_attr "mode" "DF") 4633 (set_attr "unit" "*,i387,*,*") 4634 (set_attr "athlon_decode" "*,*,double,direct") 4635 (set_attr "amdfam10_decode" "*,*,vector,double") 4636 (set_attr "fp_int_src" "true")]) 4637 4638(define_insn "*floatsidf2_sse" 4639 [(set (match_operand:DF 0 "register_operand" "=Y,Y") 4640 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))] 4641 "TARGET_SSE2 && TARGET_SSE_MATH" 4642 "cvtsi2sd\t{%1, %0|%0, %1}" 4643 [(set_attr "type" "sseicvt") 4644 (set_attr "mode" "DF") 4645 (set_attr "athlon_decode" "double,direct") 4646 (set_attr "amdfam10_decode" "vector,double") 4647 (set_attr "fp_int_src" "true")]) 4648 4649(define_insn "*floatsidf2_i387" 4650 [(set (match_operand:DF 0 "register_operand" "=f,f") 4651 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))] 4652 "TARGET_80387" 4653 "@ 4654 fild%z1\t%1 4655 #" 4656 [(set_attr "type" "fmov,multi") 4657 (set_attr "mode" "DF") 4658 (set_attr "unit" "*,i387") 4659 (set_attr "fp_int_src" "true")]) 4660 4661(define_expand "floatdidf2" 4662 [(set (match_operand:DF 0 "register_operand" "") 4663 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))] 4664 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)" 4665 "") 4666 4667(define_insn "*floatdidf2_mixed" 4668 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y") 4669 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))] 4670 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387" 4671 "@ 4672 fild%z1\t%1 4673 # 4674 cvtsi2sd{q}\t{%1, %0|%0, %1} 4675 cvtsi2sd{q}\t{%1, %0|%0, %1}" 4676 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4677 (set_attr "mode" "DF") 4678 (set_attr "unit" "*,i387,*,*") 4679 (set_attr "athlon_decode" "*,*,double,direct") 4680 (set_attr "amdfam10_decode" "*,*,vector,double") 4681 (set_attr "fp_int_src" "true")]) 4682 4683(define_insn "*floatdidf2_sse" 4684 [(set (match_operand:DF 0 "register_operand" "=Y,Y") 4685 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))] 4686 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH" 4687 "cvtsi2sd{q}\t{%1, %0|%0, %1}" 4688 [(set_attr "type" "sseicvt") 4689 (set_attr "mode" "DF") 4690 (set_attr "athlon_decode" "double,direct") 4691 (set_attr "amdfam10_decode" "vector,double") 4692 (set_attr "fp_int_src" "true")]) 4693 4694(define_insn "*floatdidf2_i387" 4695 [(set (match_operand:DF 0 "register_operand" "=f,f") 4696 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))] 4697 "TARGET_80387" 4698 "@ 4699 fild%z1\t%1 4700 #" 4701 [(set_attr "type" "fmov,multi") 4702 (set_attr "mode" "DF") 4703 (set_attr "unit" "*,i387") 4704 (set_attr "fp_int_src" "true")]) 4705 4706(define_insn "floathixf2" 4707 [(set (match_operand:XF 0 "register_operand" "=f,f") 4708 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))] 4709 "TARGET_80387" 4710 "@ 4711 fild%z1\t%1 4712 #" 4713 [(set_attr "type" "fmov,multi") 4714 (set_attr "mode" "XF") 4715 (set_attr "unit" "*,i387") 4716 (set_attr "fp_int_src" "true")]) 4717 4718(define_insn "floatsixf2" 4719 [(set (match_operand:XF 0 "register_operand" "=f,f") 4720 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))] 4721 "TARGET_80387" 4722 "@ 4723 fild%z1\t%1 4724 #" 4725 [(set_attr "type" "fmov,multi") 4726 (set_attr "mode" "XF") 4727 (set_attr "unit" "*,i387") 4728 (set_attr "fp_int_src" "true")]) 4729 4730(define_insn "floatdixf2" 4731 [(set (match_operand:XF 0 "register_operand" "=f,f") 4732 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))] 4733 "TARGET_80387" 4734 "@ 4735 fild%z1\t%1 4736 #" 4737 [(set_attr "type" "fmov,multi") 4738 (set_attr "mode" "XF") 4739 (set_attr "unit" "*,i387") 4740 (set_attr "fp_int_src" "true")]) 4741 4742;; %%% Kill these when reload knows how to do it. 4743(define_split 4744 [(set (match_operand 0 "fp_register_operand" "") 4745 (float (match_operand 1 "register_operand" "")))] 4746 "reload_completed 4747 && TARGET_80387 4748 && FLOAT_MODE_P (GET_MODE (operands[0]))" 4749 [(const_int 0)] 4750{ 4751 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]); 4752 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]); 4753 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2])); 4754 ix86_free_from_memory (GET_MODE (operands[1])); 4755 DONE; 4756}) 4757 4758(define_expand "floatunssisf2" 4759 [(use (match_operand:SF 0 "register_operand" "")) 4760 (use (match_operand:SI 1 "register_operand" ""))] 4761 "!TARGET_64BIT && TARGET_SSE_MATH" 4762 "x86_emit_floatuns (operands); DONE;") 4763 4764(define_expand "floatunsdisf2" 4765 [(use (match_operand:SF 0 "register_operand" "")) 4766 (use (match_operand:DI 1 "register_operand" ""))] 4767 "TARGET_64BIT && TARGET_SSE_MATH" 4768 "x86_emit_floatuns (operands); DONE;") 4769 4770(define_expand "floatunsdidf2" 4771 [(use (match_operand:DF 0 "register_operand" "")) 4772 (use (match_operand:DI 1 "register_operand" ""))] 4773 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH" 4774 "x86_emit_floatuns (operands); DONE;") 4775 4776;; SSE extract/set expanders 4777 4778 4779;; Add instructions 4780 4781;; %%% splits for addditi3 4782 4783(define_expand "addti3" 4784 [(set (match_operand:TI 0 "nonimmediate_operand" "") 4785 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "") 4786 (match_operand:TI 2 "x86_64_general_operand" ""))) 4787 (clobber (reg:CC FLAGS_REG))] 4788 "TARGET_64BIT" 4789 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;") 4790 4791(define_insn "*addti3_1" 4792 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o") 4793 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0") 4794 (match_operand:TI 2 "x86_64_general_operand" "roe,re"))) 4795 (clobber (reg:CC FLAGS_REG))] 4796 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)" 4797 "#") 4798 4799(define_split 4800 [(set (match_operand:TI 0 "nonimmediate_operand" "") 4801 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "") 4802 (match_operand:TI 2 "x86_64_general_operand" ""))) 4803 (clobber (reg:CC FLAGS_REG))] 4804 "TARGET_64BIT && reload_completed" 4805 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)] 4806 UNSPEC_ADD_CARRY)) 4807 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]) 4808 (parallel [(set (match_dup 3) 4809 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) 4810 (match_dup 4)) 4811 (match_dup 5))) 4812 (clobber (reg:CC FLAGS_REG))])] 4813 "split_ti (operands+0, 1, operands+0, operands+3); 4814 split_ti (operands+1, 1, operands+1, operands+4); 4815 split_ti (operands+2, 1, operands+2, operands+5);") 4816 4817;; %%% splits for addsidi3 4818; [(set (match_operand:DI 0 "nonimmediate_operand" "") 4819; (plus:DI (match_operand:DI 1 "general_operand" "") 4820; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))] 4821 4822(define_expand "adddi3" 4823 [(set (match_operand:DI 0 "nonimmediate_operand" "") 4824 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") 4825 (match_operand:DI 2 "x86_64_general_operand" ""))) 4826 (clobber (reg:CC FLAGS_REG))] 4827 "" 4828 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;") 4829 4830(define_insn "*adddi3_1" 4831 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") 4832 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 4833 (match_operand:DI 2 "general_operand" "roiF,riF"))) 4834 (clobber (reg:CC FLAGS_REG))] 4835 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 4836 "#") 4837 4838(define_split 4839 [(set (match_operand:DI 0 "nonimmediate_operand" "") 4840 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") 4841 (match_operand:DI 2 "general_operand" ""))) 4842 (clobber (reg:CC FLAGS_REG))] 4843 "!TARGET_64BIT && reload_completed" 4844 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)] 4845 UNSPEC_ADD_CARRY)) 4846 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) 4847 (parallel [(set (match_dup 3) 4848 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) 4849 (match_dup 4)) 4850 (match_dup 5))) 4851 (clobber (reg:CC FLAGS_REG))])] 4852 "split_di (operands+0, 1, operands+0, operands+3); 4853 split_di (operands+1, 1, operands+1, operands+4); 4854 split_di (operands+2, 1, operands+2, operands+5);") 4855 4856(define_insn "adddi3_carry_rex64" 4857 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 4858 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "") 4859 (match_operand:DI 1 "nonimmediate_operand" "%0,0")) 4860 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 4861 (clobber (reg:CC FLAGS_REG))] 4862 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 4863 "adc{q}\t{%2, %0|%0, %2}" 4864 [(set_attr "type" "alu") 4865 (set_attr "pent_pair" "pu") 4866 (set_attr "mode" "DI")]) 4867 4868(define_insn "*adddi3_cc_rex64" 4869 [(set (reg:CC FLAGS_REG) 4870 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0") 4871 (match_operand:DI 2 "x86_64_general_operand" "re,rm")] 4872 UNSPEC_ADD_CARRY)) 4873 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 4874 (plus:DI (match_dup 1) (match_dup 2)))] 4875 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 4876 "add{q}\t{%2, %0|%0, %2}" 4877 [(set_attr "type" "alu") 4878 (set_attr "mode" "DI")]) 4879 4880(define_insn "addqi3_carry" 4881 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 4882 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "") 4883 (match_operand:QI 1 "nonimmediate_operand" "%0,0")) 4884 (match_operand:QI 2 "general_operand" "qi,qm"))) 4885 (clobber (reg:CC FLAGS_REG))] 4886 "ix86_binary_operator_ok (PLUS, QImode, operands)" 4887 "adc{b}\t{%2, %0|%0, %2}" 4888 [(set_attr "type" "alu") 4889 (set_attr "pent_pair" "pu") 4890 (set_attr "mode" "QI")]) 4891 4892(define_insn "addhi3_carry" 4893 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 4894 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "") 4895 (match_operand:HI 1 "nonimmediate_operand" "%0,0")) 4896 (match_operand:HI 2 "general_operand" "ri,rm"))) 4897 (clobber (reg:CC FLAGS_REG))] 4898 "ix86_binary_operator_ok (PLUS, HImode, operands)" 4899 "adc{w}\t{%2, %0|%0, %2}" 4900 [(set_attr "type" "alu") 4901 (set_attr "pent_pair" "pu") 4902 (set_attr "mode" "HI")]) 4903 4904(define_insn "addsi3_carry" 4905 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 4906 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 4907 (match_operand:SI 1 "nonimmediate_operand" "%0,0")) 4908 (match_operand:SI 2 "general_operand" "ri,rm"))) 4909 (clobber (reg:CC FLAGS_REG))] 4910 "ix86_binary_operator_ok (PLUS, SImode, operands)" 4911 "adc{l}\t{%2, %0|%0, %2}" 4912 [(set_attr "type" "alu") 4913 (set_attr "pent_pair" "pu") 4914 (set_attr "mode" "SI")]) 4915 4916(define_insn "*addsi3_carry_zext" 4917 [(set (match_operand:DI 0 "register_operand" "=r") 4918 (zero_extend:DI 4919 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 4920 (match_operand:SI 1 "nonimmediate_operand" "%0")) 4921 (match_operand:SI 2 "general_operand" "rim")))) 4922 (clobber (reg:CC FLAGS_REG))] 4923 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 4924 "adc{l}\t{%2, %k0|%k0, %2}" 4925 [(set_attr "type" "alu") 4926 (set_attr "pent_pair" "pu") 4927 (set_attr "mode" "SI")]) 4928 4929(define_insn "*addsi3_cc" 4930 [(set (reg:CC FLAGS_REG) 4931 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0") 4932 (match_operand:SI 2 "general_operand" "ri,rm")] 4933 UNSPEC_ADD_CARRY)) 4934 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 4935 (plus:SI (match_dup 1) (match_dup 2)))] 4936 "ix86_binary_operator_ok (PLUS, SImode, operands)" 4937 "add{l}\t{%2, %0|%0, %2}" 4938 [(set_attr "type" "alu") 4939 (set_attr "mode" "SI")]) 4940 4941(define_insn "addqi3_cc" 4942 [(set (reg:CC FLAGS_REG) 4943 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0") 4944 (match_operand:QI 2 "general_operand" "qi,qm")] 4945 UNSPEC_ADD_CARRY)) 4946 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 4947 (plus:QI (match_dup 1) (match_dup 2)))] 4948 "ix86_binary_operator_ok (PLUS, QImode, operands)" 4949 "add{b}\t{%2, %0|%0, %2}" 4950 [(set_attr "type" "alu") 4951 (set_attr "mode" "QI")]) 4952 4953(define_expand "addsi3" 4954 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4955 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "") 4956 (match_operand:SI 2 "general_operand" ""))) 4957 (clobber (reg:CC FLAGS_REG))])] 4958 "" 4959 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;") 4960 4961(define_insn "*lea_1" 4962 [(set (match_operand:SI 0 "register_operand" "=r") 4963 (match_operand:SI 1 "no_seg_address_operand" "p"))] 4964 "!TARGET_64BIT" 4965 "lea{l}\t{%a1, %0|%0, %a1}" 4966 [(set_attr "type" "lea") 4967 (set_attr "mode" "SI")]) 4968 4969(define_insn "*lea_1_rex64" 4970 [(set (match_operand:SI 0 "register_operand" "=r") 4971 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))] 4972 "TARGET_64BIT" 4973 "lea{l}\t{%a1, %0|%0, %a1}" 4974 [(set_attr "type" "lea") 4975 (set_attr "mode" "SI")]) 4976 4977(define_insn "*lea_1_zext" 4978 [(set (match_operand:DI 0 "register_operand" "=r") 4979 (zero_extend:DI 4980 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))] 4981 "TARGET_64BIT" 4982 "lea{l}\t{%a1, %k0|%k0, %a1}" 4983 [(set_attr "type" "lea") 4984 (set_attr "mode" "SI")]) 4985 4986(define_insn "*lea_2_rex64" 4987 [(set (match_operand:DI 0 "register_operand" "=r") 4988 (match_operand:DI 1 "no_seg_address_operand" "p"))] 4989 "TARGET_64BIT" 4990 "lea{q}\t{%a1, %0|%0, %a1}" 4991 [(set_attr "type" "lea") 4992 (set_attr "mode" "DI")]) 4993 4994;; The lea patterns for non-Pmodes needs to be matched by several 4995;; insns converted to real lea by splitters. 4996 4997(define_insn_and_split "*lea_general_1" 4998 [(set (match_operand 0 "register_operand" "=r") 4999 (plus (plus (match_operand 1 "index_register_operand" "l") 5000 (match_operand 2 "register_operand" "r")) 5001 (match_operand 3 "immediate_operand" "i")))] 5002 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode 5003 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) 5004 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 5005 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 5006 && GET_MODE (operands[0]) == GET_MODE (operands[2]) 5007 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 5008 || GET_MODE (operands[3]) == VOIDmode)" 5009 "#" 5010 "&& reload_completed" 5011 [(const_int 0)] 5012{ 5013 rtx pat; 5014 operands[0] = gen_lowpart (SImode, operands[0]); 5015 operands[1] = gen_lowpart (Pmode, operands[1]); 5016 operands[2] = gen_lowpart (Pmode, operands[2]); 5017 operands[3] = gen_lowpart (Pmode, operands[3]); 5018 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]), 5019 operands[3]); 5020 if (Pmode != SImode) 5021 pat = gen_rtx_SUBREG (SImode, pat, 0); 5022 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5023 DONE; 5024} 5025 [(set_attr "type" "lea") 5026 (set_attr "mode" "SI")]) 5027 5028(define_insn_and_split "*lea_general_1_zext" 5029 [(set (match_operand:DI 0 "register_operand" "=r") 5030 (zero_extend:DI 5031 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l") 5032 (match_operand:SI 2 "register_operand" "r")) 5033 (match_operand:SI 3 "immediate_operand" "i"))))] 5034 "TARGET_64BIT" 5035 "#" 5036 "&& reload_completed" 5037 [(set (match_dup 0) 5038 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1) 5039 (match_dup 2)) 5040 (match_dup 3)) 0)))] 5041{ 5042 operands[1] = gen_lowpart (Pmode, operands[1]); 5043 operands[2] = gen_lowpart (Pmode, operands[2]); 5044 operands[3] = gen_lowpart (Pmode, operands[3]); 5045} 5046 [(set_attr "type" "lea") 5047 (set_attr "mode" "SI")]) 5048 5049(define_insn_and_split "*lea_general_2" 5050 [(set (match_operand 0 "register_operand" "=r") 5051 (plus (mult (match_operand 1 "index_register_operand" "l") 5052 (match_operand 2 "const248_operand" "i")) 5053 (match_operand 3 "nonmemory_operand" "ri")))] 5054 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode 5055 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) 5056 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 5057 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 5058 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 5059 || GET_MODE (operands[3]) == VOIDmode)" 5060 "#" 5061 "&& reload_completed" 5062 [(const_int 0)] 5063{ 5064 rtx pat; 5065 operands[0] = gen_lowpart (SImode, operands[0]); 5066 operands[1] = gen_lowpart (Pmode, operands[1]); 5067 operands[3] = gen_lowpart (Pmode, operands[3]); 5068 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]), 5069 operands[3]); 5070 if (Pmode != SImode) 5071 pat = gen_rtx_SUBREG (SImode, pat, 0); 5072 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5073 DONE; 5074} 5075 [(set_attr "type" "lea") 5076 (set_attr "mode" "SI")]) 5077 5078(define_insn_and_split "*lea_general_2_zext" 5079 [(set (match_operand:DI 0 "register_operand" "=r") 5080 (zero_extend:DI 5081 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l") 5082 (match_operand:SI 2 "const248_operand" "n")) 5083 (match_operand:SI 3 "nonmemory_operand" "ri"))))] 5084 "TARGET_64BIT" 5085 "#" 5086 "&& reload_completed" 5087 [(set (match_dup 0) 5088 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1) 5089 (match_dup 2)) 5090 (match_dup 3)) 0)))] 5091{ 5092 operands[1] = gen_lowpart (Pmode, operands[1]); 5093 operands[3] = gen_lowpart (Pmode, operands[3]); 5094} 5095 [(set_attr "type" "lea") 5096 (set_attr "mode" "SI")]) 5097 5098(define_insn_and_split "*lea_general_3" 5099 [(set (match_operand 0 "register_operand" "=r") 5100 (plus (plus (mult (match_operand 1 "index_register_operand" "l") 5101 (match_operand 2 "const248_operand" "i")) 5102 (match_operand 3 "register_operand" "r")) 5103 (match_operand 4 "immediate_operand" "i")))] 5104 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode 5105 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) 5106 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 5107 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 5108 && GET_MODE (operands[0]) == GET_MODE (operands[3])" 5109 "#" 5110 "&& reload_completed" 5111 [(const_int 0)] 5112{ 5113 rtx pat; 5114 operands[0] = gen_lowpart (SImode, operands[0]); 5115 operands[1] = gen_lowpart (Pmode, operands[1]); 5116 operands[3] = gen_lowpart (Pmode, operands[3]); 5117 operands[4] = gen_lowpart (Pmode, operands[4]); 5118 pat = gen_rtx_PLUS (Pmode, 5119 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], 5120 operands[2]), 5121 operands[3]), 5122 operands[4]); 5123 if (Pmode != SImode) 5124 pat = gen_rtx_SUBREG (SImode, pat, 0); 5125 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5126 DONE; 5127} 5128 [(set_attr "type" "lea") 5129 (set_attr "mode" "SI")]) 5130 5131(define_insn_and_split "*lea_general_3_zext" 5132 [(set (match_operand:DI 0 "register_operand" "=r") 5133 (zero_extend:DI 5134 (plus:SI (plus:SI (mult:SI 5135 (match_operand:SI 1 "index_register_operand" "l") 5136 (match_operand:SI 2 "const248_operand" "n")) 5137 (match_operand:SI 3 "register_operand" "r")) 5138 (match_operand:SI 4 "immediate_operand" "i"))))] 5139 "TARGET_64BIT" 5140 "#" 5141 "&& reload_completed" 5142 [(set (match_dup 0) 5143 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1) 5144 (match_dup 2)) 5145 (match_dup 3)) 5146 (match_dup 4)) 0)))] 5147{ 5148 operands[1] = gen_lowpart (Pmode, operands[1]); 5149 operands[3] = gen_lowpart (Pmode, operands[3]); 5150 operands[4] = gen_lowpart (Pmode, operands[4]); 5151} 5152 [(set_attr "type" "lea") 5153 (set_attr "mode" "SI")]) 5154 5155(define_insn "*adddi_1_rex64" 5156 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r") 5157 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r") 5158 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le"))) 5159 (clobber (reg:CC FLAGS_REG))] 5160 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 5161{ 5162 switch (get_attr_type (insn)) 5163 { 5164 case TYPE_LEA: 5165 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 5166 return "lea{q}\t{%a2, %0|%0, %a2}"; 5167 5168 case TYPE_INCDEC: 5169 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5170 if (operands[2] == const1_rtx) 5171 return "inc{q}\t%0"; 5172 else 5173 { 5174 gcc_assert (operands[2] == constm1_rtx); 5175 return "dec{q}\t%0"; 5176 } 5177 5178 default: 5179 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5180 5181 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5182 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5183 if (GET_CODE (operands[2]) == CONST_INT 5184 /* Avoid overflows. */ 5185 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5186 && (INTVAL (operands[2]) == 128 5187 || (INTVAL (operands[2]) < 0 5188 && INTVAL (operands[2]) != -128))) 5189 { 5190 operands[2] = GEN_INT (-INTVAL (operands[2])); 5191 return "sub{q}\t{%2, %0|%0, %2}"; 5192 } 5193 return "add{q}\t{%2, %0|%0, %2}"; 5194 } 5195} 5196 [(set (attr "type") 5197 (cond [(eq_attr "alternative" "2") 5198 (const_string "lea") 5199 ; Current assemblers are broken and do not allow @GOTOFF in 5200 ; ought but a memory context. 5201 (match_operand:DI 2 "pic_symbolic_operand" "") 5202 (const_string "lea") 5203 (match_operand:DI 2 "incdec_operand" "") 5204 (const_string "incdec") 5205 ] 5206 (const_string "alu"))) 5207 (set_attr "mode" "DI")]) 5208 5209;; Convert lea to the lea pattern to avoid flags dependency. 5210(define_split 5211 [(set (match_operand:DI 0 "register_operand" "") 5212 (plus:DI (match_operand:DI 1 "register_operand" "") 5213 (match_operand:DI 2 "x86_64_nonmemory_operand" ""))) 5214 (clobber (reg:CC FLAGS_REG))] 5215 "TARGET_64BIT && reload_completed 5216 && true_regnum (operands[0]) != true_regnum (operands[1])" 5217 [(set (match_dup 0) 5218 (plus:DI (match_dup 1) 5219 (match_dup 2)))] 5220 "") 5221 5222(define_insn "*adddi_2_rex64" 5223 [(set (reg FLAGS_REG) 5224 (compare 5225 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 5226 (match_operand:DI 2 "x86_64_general_operand" "rme,re")) 5227 (const_int 0))) 5228 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") 5229 (plus:DI (match_dup 1) (match_dup 2)))] 5230 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 5231 && ix86_binary_operator_ok (PLUS, DImode, operands) 5232 /* Current assemblers are broken and do not allow @GOTOFF in 5233 ought but a memory context. */ 5234 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5235{ 5236 switch (get_attr_type (insn)) 5237 { 5238 case TYPE_INCDEC: 5239 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5240 if (operands[2] == const1_rtx) 5241 return "inc{q}\t%0"; 5242 else 5243 { 5244 gcc_assert (operands[2] == constm1_rtx); 5245 return "dec{q}\t%0"; 5246 } 5247 5248 default: 5249 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5250 /* ???? We ought to handle there the 32bit case too 5251 - do we need new constraint? */ 5252 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5253 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5254 if (GET_CODE (operands[2]) == CONST_INT 5255 /* Avoid overflows. */ 5256 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5257 && (INTVAL (operands[2]) == 128 5258 || (INTVAL (operands[2]) < 0 5259 && INTVAL (operands[2]) != -128))) 5260 { 5261 operands[2] = GEN_INT (-INTVAL (operands[2])); 5262 return "sub{q}\t{%2, %0|%0, %2}"; 5263 } 5264 return "add{q}\t{%2, %0|%0, %2}"; 5265 } 5266} 5267 [(set (attr "type") 5268 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5269 (const_string "incdec") 5270 (const_string "alu"))) 5271 (set_attr "mode" "DI")]) 5272 5273(define_insn "*adddi_3_rex64" 5274 [(set (reg FLAGS_REG) 5275 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme")) 5276 (match_operand:DI 1 "x86_64_general_operand" "%0"))) 5277 (clobber (match_scratch:DI 0 "=r"))] 5278 "TARGET_64BIT 5279 && ix86_match_ccmode (insn, CCZmode) 5280 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5281 /* Current assemblers are broken and do not allow @GOTOFF in 5282 ought but a memory context. */ 5283 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5284{ 5285 switch (get_attr_type (insn)) 5286 { 5287 case TYPE_INCDEC: 5288 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5289 if (operands[2] == const1_rtx) 5290 return "inc{q}\t%0"; 5291 else 5292 { 5293 gcc_assert (operands[2] == constm1_rtx); 5294 return "dec{q}\t%0"; 5295 } 5296 5297 default: 5298 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5299 /* ???? We ought to handle there the 32bit case too 5300 - do we need new constraint? */ 5301 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5302 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5303 if (GET_CODE (operands[2]) == CONST_INT 5304 /* Avoid overflows. */ 5305 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5306 && (INTVAL (operands[2]) == 128 5307 || (INTVAL (operands[2]) < 0 5308 && INTVAL (operands[2]) != -128))) 5309 { 5310 operands[2] = GEN_INT (-INTVAL (operands[2])); 5311 return "sub{q}\t{%2, %0|%0, %2}"; 5312 } 5313 return "add{q}\t{%2, %0|%0, %2}"; 5314 } 5315} 5316 [(set (attr "type") 5317 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5318 (const_string "incdec") 5319 (const_string "alu"))) 5320 (set_attr "mode" "DI")]) 5321 5322; For comparisons against 1, -1 and 128, we may generate better code 5323; by converting cmp to add, inc or dec as done by peephole2. This pattern 5324; is matched then. We can't accept general immediate, because for 5325; case of overflows, the result is messed up. 5326; This pattern also don't hold of 0x8000000000000000, since the value overflows 5327; when negated. 5328; Also carry flag is reversed compared to cmp, so this conversion is valid 5329; only for comparisons not depending on it. 5330(define_insn "*adddi_4_rex64" 5331 [(set (reg FLAGS_REG) 5332 (compare (match_operand:DI 1 "nonimmediate_operand" "0") 5333 (match_operand:DI 2 "x86_64_immediate_operand" "e"))) 5334 (clobber (match_scratch:DI 0 "=rm"))] 5335 "TARGET_64BIT 5336 && ix86_match_ccmode (insn, CCGCmode)" 5337{ 5338 switch (get_attr_type (insn)) 5339 { 5340 case TYPE_INCDEC: 5341 if (operands[2] == constm1_rtx) 5342 return "inc{q}\t%0"; 5343 else 5344 { 5345 gcc_assert (operands[2] == const1_rtx); 5346 return "dec{q}\t%0"; 5347 } 5348 5349 default: 5350 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5351 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5352 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5353 if ((INTVAL (operands[2]) == -128 5354 || (INTVAL (operands[2]) > 0 5355 && INTVAL (operands[2]) != 128)) 5356 /* Avoid overflows. */ 5357 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))) 5358 return "sub{q}\t{%2, %0|%0, %2}"; 5359 operands[2] = GEN_INT (-INTVAL (operands[2])); 5360 return "add{q}\t{%2, %0|%0, %2}"; 5361 } 5362} 5363 [(set (attr "type") 5364 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5365 (const_string "incdec") 5366 (const_string "alu"))) 5367 (set_attr "mode" "DI")]) 5368 5369(define_insn "*adddi_5_rex64" 5370 [(set (reg FLAGS_REG) 5371 (compare 5372 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0") 5373 (match_operand:DI 2 "x86_64_general_operand" "rme")) 5374 (const_int 0))) 5375 (clobber (match_scratch:DI 0 "=r"))] 5376 "TARGET_64BIT 5377 && ix86_match_ccmode (insn, CCGOCmode) 5378 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5379 /* Current assemblers are broken and do not allow @GOTOFF in 5380 ought but a memory context. */ 5381 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5382{ 5383 switch (get_attr_type (insn)) 5384 { 5385 case TYPE_INCDEC: 5386 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5387 if (operands[2] == const1_rtx) 5388 return "inc{q}\t%0"; 5389 else 5390 { 5391 gcc_assert (operands[2] == constm1_rtx); 5392 return "dec{q}\t%0"; 5393 } 5394 5395 default: 5396 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5397 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5398 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5399 if (GET_CODE (operands[2]) == CONST_INT 5400 /* Avoid overflows. */ 5401 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5402 && (INTVAL (operands[2]) == 128 5403 || (INTVAL (operands[2]) < 0 5404 && INTVAL (operands[2]) != -128))) 5405 { 5406 operands[2] = GEN_INT (-INTVAL (operands[2])); 5407 return "sub{q}\t{%2, %0|%0, %2}"; 5408 } 5409 return "add{q}\t{%2, %0|%0, %2}"; 5410 } 5411} 5412 [(set (attr "type") 5413 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5414 (const_string "incdec") 5415 (const_string "alu"))) 5416 (set_attr "mode" "DI")]) 5417 5418 5419(define_insn "*addsi_1" 5420 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r") 5421 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r") 5422 (match_operand:SI 2 "general_operand" "rmni,rni,lni"))) 5423 (clobber (reg:CC FLAGS_REG))] 5424 "ix86_binary_operator_ok (PLUS, SImode, operands)" 5425{ 5426 switch (get_attr_type (insn)) 5427 { 5428 case TYPE_LEA: 5429 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 5430 return "lea{l}\t{%a2, %0|%0, %a2}"; 5431 5432 case TYPE_INCDEC: 5433 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5434 if (operands[2] == const1_rtx) 5435 return "inc{l}\t%0"; 5436 else 5437 { 5438 gcc_assert (operands[2] == constm1_rtx); 5439 return "dec{l}\t%0"; 5440 } 5441 5442 default: 5443 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5444 5445 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5446 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5447 if (GET_CODE (operands[2]) == CONST_INT 5448 && (INTVAL (operands[2]) == 128 5449 || (INTVAL (operands[2]) < 0 5450 && INTVAL (operands[2]) != -128))) 5451 { 5452 operands[2] = GEN_INT (-INTVAL (operands[2])); 5453 return "sub{l}\t{%2, %0|%0, %2}"; 5454 } 5455 return "add{l}\t{%2, %0|%0, %2}"; 5456 } 5457} 5458 [(set (attr "type") 5459 (cond [(eq_attr "alternative" "2") 5460 (const_string "lea") 5461 ; Current assemblers are broken and do not allow @GOTOFF in 5462 ; ought but a memory context. 5463 (match_operand:SI 2 "pic_symbolic_operand" "") 5464 (const_string "lea") 5465 (match_operand:SI 2 "incdec_operand" "") 5466 (const_string "incdec") 5467 ] 5468 (const_string "alu"))) 5469 (set_attr "mode" "SI")]) 5470 5471;; Convert lea to the lea pattern to avoid flags dependency. 5472(define_split 5473 [(set (match_operand 0 "register_operand" "") 5474 (plus (match_operand 1 "register_operand" "") 5475 (match_operand 2 "nonmemory_operand" ""))) 5476 (clobber (reg:CC FLAGS_REG))] 5477 "reload_completed 5478 && true_regnum (operands[0]) != true_regnum (operands[1])" 5479 [(const_int 0)] 5480{ 5481 rtx pat; 5482 /* In -fPIC mode the constructs like (const (unspec [symbol_ref])) 5483 may confuse gen_lowpart. */ 5484 if (GET_MODE (operands[0]) != Pmode) 5485 { 5486 operands[1] = gen_lowpart (Pmode, operands[1]); 5487 operands[2] = gen_lowpart (Pmode, operands[2]); 5488 } 5489 operands[0] = gen_lowpart (SImode, operands[0]); 5490 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]); 5491 if (Pmode != SImode) 5492 pat = gen_rtx_SUBREG (SImode, pat, 0); 5493 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5494 DONE; 5495}) 5496 5497;; It may seem that nonimmediate operand is proper one for operand 1. 5498;; The addsi_1 pattern allows nonimmediate operand at that place and 5499;; we take care in ix86_binary_operator_ok to not allow two memory 5500;; operands so proper swapping will be done in reload. This allow 5501;; patterns constructed from addsi_1 to match. 5502(define_insn "addsi_1_zext" 5503 [(set (match_operand:DI 0 "register_operand" "=r,r") 5504 (zero_extend:DI 5505 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") 5506 (match_operand:SI 2 "general_operand" "rmni,lni")))) 5507 (clobber (reg:CC FLAGS_REG))] 5508 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 5509{ 5510 switch (get_attr_type (insn)) 5511 { 5512 case TYPE_LEA: 5513 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 5514 return "lea{l}\t{%a2, %k0|%k0, %a2}"; 5515 5516 case TYPE_INCDEC: 5517 if (operands[2] == const1_rtx) 5518 return "inc{l}\t%k0"; 5519 else 5520 { 5521 gcc_assert (operands[2] == constm1_rtx); 5522 return "dec{l}\t%k0"; 5523 } 5524 5525 default: 5526 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5527 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5528 if (GET_CODE (operands[2]) == CONST_INT 5529 && (INTVAL (operands[2]) == 128 5530 || (INTVAL (operands[2]) < 0 5531 && INTVAL (operands[2]) != -128))) 5532 { 5533 operands[2] = GEN_INT (-INTVAL (operands[2])); 5534 return "sub{l}\t{%2, %k0|%k0, %2}"; 5535 } 5536 return "add{l}\t{%2, %k0|%k0, %2}"; 5537 } 5538} 5539 [(set (attr "type") 5540 (cond [(eq_attr "alternative" "1") 5541 (const_string "lea") 5542 ; Current assemblers are broken and do not allow @GOTOFF in 5543 ; ought but a memory context. 5544 (match_operand:SI 2 "pic_symbolic_operand" "") 5545 (const_string "lea") 5546 (match_operand:SI 2 "incdec_operand" "") 5547 (const_string "incdec") 5548 ] 5549 (const_string "alu"))) 5550 (set_attr "mode" "SI")]) 5551 5552;; Convert lea to the lea pattern to avoid flags dependency. 5553(define_split 5554 [(set (match_operand:DI 0 "register_operand" "") 5555 (zero_extend:DI 5556 (plus:SI (match_operand:SI 1 "register_operand" "") 5557 (match_operand:SI 2 "nonmemory_operand" "")))) 5558 (clobber (reg:CC FLAGS_REG))] 5559 "TARGET_64BIT && reload_completed 5560 && true_regnum (operands[0]) != true_regnum (operands[1])" 5561 [(set (match_dup 0) 5562 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))] 5563{ 5564 operands[1] = gen_lowpart (Pmode, operands[1]); 5565 operands[2] = gen_lowpart (Pmode, operands[2]); 5566}) 5567 5568(define_insn "*addsi_2" 5569 [(set (reg FLAGS_REG) 5570 (compare 5571 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 5572 (match_operand:SI 2 "general_operand" "rmni,rni")) 5573 (const_int 0))) 5574 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 5575 (plus:SI (match_dup 1) (match_dup 2)))] 5576 "ix86_match_ccmode (insn, CCGOCmode) 5577 && ix86_binary_operator_ok (PLUS, SImode, operands) 5578 /* Current assemblers are broken and do not allow @GOTOFF in 5579 ought but a memory context. */ 5580 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5581{ 5582 switch (get_attr_type (insn)) 5583 { 5584 case TYPE_INCDEC: 5585 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5586 if (operands[2] == const1_rtx) 5587 return "inc{l}\t%0"; 5588 else 5589 { 5590 gcc_assert (operands[2] == constm1_rtx); 5591 return "dec{l}\t%0"; 5592 } 5593 5594 default: 5595 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5596 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5597 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5598 if (GET_CODE (operands[2]) == CONST_INT 5599 && (INTVAL (operands[2]) == 128 5600 || (INTVAL (operands[2]) < 0 5601 && INTVAL (operands[2]) != -128))) 5602 { 5603 operands[2] = GEN_INT (-INTVAL (operands[2])); 5604 return "sub{l}\t{%2, %0|%0, %2}"; 5605 } 5606 return "add{l}\t{%2, %0|%0, %2}"; 5607 } 5608} 5609 [(set (attr "type") 5610 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5611 (const_string "incdec") 5612 (const_string "alu"))) 5613 (set_attr "mode" "SI")]) 5614 5615;; See comment for addsi_1_zext why we do use nonimmediate_operand 5616(define_insn "*addsi_2_zext" 5617 [(set (reg FLAGS_REG) 5618 (compare 5619 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 5620 (match_operand:SI 2 "general_operand" "rmni")) 5621 (const_int 0))) 5622 (set (match_operand:DI 0 "register_operand" "=r") 5623 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5624 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 5625 && ix86_binary_operator_ok (PLUS, SImode, operands) 5626 /* Current assemblers are broken and do not allow @GOTOFF in 5627 ought but a memory context. */ 5628 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5629{ 5630 switch (get_attr_type (insn)) 5631 { 5632 case TYPE_INCDEC: 5633 if (operands[2] == const1_rtx) 5634 return "inc{l}\t%k0"; 5635 else 5636 { 5637 gcc_assert (operands[2] == constm1_rtx); 5638 return "dec{l}\t%k0"; 5639 } 5640 5641 default: 5642 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5643 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5644 if (GET_CODE (operands[2]) == CONST_INT 5645 && (INTVAL (operands[2]) == 128 5646 || (INTVAL (operands[2]) < 0 5647 && INTVAL (operands[2]) != -128))) 5648 { 5649 operands[2] = GEN_INT (-INTVAL (operands[2])); 5650 return "sub{l}\t{%2, %k0|%k0, %2}"; 5651 } 5652 return "add{l}\t{%2, %k0|%k0, %2}"; 5653 } 5654} 5655 [(set (attr "type") 5656 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5657 (const_string "incdec") 5658 (const_string "alu"))) 5659 (set_attr "mode" "SI")]) 5660 5661(define_insn "*addsi_3" 5662 [(set (reg FLAGS_REG) 5663 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni")) 5664 (match_operand:SI 1 "nonimmediate_operand" "%0"))) 5665 (clobber (match_scratch:SI 0 "=r"))] 5666 "ix86_match_ccmode (insn, CCZmode) 5667 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5668 /* Current assemblers are broken and do not allow @GOTOFF in 5669 ought but a memory context. */ 5670 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5671{ 5672 switch (get_attr_type (insn)) 5673 { 5674 case TYPE_INCDEC: 5675 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5676 if (operands[2] == const1_rtx) 5677 return "inc{l}\t%0"; 5678 else 5679 { 5680 gcc_assert (operands[2] == constm1_rtx); 5681 return "dec{l}\t%0"; 5682 } 5683 5684 default: 5685 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5686 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5687 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5688 if (GET_CODE (operands[2]) == CONST_INT 5689 && (INTVAL (operands[2]) == 128 5690 || (INTVAL (operands[2]) < 0 5691 && INTVAL (operands[2]) != -128))) 5692 { 5693 operands[2] = GEN_INT (-INTVAL (operands[2])); 5694 return "sub{l}\t{%2, %0|%0, %2}"; 5695 } 5696 return "add{l}\t{%2, %0|%0, %2}"; 5697 } 5698} 5699 [(set (attr "type") 5700 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5701 (const_string "incdec") 5702 (const_string "alu"))) 5703 (set_attr "mode" "SI")]) 5704 5705;; See comment for addsi_1_zext why we do use nonimmediate_operand 5706(define_insn "*addsi_3_zext" 5707 [(set (reg FLAGS_REG) 5708 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni")) 5709 (match_operand:SI 1 "nonimmediate_operand" "%0"))) 5710 (set (match_operand:DI 0 "register_operand" "=r") 5711 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5712 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode) 5713 && ix86_binary_operator_ok (PLUS, SImode, operands) 5714 /* Current assemblers are broken and do not allow @GOTOFF in 5715 ought but a memory context. */ 5716 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5717{ 5718 switch (get_attr_type (insn)) 5719 { 5720 case TYPE_INCDEC: 5721 if (operands[2] == const1_rtx) 5722 return "inc{l}\t%k0"; 5723 else 5724 { 5725 gcc_assert (operands[2] == constm1_rtx); 5726 return "dec{l}\t%k0"; 5727 } 5728 5729 default: 5730 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5731 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5732 if (GET_CODE (operands[2]) == CONST_INT 5733 && (INTVAL (operands[2]) == 128 5734 || (INTVAL (operands[2]) < 0 5735 && INTVAL (operands[2]) != -128))) 5736 { 5737 operands[2] = GEN_INT (-INTVAL (operands[2])); 5738 return "sub{l}\t{%2, %k0|%k0, %2}"; 5739 } 5740 return "add{l}\t{%2, %k0|%k0, %2}"; 5741 } 5742} 5743 [(set (attr "type") 5744 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5745 (const_string "incdec") 5746 (const_string "alu"))) 5747 (set_attr "mode" "SI")]) 5748 5749; For comparisons against 1, -1 and 128, we may generate better code 5750; by converting cmp to add, inc or dec as done by peephole2. This pattern 5751; is matched then. We can't accept general immediate, because for 5752; case of overflows, the result is messed up. 5753; This pattern also don't hold of 0x80000000, since the value overflows 5754; when negated. 5755; Also carry flag is reversed compared to cmp, so this conversion is valid 5756; only for comparisons not depending on it. 5757(define_insn "*addsi_4" 5758 [(set (reg FLAGS_REG) 5759 (compare (match_operand:SI 1 "nonimmediate_operand" "0") 5760 (match_operand:SI 2 "const_int_operand" "n"))) 5761 (clobber (match_scratch:SI 0 "=rm"))] 5762 "ix86_match_ccmode (insn, CCGCmode) 5763 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000" 5764{ 5765 switch (get_attr_type (insn)) 5766 { 5767 case TYPE_INCDEC: 5768 if (operands[2] == constm1_rtx) 5769 return "inc{l}\t%0"; 5770 else 5771 { 5772 gcc_assert (operands[2] == const1_rtx); 5773 return "dec{l}\t%0"; 5774 } 5775 5776 default: 5777 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5778 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5779 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5780 if ((INTVAL (operands[2]) == -128 5781 || (INTVAL (operands[2]) > 0 5782 && INTVAL (operands[2]) != 128))) 5783 return "sub{l}\t{%2, %0|%0, %2}"; 5784 operands[2] = GEN_INT (-INTVAL (operands[2])); 5785 return "add{l}\t{%2, %0|%0, %2}"; 5786 } 5787} 5788 [(set (attr "type") 5789 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5790 (const_string "incdec") 5791 (const_string "alu"))) 5792 (set_attr "mode" "SI")]) 5793 5794(define_insn "*addsi_5" 5795 [(set (reg FLAGS_REG) 5796 (compare 5797 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 5798 (match_operand:SI 2 "general_operand" "rmni")) 5799 (const_int 0))) 5800 (clobber (match_scratch:SI 0 "=r"))] 5801 "ix86_match_ccmode (insn, CCGOCmode) 5802 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5803 /* Current assemblers are broken and do not allow @GOTOFF in 5804 ought but a memory context. */ 5805 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5806{ 5807 switch (get_attr_type (insn)) 5808 { 5809 case TYPE_INCDEC: 5810 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5811 if (operands[2] == const1_rtx) 5812 return "inc{l}\t%0"; 5813 else 5814 { 5815 gcc_assert (operands[2] == constm1_rtx); 5816 return "dec{l}\t%0"; 5817 } 5818 5819 default: 5820 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5821 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5822 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5823 if (GET_CODE (operands[2]) == CONST_INT 5824 && (INTVAL (operands[2]) == 128 5825 || (INTVAL (operands[2]) < 0 5826 && INTVAL (operands[2]) != -128))) 5827 { 5828 operands[2] = GEN_INT (-INTVAL (operands[2])); 5829 return "sub{l}\t{%2, %0|%0, %2}"; 5830 } 5831 return "add{l}\t{%2, %0|%0, %2}"; 5832 } 5833} 5834 [(set (attr "type") 5835 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5836 (const_string "incdec") 5837 (const_string "alu"))) 5838 (set_attr "mode" "SI")]) 5839 5840(define_expand "addhi3" 5841 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 5842 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "") 5843 (match_operand:HI 2 "general_operand" ""))) 5844 (clobber (reg:CC FLAGS_REG))])] 5845 "TARGET_HIMODE_MATH" 5846 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;") 5847 5848;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah 5849;; type optimizations enabled by define-splits. This is not important 5850;; for PII, and in fact harmful because of partial register stalls. 5851 5852(define_insn "*addhi_1_lea" 5853 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") 5854 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r") 5855 (match_operand:HI 2 "general_operand" "ri,rm,lni"))) 5856 (clobber (reg:CC FLAGS_REG))] 5857 "!TARGET_PARTIAL_REG_STALL 5858 && ix86_binary_operator_ok (PLUS, HImode, operands)" 5859{ 5860 switch (get_attr_type (insn)) 5861 { 5862 case TYPE_LEA: 5863 return "#"; 5864 case TYPE_INCDEC: 5865 if (operands[2] == const1_rtx) 5866 return "inc{w}\t%0"; 5867 else 5868 { 5869 gcc_assert (operands[2] == constm1_rtx); 5870 return "dec{w}\t%0"; 5871 } 5872 5873 default: 5874 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5875 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5876 if (GET_CODE (operands[2]) == CONST_INT 5877 && (INTVAL (operands[2]) == 128 5878 || (INTVAL (operands[2]) < 0 5879 && INTVAL (operands[2]) != -128))) 5880 { 5881 operands[2] = GEN_INT (-INTVAL (operands[2])); 5882 return "sub{w}\t{%2, %0|%0, %2}"; 5883 } 5884 return "add{w}\t{%2, %0|%0, %2}"; 5885 } 5886} 5887 [(set (attr "type") 5888 (if_then_else (eq_attr "alternative" "2") 5889 (const_string "lea") 5890 (if_then_else (match_operand:HI 2 "incdec_operand" "") 5891 (const_string "incdec") 5892 (const_string "alu")))) 5893 (set_attr "mode" "HI,HI,SI")]) 5894 5895(define_insn "*addhi_1" 5896 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 5897 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 5898 (match_operand:HI 2 "general_operand" "ri,rm"))) 5899 (clobber (reg:CC FLAGS_REG))] 5900 "TARGET_PARTIAL_REG_STALL 5901 && ix86_binary_operator_ok (PLUS, HImode, operands)" 5902{ 5903 switch (get_attr_type (insn)) 5904 { 5905 case TYPE_INCDEC: 5906 if (operands[2] == const1_rtx) 5907 return "inc{w}\t%0"; 5908 else 5909 { 5910 gcc_assert (operands[2] == constm1_rtx); 5911 return "dec{w}\t%0"; 5912 } 5913 5914 default: 5915 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5916 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5917 if (GET_CODE (operands[2]) == CONST_INT 5918 && (INTVAL (operands[2]) == 128 5919 || (INTVAL (operands[2]) < 0 5920 && INTVAL (operands[2]) != -128))) 5921 { 5922 operands[2] = GEN_INT (-INTVAL (operands[2])); 5923 return "sub{w}\t{%2, %0|%0, %2}"; 5924 } 5925 return "add{w}\t{%2, %0|%0, %2}"; 5926 } 5927} 5928 [(set (attr "type") 5929 (if_then_else (match_operand:HI 2 "incdec_operand" "") 5930 (const_string "incdec") 5931 (const_string "alu"))) 5932 (set_attr "mode" "HI")]) 5933 5934(define_insn "*addhi_2" 5935 [(set (reg FLAGS_REG) 5936 (compare 5937 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 5938 (match_operand:HI 2 "general_operand" "rmni,rni")) 5939 (const_int 0))) 5940 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 5941 (plus:HI (match_dup 1) (match_dup 2)))] 5942 "ix86_match_ccmode (insn, CCGOCmode) 5943 && ix86_binary_operator_ok (PLUS, HImode, operands)" 5944{ 5945 switch (get_attr_type (insn)) 5946 { 5947 case TYPE_INCDEC: 5948 if (operands[2] == const1_rtx) 5949 return "inc{w}\t%0"; 5950 else 5951 { 5952 gcc_assert (operands[2] == constm1_rtx); 5953 return "dec{w}\t%0"; 5954 } 5955 5956 default: 5957 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5958 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5959 if (GET_CODE (operands[2]) == CONST_INT 5960 && (INTVAL (operands[2]) == 128 5961 || (INTVAL (operands[2]) < 0 5962 && INTVAL (operands[2]) != -128))) 5963 { 5964 operands[2] = GEN_INT (-INTVAL (operands[2])); 5965 return "sub{w}\t{%2, %0|%0, %2}"; 5966 } 5967 return "add{w}\t{%2, %0|%0, %2}"; 5968 } 5969} 5970 [(set (attr "type") 5971 (if_then_else (match_operand:HI 2 "incdec_operand" "") 5972 (const_string "incdec") 5973 (const_string "alu"))) 5974 (set_attr "mode" "HI")]) 5975 5976(define_insn "*addhi_3" 5977 [(set (reg FLAGS_REG) 5978 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni")) 5979 (match_operand:HI 1 "nonimmediate_operand" "%0"))) 5980 (clobber (match_scratch:HI 0 "=r"))] 5981 "ix86_match_ccmode (insn, CCZmode) 5982 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 5983{ 5984 switch (get_attr_type (insn)) 5985 { 5986 case TYPE_INCDEC: 5987 if (operands[2] == const1_rtx) 5988 return "inc{w}\t%0"; 5989 else 5990 { 5991 gcc_assert (operands[2] == constm1_rtx); 5992 return "dec{w}\t%0"; 5993 } 5994 5995 default: 5996 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5997 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5998 if (GET_CODE (operands[2]) == CONST_INT 5999 && (INTVAL (operands[2]) == 128 6000 || (INTVAL (operands[2]) < 0 6001 && INTVAL (operands[2]) != -128))) 6002 { 6003 operands[2] = GEN_INT (-INTVAL (operands[2])); 6004 return "sub{w}\t{%2, %0|%0, %2}"; 6005 } 6006 return "add{w}\t{%2, %0|%0, %2}"; 6007 } 6008} 6009 [(set (attr "type") 6010 (if_then_else (match_operand:HI 2 "incdec_operand" "") 6011 (const_string "incdec") 6012 (const_string "alu"))) 6013 (set_attr "mode" "HI")]) 6014 6015; See comments above addsi_4 for details. 6016(define_insn "*addhi_4" 6017 [(set (reg FLAGS_REG) 6018 (compare (match_operand:HI 1 "nonimmediate_operand" "0") 6019 (match_operand:HI 2 "const_int_operand" "n"))) 6020 (clobber (match_scratch:HI 0 "=rm"))] 6021 "ix86_match_ccmode (insn, CCGCmode) 6022 && (INTVAL (operands[2]) & 0xffff) != 0x8000" 6023{ 6024 switch (get_attr_type (insn)) 6025 { 6026 case TYPE_INCDEC: 6027 if (operands[2] == constm1_rtx) 6028 return "inc{w}\t%0"; 6029 else 6030 { 6031 gcc_assert (operands[2] == const1_rtx); 6032 return "dec{w}\t%0"; 6033 } 6034 6035 default: 6036 gcc_assert (rtx_equal_p (operands[0], operands[1])); 6037 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 6038 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 6039 if ((INTVAL (operands[2]) == -128 6040 || (INTVAL (operands[2]) > 0 6041 && INTVAL (operands[2]) != 128))) 6042 return "sub{w}\t{%2, %0|%0, %2}"; 6043 operands[2] = GEN_INT (-INTVAL (operands[2])); 6044 return "add{w}\t{%2, %0|%0, %2}"; 6045 } 6046} 6047 [(set (attr "type") 6048 (if_then_else (match_operand:HI 2 "incdec_operand" "") 6049 (const_string "incdec") 6050 (const_string "alu"))) 6051 (set_attr "mode" "SI")]) 6052 6053 6054(define_insn "*addhi_5" 6055 [(set (reg FLAGS_REG) 6056 (compare 6057 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0") 6058 (match_operand:HI 2 "general_operand" "rmni")) 6059 (const_int 0))) 6060 (clobber (match_scratch:HI 0 "=r"))] 6061 "ix86_match_ccmode (insn, CCGOCmode) 6062 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6063{ 6064 switch (get_attr_type (insn)) 6065 { 6066 case TYPE_INCDEC: 6067 if (operands[2] == const1_rtx) 6068 return "inc{w}\t%0"; 6069 else 6070 { 6071 gcc_assert (operands[2] == constm1_rtx); 6072 return "dec{w}\t%0"; 6073 } 6074 6075 default: 6076 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 6077 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 6078 if (GET_CODE (operands[2]) == CONST_INT 6079 && (INTVAL (operands[2]) == 128 6080 || (INTVAL (operands[2]) < 0 6081 && INTVAL (operands[2]) != -128))) 6082 { 6083 operands[2] = GEN_INT (-INTVAL (operands[2])); 6084 return "sub{w}\t{%2, %0|%0, %2}"; 6085 } 6086 return "add{w}\t{%2, %0|%0, %2}"; 6087 } 6088} 6089 [(set (attr "type") 6090 (if_then_else (match_operand:HI 2 "incdec_operand" "") 6091 (const_string "incdec") 6092 (const_string "alu"))) 6093 (set_attr "mode" "HI")]) 6094 6095(define_expand "addqi3" 6096 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") 6097 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "") 6098 (match_operand:QI 2 "general_operand" ""))) 6099 (clobber (reg:CC FLAGS_REG))])] 6100 "TARGET_QIMODE_MATH" 6101 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;") 6102 6103;; %%% Potential partial reg stall on alternative 2. What to do? 6104(define_insn "*addqi_1_lea" 6105 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r") 6106 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r") 6107 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln"))) 6108 (clobber (reg:CC FLAGS_REG))] 6109 "!TARGET_PARTIAL_REG_STALL 6110 && ix86_binary_operator_ok (PLUS, QImode, operands)" 6111{ 6112 int widen = (which_alternative == 2); 6113 switch (get_attr_type (insn)) 6114 { 6115 case TYPE_LEA: 6116 return "#"; 6117 case TYPE_INCDEC: 6118 if (operands[2] == const1_rtx) 6119 return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; 6120 else 6121 { 6122 gcc_assert (operands[2] == constm1_rtx); 6123 return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; 6124 } 6125 6126 default: 6127 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 6128 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 6129 if (GET_CODE (operands[2]) == CONST_INT 6130 && (INTVAL (operands[2]) == 128 6131 || (INTVAL (operands[2]) < 0 6132 && INTVAL (operands[2]) != -128))) 6133 { 6134 operands[2] = GEN_INT (-INTVAL (operands[2])); 6135 if (widen) 6136 return "sub{l}\t{%2, %k0|%k0, %2}"; 6137 else 6138 return "sub{b}\t{%2, %0|%0, %2}"; 6139 } 6140 if (widen) 6141 return "add{l}\t{%k2, %k0|%k0, %k2}"; 6142 else 6143 return "add{b}\t{%2, %0|%0, %2}"; 6144 } 6145} 6146 [(set (attr "type") 6147 (if_then_else (eq_attr "alternative" "3") 6148 (const_string "lea") 6149 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6150 (const_string "incdec") 6151 (const_string "alu")))) 6152 (set_attr "mode" "QI,QI,SI,SI")]) 6153 6154(define_insn "*addqi_1" 6155 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 6156 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 6157 (match_operand:QI 2 "general_operand" "qn,qmn,rn"))) 6158 (clobber (reg:CC FLAGS_REG))] 6159 "TARGET_PARTIAL_REG_STALL 6160 && ix86_binary_operator_ok (PLUS, QImode, operands)" 6161{ 6162 int widen = (which_alternative == 2); 6163 switch (get_attr_type (insn)) 6164 { 6165 case TYPE_INCDEC: 6166 if (operands[2] == const1_rtx) 6167 return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; 6168 else 6169 { 6170 gcc_assert (operands[2] == constm1_rtx); 6171 return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; 6172 } 6173 6174 default: 6175 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 6176 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 6177 if (GET_CODE (operands[2]) == CONST_INT 6178 && (INTVAL (operands[2]) == 128 6179 || (INTVAL (operands[2]) < 0 6180 && INTVAL (operands[2]) != -128))) 6181 { 6182 operands[2] = GEN_INT (-INTVAL (operands[2])); 6183 if (widen) 6184 return "sub{l}\t{%2, %k0|%k0, %2}"; 6185 else 6186 return "sub{b}\t{%2, %0|%0, %2}"; 6187 } 6188 if (widen) 6189 return "add{l}\t{%k2, %k0|%k0, %k2}"; 6190 else 6191 return "add{b}\t{%2, %0|%0, %2}"; 6192 } 6193} 6194 [(set (attr "type") 6195 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6196 (const_string "incdec") 6197 (const_string "alu"))) 6198 (set_attr "mode" "QI,QI,SI")]) 6199 6200(define_insn "*addqi_1_slp" 6201 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 6202 (plus:QI (match_dup 0) 6203 (match_operand:QI 1 "general_operand" "qn,qnm"))) 6204 (clobber (reg:CC FLAGS_REG))] 6205 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 6206 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 6207{ 6208 switch (get_attr_type (insn)) 6209 { 6210 case TYPE_INCDEC: 6211 if (operands[1] == const1_rtx) 6212 return "inc{b}\t%0"; 6213 else 6214 { 6215 gcc_assert (operands[1] == constm1_rtx); 6216 return "dec{b}\t%0"; 6217 } 6218 6219 default: 6220 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */ 6221 if (GET_CODE (operands[1]) == CONST_INT 6222 && INTVAL (operands[1]) < 0) 6223 { 6224 operands[1] = GEN_INT (-INTVAL (operands[1])); 6225 return "sub{b}\t{%1, %0|%0, %1}"; 6226 } 6227 return "add{b}\t{%1, %0|%0, %1}"; 6228 } 6229} 6230 [(set (attr "type") 6231 (if_then_else (match_operand:QI 1 "incdec_operand" "") 6232 (const_string "incdec") 6233 (const_string "alu1"))) 6234 (set (attr "memory") 6235 (if_then_else (match_operand 1 "memory_operand" "") 6236 (const_string "load") 6237 (const_string "none"))) 6238 (set_attr "mode" "QI")]) 6239 6240(define_insn "*addqi_2" 6241 [(set (reg FLAGS_REG) 6242 (compare 6243 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 6244 (match_operand:QI 2 "general_operand" "qmni,qni")) 6245 (const_int 0))) 6246 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 6247 (plus:QI (match_dup 1) (match_dup 2)))] 6248 "ix86_match_ccmode (insn, CCGOCmode) 6249 && ix86_binary_operator_ok (PLUS, QImode, operands)" 6250{ 6251 switch (get_attr_type (insn)) 6252 { 6253 case TYPE_INCDEC: 6254 if (operands[2] == const1_rtx) 6255 return "inc{b}\t%0"; 6256 else 6257 { 6258 gcc_assert (operands[2] == constm1_rtx 6259 || (GET_CODE (operands[2]) == CONST_INT 6260 && INTVAL (operands[2]) == 255)); 6261 return "dec{b}\t%0"; 6262 } 6263 6264 default: 6265 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ 6266 if (GET_CODE (operands[2]) == CONST_INT 6267 && INTVAL (operands[2]) < 0) 6268 { 6269 operands[2] = GEN_INT (-INTVAL (operands[2])); 6270 return "sub{b}\t{%2, %0|%0, %2}"; 6271 } 6272 return "add{b}\t{%2, %0|%0, %2}"; 6273 } 6274} 6275 [(set (attr "type") 6276 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6277 (const_string "incdec") 6278 (const_string "alu"))) 6279 (set_attr "mode" "QI")]) 6280 6281(define_insn "*addqi_3" 6282 [(set (reg FLAGS_REG) 6283 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni")) 6284 (match_operand:QI 1 "nonimmediate_operand" "%0"))) 6285 (clobber (match_scratch:QI 0 "=q"))] 6286 "ix86_match_ccmode (insn, CCZmode) 6287 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6288{ 6289 switch (get_attr_type (insn)) 6290 { 6291 case TYPE_INCDEC: 6292 if (operands[2] == const1_rtx) 6293 return "inc{b}\t%0"; 6294 else 6295 { 6296 gcc_assert (operands[2] == constm1_rtx 6297 || (GET_CODE (operands[2]) == CONST_INT 6298 && INTVAL (operands[2]) == 255)); 6299 return "dec{b}\t%0"; 6300 } 6301 6302 default: 6303 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ 6304 if (GET_CODE (operands[2]) == CONST_INT 6305 && INTVAL (operands[2]) < 0) 6306 { 6307 operands[2] = GEN_INT (-INTVAL (operands[2])); 6308 return "sub{b}\t{%2, %0|%0, %2}"; 6309 } 6310 return "add{b}\t{%2, %0|%0, %2}"; 6311 } 6312} 6313 [(set (attr "type") 6314 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6315 (const_string "incdec") 6316 (const_string "alu"))) 6317 (set_attr "mode" "QI")]) 6318 6319; See comments above addsi_4 for details. 6320(define_insn "*addqi_4" 6321 [(set (reg FLAGS_REG) 6322 (compare (match_operand:QI 1 "nonimmediate_operand" "0") 6323 (match_operand:QI 2 "const_int_operand" "n"))) 6324 (clobber (match_scratch:QI 0 "=qm"))] 6325 "ix86_match_ccmode (insn, CCGCmode) 6326 && (INTVAL (operands[2]) & 0xff) != 0x80" 6327{ 6328 switch (get_attr_type (insn)) 6329 { 6330 case TYPE_INCDEC: 6331 if (operands[2] == constm1_rtx 6332 || (GET_CODE (operands[2]) == CONST_INT 6333 && INTVAL (operands[2]) == 255)) 6334 return "inc{b}\t%0"; 6335 else 6336 { 6337 gcc_assert (operands[2] == const1_rtx); 6338 return "dec{b}\t%0"; 6339 } 6340 6341 default: 6342 gcc_assert (rtx_equal_p (operands[0], operands[1])); 6343 if (INTVAL (operands[2]) < 0) 6344 { 6345 operands[2] = GEN_INT (-INTVAL (operands[2])); 6346 return "add{b}\t{%2, %0|%0, %2}"; 6347 } 6348 return "sub{b}\t{%2, %0|%0, %2}"; 6349 } 6350} 6351 [(set (attr "type") 6352 (if_then_else (match_operand:HI 2 "incdec_operand" "") 6353 (const_string "incdec") 6354 (const_string "alu"))) 6355 (set_attr "mode" "QI")]) 6356 6357 6358(define_insn "*addqi_5" 6359 [(set (reg FLAGS_REG) 6360 (compare 6361 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 6362 (match_operand:QI 2 "general_operand" "qmni")) 6363 (const_int 0))) 6364 (clobber (match_scratch:QI 0 "=q"))] 6365 "ix86_match_ccmode (insn, CCGOCmode) 6366 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6367{ 6368 switch (get_attr_type (insn)) 6369 { 6370 case TYPE_INCDEC: 6371 if (operands[2] == const1_rtx) 6372 return "inc{b}\t%0"; 6373 else 6374 { 6375 gcc_assert (operands[2] == constm1_rtx 6376 || (GET_CODE (operands[2]) == CONST_INT 6377 && INTVAL (operands[2]) == 255)); 6378 return "dec{b}\t%0"; 6379 } 6380 6381 default: 6382 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ 6383 if (GET_CODE (operands[2]) == CONST_INT 6384 && INTVAL (operands[2]) < 0) 6385 { 6386 operands[2] = GEN_INT (-INTVAL (operands[2])); 6387 return "sub{b}\t{%2, %0|%0, %2}"; 6388 } 6389 return "add{b}\t{%2, %0|%0, %2}"; 6390 } 6391} 6392 [(set (attr "type") 6393 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6394 (const_string "incdec") 6395 (const_string "alu"))) 6396 (set_attr "mode" "QI")]) 6397 6398 6399(define_insn "addqi_ext_1" 6400 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6401 (const_int 8) 6402 (const_int 8)) 6403 (plus:SI 6404 (zero_extract:SI 6405 (match_operand 1 "ext_register_operand" "0") 6406 (const_int 8) 6407 (const_int 8)) 6408 (match_operand:QI 2 "general_operand" "Qmn"))) 6409 (clobber (reg:CC FLAGS_REG))] 6410 "!TARGET_64BIT" 6411{ 6412 switch (get_attr_type (insn)) 6413 { 6414 case TYPE_INCDEC: 6415 if (operands[2] == const1_rtx) 6416 return "inc{b}\t%h0"; 6417 else 6418 { 6419 gcc_assert (operands[2] == constm1_rtx 6420 || (GET_CODE (operands[2]) == CONST_INT 6421 && INTVAL (operands[2]) == 255)); 6422 return "dec{b}\t%h0"; 6423 } 6424 6425 default: 6426 return "add{b}\t{%2, %h0|%h0, %2}"; 6427 } 6428} 6429 [(set (attr "type") 6430 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6431 (const_string "incdec") 6432 (const_string "alu"))) 6433 (set_attr "mode" "QI")]) 6434 6435(define_insn "*addqi_ext_1_rex64" 6436 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6437 (const_int 8) 6438 (const_int 8)) 6439 (plus:SI 6440 (zero_extract:SI 6441 (match_operand 1 "ext_register_operand" "0") 6442 (const_int 8) 6443 (const_int 8)) 6444 (match_operand:QI 2 "nonmemory_operand" "Qn"))) 6445 (clobber (reg:CC FLAGS_REG))] 6446 "TARGET_64BIT" 6447{ 6448 switch (get_attr_type (insn)) 6449 { 6450 case TYPE_INCDEC: 6451 if (operands[2] == const1_rtx) 6452 return "inc{b}\t%h0"; 6453 else 6454 { 6455 gcc_assert (operands[2] == constm1_rtx 6456 || (GET_CODE (operands[2]) == CONST_INT 6457 && INTVAL (operands[2]) == 255)); 6458 return "dec{b}\t%h0"; 6459 } 6460 6461 default: 6462 return "add{b}\t{%2, %h0|%h0, %2}"; 6463 } 6464} 6465 [(set (attr "type") 6466 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6467 (const_string "incdec") 6468 (const_string "alu"))) 6469 (set_attr "mode" "QI")]) 6470 6471(define_insn "*addqi_ext_2" 6472 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6473 (const_int 8) 6474 (const_int 8)) 6475 (plus:SI 6476 (zero_extract:SI 6477 (match_operand 1 "ext_register_operand" "%0") 6478 (const_int 8) 6479 (const_int 8)) 6480 (zero_extract:SI 6481 (match_operand 2 "ext_register_operand" "Q") 6482 (const_int 8) 6483 (const_int 8)))) 6484 (clobber (reg:CC FLAGS_REG))] 6485 "" 6486 "add{b}\t{%h2, %h0|%h0, %h2}" 6487 [(set_attr "type" "alu") 6488 (set_attr "mode" "QI")]) 6489 6490;; The patterns that match these are at the end of this file. 6491 6492(define_expand "addxf3" 6493 [(set (match_operand:XF 0 "register_operand" "") 6494 (plus:XF (match_operand:XF 1 "register_operand" "") 6495 (match_operand:XF 2 "register_operand" "")))] 6496 "TARGET_80387" 6497 "") 6498 6499(define_expand "adddf3" 6500 [(set (match_operand:DF 0 "register_operand" "") 6501 (plus:DF (match_operand:DF 1 "register_operand" "") 6502 (match_operand:DF 2 "nonimmediate_operand" "")))] 6503 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 6504 "") 6505 6506(define_expand "addsf3" 6507 [(set (match_operand:SF 0 "register_operand" "") 6508 (plus:SF (match_operand:SF 1 "register_operand" "") 6509 (match_operand:SF 2 "nonimmediate_operand" "")))] 6510 "TARGET_80387 || TARGET_SSE_MATH" 6511 "") 6512 6513;; Subtract instructions 6514 6515;; %%% splits for subditi3 6516 6517(define_expand "subti3" 6518 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "") 6519 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "") 6520 (match_operand:TI 2 "x86_64_general_operand" ""))) 6521 (clobber (reg:CC FLAGS_REG))])] 6522 "TARGET_64BIT" 6523 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;") 6524 6525(define_insn "*subti3_1" 6526 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o") 6527 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0") 6528 (match_operand:TI 2 "x86_64_general_operand" "roe,re"))) 6529 (clobber (reg:CC FLAGS_REG))] 6530 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)" 6531 "#") 6532 6533(define_split 6534 [(set (match_operand:TI 0 "nonimmediate_operand" "") 6535 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "") 6536 (match_operand:TI 2 "x86_64_general_operand" ""))) 6537 (clobber (reg:CC FLAGS_REG))] 6538 "TARGET_64BIT && reload_completed" 6539 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2))) 6540 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))]) 6541 (parallel [(set (match_dup 3) 6542 (minus:DI (match_dup 4) 6543 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) 6544 (match_dup 5)))) 6545 (clobber (reg:CC FLAGS_REG))])] 6546 "split_ti (operands+0, 1, operands+0, operands+3); 6547 split_ti (operands+1, 1, operands+1, operands+4); 6548 split_ti (operands+2, 1, operands+2, operands+5);") 6549 6550;; %%% splits for subsidi3 6551 6552(define_expand "subdi3" 6553 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 6554 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "") 6555 (match_operand:DI 2 "x86_64_general_operand" ""))) 6556 (clobber (reg:CC FLAGS_REG))])] 6557 "" 6558 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;") 6559 6560(define_insn "*subdi3_1" 6561 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") 6562 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6563 (match_operand:DI 2 "general_operand" "roiF,riF"))) 6564 (clobber (reg:CC FLAGS_REG))] 6565 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" 6566 "#") 6567 6568(define_split 6569 [(set (match_operand:DI 0 "nonimmediate_operand" "") 6570 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "") 6571 (match_operand:DI 2 "general_operand" ""))) 6572 (clobber (reg:CC FLAGS_REG))] 6573 "!TARGET_64BIT && reload_completed" 6574 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2))) 6575 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 6576 (parallel [(set (match_dup 3) 6577 (minus:SI (match_dup 4) 6578 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) 6579 (match_dup 5)))) 6580 (clobber (reg:CC FLAGS_REG))])] 6581 "split_di (operands+0, 1, operands+0, operands+3); 6582 split_di (operands+1, 1, operands+1, operands+4); 6583 split_di (operands+2, 1, operands+2, operands+5);") 6584 6585(define_insn "subdi3_carry_rex64" 6586 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6587 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6588 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "") 6589 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))) 6590 (clobber (reg:CC FLAGS_REG))] 6591 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" 6592 "sbb{q}\t{%2, %0|%0, %2}" 6593 [(set_attr "type" "alu") 6594 (set_attr "pent_pair" "pu") 6595 (set_attr "mode" "DI")]) 6596 6597(define_insn "*subdi_1_rex64" 6598 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6599 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6600 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 6601 (clobber (reg:CC FLAGS_REG))] 6602 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" 6603 "sub{q}\t{%2, %0|%0, %2}" 6604 [(set_attr "type" "alu") 6605 (set_attr "mode" "DI")]) 6606 6607(define_insn "*subdi_2_rex64" 6608 [(set (reg FLAGS_REG) 6609 (compare 6610 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6611 (match_operand:DI 2 "x86_64_general_operand" "re,rm")) 6612 (const_int 0))) 6613 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6614 (minus:DI (match_dup 1) (match_dup 2)))] 6615 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 6616 && ix86_binary_operator_ok (MINUS, DImode, operands)" 6617 "sub{q}\t{%2, %0|%0, %2}" 6618 [(set_attr "type" "alu") 6619 (set_attr "mode" "DI")]) 6620 6621(define_insn "*subdi_3_rex63" 6622 [(set (reg FLAGS_REG) 6623 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0") 6624 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 6625 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6626 (minus:DI (match_dup 1) (match_dup 2)))] 6627 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 6628 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6629 "sub{q}\t{%2, %0|%0, %2}" 6630 [(set_attr "type" "alu") 6631 (set_attr "mode" "DI")]) 6632 6633(define_insn "subqi3_carry" 6634 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 6635 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 6636 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "") 6637 (match_operand:QI 2 "general_operand" "qi,qm")))) 6638 (clobber (reg:CC FLAGS_REG))] 6639 "ix86_binary_operator_ok (MINUS, QImode, operands)" 6640 "sbb{b}\t{%2, %0|%0, %2}" 6641 [(set_attr "type" "alu") 6642 (set_attr "pent_pair" "pu") 6643 (set_attr "mode" "QI")]) 6644 6645(define_insn "subhi3_carry" 6646 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6647 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 6648 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "") 6649 (match_operand:HI 2 "general_operand" "ri,rm")))) 6650 (clobber (reg:CC FLAGS_REG))] 6651 "ix86_binary_operator_ok (MINUS, HImode, operands)" 6652 "sbb{w}\t{%2, %0|%0, %2}" 6653 [(set_attr "type" "alu") 6654 (set_attr "pent_pair" "pu") 6655 (set_attr "mode" "HI")]) 6656 6657(define_insn "subsi3_carry" 6658 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6659 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6660 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 6661 (match_operand:SI 2 "general_operand" "ri,rm")))) 6662 (clobber (reg:CC FLAGS_REG))] 6663 "ix86_binary_operator_ok (MINUS, SImode, operands)" 6664 "sbb{l}\t{%2, %0|%0, %2}" 6665 [(set_attr "type" "alu") 6666 (set_attr "pent_pair" "pu") 6667 (set_attr "mode" "SI")]) 6668 6669(define_insn "subsi3_carry_zext" 6670 [(set (match_operand:DI 0 "register_operand" "=rm,r") 6671 (zero_extend:DI 6672 (minus:SI (match_operand:SI 1 "register_operand" "0,0") 6673 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 6674 (match_operand:SI 2 "general_operand" "ri,rm"))))) 6675 (clobber (reg:CC FLAGS_REG))] 6676 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6677 "sbb{l}\t{%2, %k0|%k0, %2}" 6678 [(set_attr "type" "alu") 6679 (set_attr "pent_pair" "pu") 6680 (set_attr "mode" "SI")]) 6681 6682(define_expand "subsi3" 6683 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 6684 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "") 6685 (match_operand:SI 2 "general_operand" ""))) 6686 (clobber (reg:CC FLAGS_REG))])] 6687 "" 6688 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;") 6689 6690(define_insn "*subsi_1" 6691 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6692 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6693 (match_operand:SI 2 "general_operand" "ri,rm"))) 6694 (clobber (reg:CC FLAGS_REG))] 6695 "ix86_binary_operator_ok (MINUS, SImode, operands)" 6696 "sub{l}\t{%2, %0|%0, %2}" 6697 [(set_attr "type" "alu") 6698 (set_attr "mode" "SI")]) 6699 6700(define_insn "*subsi_1_zext" 6701 [(set (match_operand:DI 0 "register_operand" "=r") 6702 (zero_extend:DI 6703 (minus:SI (match_operand:SI 1 "register_operand" "0") 6704 (match_operand:SI 2 "general_operand" "rim")))) 6705 (clobber (reg:CC FLAGS_REG))] 6706 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6707 "sub{l}\t{%2, %k0|%k0, %2}" 6708 [(set_attr "type" "alu") 6709 (set_attr "mode" "SI")]) 6710 6711(define_insn "*subsi_2" 6712 [(set (reg FLAGS_REG) 6713 (compare 6714 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6715 (match_operand:SI 2 "general_operand" "ri,rm")) 6716 (const_int 0))) 6717 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6718 (minus:SI (match_dup 1) (match_dup 2)))] 6719 "ix86_match_ccmode (insn, CCGOCmode) 6720 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6721 "sub{l}\t{%2, %0|%0, %2}" 6722 [(set_attr "type" "alu") 6723 (set_attr "mode" "SI")]) 6724 6725(define_insn "*subsi_2_zext" 6726 [(set (reg FLAGS_REG) 6727 (compare 6728 (minus:SI (match_operand:SI 1 "register_operand" "0") 6729 (match_operand:SI 2 "general_operand" "rim")) 6730 (const_int 0))) 6731 (set (match_operand:DI 0 "register_operand" "=r") 6732 (zero_extend:DI 6733 (minus:SI (match_dup 1) 6734 (match_dup 2))))] 6735 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 6736 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6737 "sub{l}\t{%2, %k0|%k0, %2}" 6738 [(set_attr "type" "alu") 6739 (set_attr "mode" "SI")]) 6740 6741(define_insn "*subsi_3" 6742 [(set (reg FLAGS_REG) 6743 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0") 6744 (match_operand:SI 2 "general_operand" "ri,rm"))) 6745 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6746 (minus:SI (match_dup 1) (match_dup 2)))] 6747 "ix86_match_ccmode (insn, CCmode) 6748 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6749 "sub{l}\t{%2, %0|%0, %2}" 6750 [(set_attr "type" "alu") 6751 (set_attr "mode" "SI")]) 6752 6753(define_insn "*subsi_3_zext" 6754 [(set (reg FLAGS_REG) 6755 (compare (match_operand:SI 1 "register_operand" "0") 6756 (match_operand:SI 2 "general_operand" "rim"))) 6757 (set (match_operand:DI 0 "register_operand" "=r") 6758 (zero_extend:DI 6759 (minus:SI (match_dup 1) 6760 (match_dup 2))))] 6761 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 6762 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6763 "sub{l}\t{%2, %1|%1, %2}" 6764 [(set_attr "type" "alu") 6765 (set_attr "mode" "DI")]) 6766 6767(define_expand "subhi3" 6768 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 6769 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "") 6770 (match_operand:HI 2 "general_operand" ""))) 6771 (clobber (reg:CC FLAGS_REG))])] 6772 "TARGET_HIMODE_MATH" 6773 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;") 6774 6775(define_insn "*subhi_1" 6776 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6777 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 6778 (match_operand:HI 2 "general_operand" "ri,rm"))) 6779 (clobber (reg:CC FLAGS_REG))] 6780 "ix86_binary_operator_ok (MINUS, HImode, operands)" 6781 "sub{w}\t{%2, %0|%0, %2}" 6782 [(set_attr "type" "alu") 6783 (set_attr "mode" "HI")]) 6784 6785(define_insn "*subhi_2" 6786 [(set (reg FLAGS_REG) 6787 (compare 6788 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 6789 (match_operand:HI 2 "general_operand" "ri,rm")) 6790 (const_int 0))) 6791 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6792 (minus:HI (match_dup 1) (match_dup 2)))] 6793 "ix86_match_ccmode (insn, CCGOCmode) 6794 && ix86_binary_operator_ok (MINUS, HImode, operands)" 6795 "sub{w}\t{%2, %0|%0, %2}" 6796 [(set_attr "type" "alu") 6797 (set_attr "mode" "HI")]) 6798 6799(define_insn "*subhi_3" 6800 [(set (reg FLAGS_REG) 6801 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0") 6802 (match_operand:HI 2 "general_operand" "ri,rm"))) 6803 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6804 (minus:HI (match_dup 1) (match_dup 2)))] 6805 "ix86_match_ccmode (insn, CCmode) 6806 && ix86_binary_operator_ok (MINUS, HImode, operands)" 6807 "sub{w}\t{%2, %0|%0, %2}" 6808 [(set_attr "type" "alu") 6809 (set_attr "mode" "HI")]) 6810 6811(define_expand "subqi3" 6812 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") 6813 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "") 6814 (match_operand:QI 2 "general_operand" ""))) 6815 (clobber (reg:CC FLAGS_REG))])] 6816 "TARGET_QIMODE_MATH" 6817 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;") 6818 6819(define_insn "*subqi_1" 6820 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 6821 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 6822 (match_operand:QI 2 "general_operand" "qn,qmn"))) 6823 (clobber (reg:CC FLAGS_REG))] 6824 "ix86_binary_operator_ok (MINUS, QImode, operands)" 6825 "sub{b}\t{%2, %0|%0, %2}" 6826 [(set_attr "type" "alu") 6827 (set_attr "mode" "QI")]) 6828 6829(define_insn "*subqi_1_slp" 6830 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 6831 (minus:QI (match_dup 0) 6832 (match_operand:QI 1 "general_operand" "qn,qmn"))) 6833 (clobber (reg:CC FLAGS_REG))] 6834 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 6835 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 6836 "sub{b}\t{%1, %0|%0, %1}" 6837 [(set_attr "type" "alu1") 6838 (set_attr "mode" "QI")]) 6839 6840(define_insn "*subqi_2" 6841 [(set (reg FLAGS_REG) 6842 (compare 6843 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 6844 (match_operand:QI 2 "general_operand" "qi,qm")) 6845 (const_int 0))) 6846 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q") 6847 (minus:HI (match_dup 1) (match_dup 2)))] 6848 "ix86_match_ccmode (insn, CCGOCmode) 6849 && ix86_binary_operator_ok (MINUS, QImode, operands)" 6850 "sub{b}\t{%2, %0|%0, %2}" 6851 [(set_attr "type" "alu") 6852 (set_attr "mode" "QI")]) 6853 6854(define_insn "*subqi_3" 6855 [(set (reg FLAGS_REG) 6856 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0") 6857 (match_operand:QI 2 "general_operand" "qi,qm"))) 6858 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q") 6859 (minus:HI (match_dup 1) (match_dup 2)))] 6860 "ix86_match_ccmode (insn, CCmode) 6861 && ix86_binary_operator_ok (MINUS, QImode, operands)" 6862 "sub{b}\t{%2, %0|%0, %2}" 6863 [(set_attr "type" "alu") 6864 (set_attr "mode" "QI")]) 6865 6866;; The patterns that match these are at the end of this file. 6867 6868(define_expand "subxf3" 6869 [(set (match_operand:XF 0 "register_operand" "") 6870 (minus:XF (match_operand:XF 1 "register_operand" "") 6871 (match_operand:XF 2 "register_operand" "")))] 6872 "TARGET_80387" 6873 "") 6874 6875(define_expand "subdf3" 6876 [(set (match_operand:DF 0 "register_operand" "") 6877 (minus:DF (match_operand:DF 1 "register_operand" "") 6878 (match_operand:DF 2 "nonimmediate_operand" "")))] 6879 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 6880 "") 6881 6882(define_expand "subsf3" 6883 [(set (match_operand:SF 0 "register_operand" "") 6884 (minus:SF (match_operand:SF 1 "register_operand" "") 6885 (match_operand:SF 2 "nonimmediate_operand" "")))] 6886 "TARGET_80387 || TARGET_SSE_MATH" 6887 "") 6888 6889;; Multiply instructions 6890 6891(define_expand "muldi3" 6892 [(parallel [(set (match_operand:DI 0 "register_operand" "") 6893 (mult:DI (match_operand:DI 1 "register_operand" "") 6894 (match_operand:DI 2 "x86_64_general_operand" ""))) 6895 (clobber (reg:CC FLAGS_REG))])] 6896 "TARGET_64BIT" 6897 "") 6898 6899;; On AMDFAM10 6900;; IMUL reg64, reg64, imm8 Direct 6901;; IMUL reg64, mem64, imm8 VectorPath 6902;; IMUL reg64, reg64, imm32 Direct 6903;; IMUL reg64, mem64, imm32 VectorPath 6904;; IMUL reg64, reg64 Direct 6905;; IMUL reg64, mem64 Direct 6906 6907(define_insn "*muldi3_1_rex64" 6908 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 6909 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0") 6910 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr"))) 6911 (clobber (reg:CC FLAGS_REG))] 6912 "TARGET_64BIT 6913 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6914 "@ 6915 imul{q}\t{%2, %1, %0|%0, %1, %2} 6916 imul{q}\t{%2, %1, %0|%0, %1, %2} 6917 imul{q}\t{%2, %0|%0, %2}" 6918 [(set_attr "type" "imul") 6919 (set_attr "prefix_0f" "0,0,1") 6920 (set (attr "athlon_decode") 6921 (cond [(eq_attr "cpu" "athlon") 6922 (const_string "vector") 6923 (eq_attr "alternative" "1") 6924 (const_string "vector") 6925 (and (eq_attr "alternative" "2") 6926 (match_operand 1 "memory_operand" "")) 6927 (const_string "vector")] 6928 (const_string "direct"))) 6929 (set (attr "amdfam10_decode") 6930 (cond [(and (eq_attr "alternative" "0,1") 6931 (match_operand 1 "memory_operand" "")) 6932 (const_string "vector")] 6933 (const_string "direct"))) 6934 (set_attr "mode" "DI")]) 6935 6936(define_expand "mulsi3" 6937 [(parallel [(set (match_operand:SI 0 "register_operand" "") 6938 (mult:SI (match_operand:SI 1 "register_operand" "") 6939 (match_operand:SI 2 "general_operand" ""))) 6940 (clobber (reg:CC FLAGS_REG))])] 6941 "" 6942 "") 6943 6944;; On AMDFAM10 6945;; IMUL reg32, reg32, imm8 Direct 6946;; IMUL reg32, mem32, imm8 VectorPath 6947;; IMUL reg32, reg32, imm32 Direct 6948;; IMUL reg32, mem32, imm32 VectorPath 6949;; IMUL reg32, reg32 Direct 6950;; IMUL reg32, mem32 Direct 6951 6952(define_insn "*mulsi3_1" 6953 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 6954 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") 6955 (match_operand:SI 2 "general_operand" "K,i,mr"))) 6956 (clobber (reg:CC FLAGS_REG))] 6957 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 6958 "@ 6959 imul{l}\t{%2, %1, %0|%0, %1, %2} 6960 imul{l}\t{%2, %1, %0|%0, %1, %2} 6961 imul{l}\t{%2, %0|%0, %2}" 6962 [(set_attr "type" "imul") 6963 (set_attr "prefix_0f" "0,0,1") 6964 (set (attr "athlon_decode") 6965 (cond [(eq_attr "cpu" "athlon") 6966 (const_string "vector") 6967 (eq_attr "alternative" "1") 6968 (const_string "vector") 6969 (and (eq_attr "alternative" "2") 6970 (match_operand 1 "memory_operand" "")) 6971 (const_string "vector")] 6972 (const_string "direct"))) 6973 (set (attr "amdfam10_decode") 6974 (cond [(and (eq_attr "alternative" "0,1") 6975 (match_operand 1 "memory_operand" "")) 6976 (const_string "vector")] 6977 (const_string "direct"))) 6978 (set_attr "mode" "SI")]) 6979 6980(define_insn "*mulsi3_1_zext" 6981 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 6982 (zero_extend:DI 6983 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") 6984 (match_operand:SI 2 "general_operand" "K,i,mr")))) 6985 (clobber (reg:CC FLAGS_REG))] 6986 "TARGET_64BIT 6987 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6988 "@ 6989 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6990 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6991 imul{l}\t{%2, %k0|%k0, %2}" 6992 [(set_attr "type" "imul") 6993 (set_attr "prefix_0f" "0,0,1") 6994 (set (attr "athlon_decode") 6995 (cond [(eq_attr "cpu" "athlon") 6996 (const_string "vector") 6997 (eq_attr "alternative" "1") 6998 (const_string "vector") 6999 (and (eq_attr "alternative" "2") 7000 (match_operand 1 "memory_operand" "")) 7001 (const_string "vector")] 7002 (const_string "direct"))) 7003 (set (attr "amdfam10_decode") 7004 (cond [(and (eq_attr "alternative" "0,1") 7005 (match_operand 1 "memory_operand" "")) 7006 (const_string "vector")] 7007 (const_string "direct"))) 7008 (set_attr "mode" "SI")]) 7009 7010(define_expand "mulhi3" 7011 [(parallel [(set (match_operand:HI 0 "register_operand" "") 7012 (mult:HI (match_operand:HI 1 "register_operand" "") 7013 (match_operand:HI 2 "general_operand" ""))) 7014 (clobber (reg:CC FLAGS_REG))])] 7015 "TARGET_HIMODE_MATH" 7016 "") 7017 7018;; On AMDFAM10 7019;; IMUL reg16, reg16, imm8 VectorPath 7020;; IMUL reg16, mem16, imm8 VectorPath 7021;; IMUL reg16, reg16, imm16 VectorPath 7022;; IMUL reg16, mem16, imm16 VectorPath 7023;; IMUL reg16, reg16 Direct 7024;; IMUL reg16, mem16 Direct 7025(define_insn "*mulhi3_1" 7026 [(set (match_operand:HI 0 "register_operand" "=r,r,r") 7027 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0") 7028 (match_operand:HI 2 "general_operand" "K,i,mr"))) 7029 (clobber (reg:CC FLAGS_REG))] 7030 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 7031 "@ 7032 imul{w}\t{%2, %1, %0|%0, %1, %2} 7033 imul{w}\t{%2, %1, %0|%0, %1, %2} 7034 imul{w}\t{%2, %0|%0, %2}" 7035 [(set_attr "type" "imul") 7036 (set_attr "prefix_0f" "0,0,1") 7037 (set (attr "athlon_decode") 7038 (cond [(eq_attr "cpu" "athlon") 7039 (const_string "vector") 7040 (eq_attr "alternative" "1,2") 7041 (const_string "vector")] 7042 (const_string "direct"))) 7043 (set (attr "amdfam10_decode") 7044 (cond [(eq_attr "alternative" "0,1") 7045 (const_string "vector")] 7046 (const_string "direct"))) 7047 (set_attr "mode" "HI")]) 7048 7049(define_expand "mulqi3" 7050 [(parallel [(set (match_operand:QI 0 "register_operand" "") 7051 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "") 7052 (match_operand:QI 2 "register_operand" ""))) 7053 (clobber (reg:CC FLAGS_REG))])] 7054 "TARGET_QIMODE_MATH" 7055 "") 7056 7057;;On AMDFAM10 7058;; MUL reg8 Direct 7059;; MUL mem8 Direct 7060 7061(define_insn "*mulqi3_1" 7062 [(set (match_operand:QI 0 "register_operand" "=a") 7063 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 7064 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 7065 (clobber (reg:CC FLAGS_REG))] 7066 "TARGET_QIMODE_MATH 7067 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7068 "mul{b}\t%2" 7069 [(set_attr "type" "imul") 7070 (set_attr "length_immediate" "0") 7071 (set (attr "athlon_decode") 7072 (if_then_else (eq_attr "cpu" "athlon") 7073 (const_string "vector") 7074 (const_string "direct"))) 7075 (set_attr "amdfam10_decode" "direct") 7076 (set_attr "mode" "QI")]) 7077 7078(define_expand "umulqihi3" 7079 [(parallel [(set (match_operand:HI 0 "register_operand" "") 7080 (mult:HI (zero_extend:HI 7081 (match_operand:QI 1 "nonimmediate_operand" "")) 7082 (zero_extend:HI 7083 (match_operand:QI 2 "register_operand" "")))) 7084 (clobber (reg:CC FLAGS_REG))])] 7085 "TARGET_QIMODE_MATH" 7086 "") 7087 7088(define_insn "*umulqihi3_1" 7089 [(set (match_operand:HI 0 "register_operand" "=a") 7090 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0")) 7091 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm")))) 7092 (clobber (reg:CC FLAGS_REG))] 7093 "TARGET_QIMODE_MATH 7094 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7095 "mul{b}\t%2" 7096 [(set_attr "type" "imul") 7097 (set_attr "length_immediate" "0") 7098 (set (attr "athlon_decode") 7099 (if_then_else (eq_attr "cpu" "athlon") 7100 (const_string "vector") 7101 (const_string "direct"))) 7102 (set_attr "amdfam10_decode" "direct") 7103 (set_attr "mode" "QI")]) 7104 7105(define_expand "mulqihi3" 7106 [(parallel [(set (match_operand:HI 0 "register_operand" "") 7107 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")) 7108 (sign_extend:HI (match_operand:QI 2 "register_operand" "")))) 7109 (clobber (reg:CC FLAGS_REG))])] 7110 "TARGET_QIMODE_MATH" 7111 "") 7112 7113(define_insn "*mulqihi3_insn" 7114 [(set (match_operand:HI 0 "register_operand" "=a") 7115 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0")) 7116 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm")))) 7117 (clobber (reg:CC FLAGS_REG))] 7118 "TARGET_QIMODE_MATH 7119 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7120 "imul{b}\t%2" 7121 [(set_attr "type" "imul") 7122 (set_attr "length_immediate" "0") 7123 (set (attr "athlon_decode") 7124 (if_then_else (eq_attr "cpu" "athlon") 7125 (const_string "vector") 7126 (const_string "direct"))) 7127 (set_attr "amdfam10_decode" "direct") 7128 (set_attr "mode" "QI")]) 7129 7130(define_expand "umulditi3" 7131 [(parallel [(set (match_operand:TI 0 "register_operand" "") 7132 (mult:TI (zero_extend:TI 7133 (match_operand:DI 1 "nonimmediate_operand" "")) 7134 (zero_extend:TI 7135 (match_operand:DI 2 "register_operand" "")))) 7136 (clobber (reg:CC FLAGS_REG))])] 7137 "TARGET_64BIT" 7138 "") 7139 7140(define_insn "*umulditi3_insn" 7141 [(set (match_operand:TI 0 "register_operand" "=A") 7142 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0")) 7143 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm")))) 7144 (clobber (reg:CC FLAGS_REG))] 7145 "TARGET_64BIT 7146 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7147 "mul{q}\t%2" 7148 [(set_attr "type" "imul") 7149 (set_attr "length_immediate" "0") 7150 (set (attr "athlon_decode") 7151 (if_then_else (eq_attr "cpu" "athlon") 7152 (const_string "vector") 7153 (const_string "double"))) 7154 (set_attr "amdfam10_decode" "double") 7155 (set_attr "mode" "DI")]) 7156 7157;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers 7158(define_expand "umulsidi3" 7159 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7160 (mult:DI (zero_extend:DI 7161 (match_operand:SI 1 "nonimmediate_operand" "")) 7162 (zero_extend:DI 7163 (match_operand:SI 2 "register_operand" "")))) 7164 (clobber (reg:CC FLAGS_REG))])] 7165 "!TARGET_64BIT" 7166 "") 7167 7168(define_insn "*umulsidi3_insn" 7169 [(set (match_operand:DI 0 "register_operand" "=A") 7170 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0")) 7171 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))) 7172 (clobber (reg:CC FLAGS_REG))] 7173 "!TARGET_64BIT 7174 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7175 "mul{l}\t%2" 7176 [(set_attr "type" "imul") 7177 (set_attr "length_immediate" "0") 7178 (set (attr "athlon_decode") 7179 (if_then_else (eq_attr "cpu" "athlon") 7180 (const_string "vector") 7181 (const_string "double"))) 7182 (set_attr "amdfam10_decode" "double") 7183 (set_attr "mode" "SI")]) 7184 7185(define_expand "mulditi3" 7186 [(parallel [(set (match_operand:TI 0 "register_operand" "") 7187 (mult:TI (sign_extend:TI 7188 (match_operand:DI 1 "nonimmediate_operand" "")) 7189 (sign_extend:TI 7190 (match_operand:DI 2 "register_operand" "")))) 7191 (clobber (reg:CC FLAGS_REG))])] 7192 "TARGET_64BIT" 7193 "") 7194 7195(define_insn "*mulditi3_insn" 7196 [(set (match_operand:TI 0 "register_operand" "=A") 7197 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0")) 7198 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm")))) 7199 (clobber (reg:CC FLAGS_REG))] 7200 "TARGET_64BIT 7201 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7202 "imul{q}\t%2" 7203 [(set_attr "type" "imul") 7204 (set_attr "length_immediate" "0") 7205 (set (attr "athlon_decode") 7206 (if_then_else (eq_attr "cpu" "athlon") 7207 (const_string "vector") 7208 (const_string "double"))) 7209 (set_attr "amdfam10_decode" "double") 7210 (set_attr "mode" "DI")]) 7211 7212(define_expand "mulsidi3" 7213 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7214 (mult:DI (sign_extend:DI 7215 (match_operand:SI 1 "nonimmediate_operand" "")) 7216 (sign_extend:DI 7217 (match_operand:SI 2 "register_operand" "")))) 7218 (clobber (reg:CC FLAGS_REG))])] 7219 "!TARGET_64BIT" 7220 "") 7221 7222(define_insn "*mulsidi3_insn" 7223 [(set (match_operand:DI 0 "register_operand" "=A") 7224 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0")) 7225 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))) 7226 (clobber (reg:CC FLAGS_REG))] 7227 "!TARGET_64BIT 7228 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7229 "imul{l}\t%2" 7230 [(set_attr "type" "imul") 7231 (set_attr "length_immediate" "0") 7232 (set (attr "athlon_decode") 7233 (if_then_else (eq_attr "cpu" "athlon") 7234 (const_string "vector") 7235 (const_string "double"))) 7236 (set_attr "amdfam10_decode" "double") 7237 (set_attr "mode" "SI")]) 7238 7239(define_expand "umuldi3_highpart" 7240 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7241 (truncate:DI 7242 (lshiftrt:TI 7243 (mult:TI (zero_extend:TI 7244 (match_operand:DI 1 "nonimmediate_operand" "")) 7245 (zero_extend:TI 7246 (match_operand:DI 2 "register_operand" ""))) 7247 (const_int 64)))) 7248 (clobber (match_scratch:DI 3 "")) 7249 (clobber (reg:CC FLAGS_REG))])] 7250 "TARGET_64BIT" 7251 "") 7252 7253(define_insn "*umuldi3_highpart_rex64" 7254 [(set (match_operand:DI 0 "register_operand" "=d") 7255 (truncate:DI 7256 (lshiftrt:TI 7257 (mult:TI (zero_extend:TI 7258 (match_operand:DI 1 "nonimmediate_operand" "%a")) 7259 (zero_extend:TI 7260 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7261 (const_int 64)))) 7262 (clobber (match_scratch:DI 3 "=1")) 7263 (clobber (reg:CC FLAGS_REG))] 7264 "TARGET_64BIT 7265 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7266 "mul{q}\t%2" 7267 [(set_attr "type" "imul") 7268 (set_attr "length_immediate" "0") 7269 (set (attr "athlon_decode") 7270 (if_then_else (eq_attr "cpu" "athlon") 7271 (const_string "vector") 7272 (const_string "double"))) 7273 (set_attr "amdfam10_decode" "double") 7274 (set_attr "mode" "DI")]) 7275 7276(define_expand "umulsi3_highpart" 7277 [(parallel [(set (match_operand:SI 0 "register_operand" "") 7278 (truncate:SI 7279 (lshiftrt:DI 7280 (mult:DI (zero_extend:DI 7281 (match_operand:SI 1 "nonimmediate_operand" "")) 7282 (zero_extend:DI 7283 (match_operand:SI 2 "register_operand" ""))) 7284 (const_int 32)))) 7285 (clobber (match_scratch:SI 3 "")) 7286 (clobber (reg:CC FLAGS_REG))])] 7287 "" 7288 "") 7289 7290(define_insn "*umulsi3_highpart_insn" 7291 [(set (match_operand:SI 0 "register_operand" "=d") 7292 (truncate:SI 7293 (lshiftrt:DI 7294 (mult:DI (zero_extend:DI 7295 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7296 (zero_extend:DI 7297 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7298 (const_int 32)))) 7299 (clobber (match_scratch:SI 3 "=1")) 7300 (clobber (reg:CC FLAGS_REG))] 7301 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 7302 "mul{l}\t%2" 7303 [(set_attr "type" "imul") 7304 (set_attr "length_immediate" "0") 7305 (set (attr "athlon_decode") 7306 (if_then_else (eq_attr "cpu" "athlon") 7307 (const_string "vector") 7308 (const_string "double"))) 7309 (set_attr "amdfam10_decode" "double") 7310 (set_attr "mode" "SI")]) 7311 7312(define_insn "*umulsi3_highpart_zext" 7313 [(set (match_operand:DI 0 "register_operand" "=d") 7314 (zero_extend:DI (truncate:SI 7315 (lshiftrt:DI 7316 (mult:DI (zero_extend:DI 7317 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7318 (zero_extend:DI 7319 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7320 (const_int 32))))) 7321 (clobber (match_scratch:SI 3 "=1")) 7322 (clobber (reg:CC FLAGS_REG))] 7323 "TARGET_64BIT 7324 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7325 "mul{l}\t%2" 7326 [(set_attr "type" "imul") 7327 (set_attr "length_immediate" "0") 7328 (set (attr "athlon_decode") 7329 (if_then_else (eq_attr "cpu" "athlon") 7330 (const_string "vector") 7331 (const_string "double"))) 7332 (set_attr "amdfam10_decode" "double") 7333 (set_attr "mode" "SI")]) 7334 7335(define_expand "smuldi3_highpart" 7336 [(parallel [(set (match_operand:DI 0 "register_operand" "=d") 7337 (truncate:DI 7338 (lshiftrt:TI 7339 (mult:TI (sign_extend:TI 7340 (match_operand:DI 1 "nonimmediate_operand" "")) 7341 (sign_extend:TI 7342 (match_operand:DI 2 "register_operand" ""))) 7343 (const_int 64)))) 7344 (clobber (match_scratch:DI 3 "")) 7345 (clobber (reg:CC FLAGS_REG))])] 7346 "TARGET_64BIT" 7347 "") 7348 7349(define_insn "*smuldi3_highpart_rex64" 7350 [(set (match_operand:DI 0 "register_operand" "=d") 7351 (truncate:DI 7352 (lshiftrt:TI 7353 (mult:TI (sign_extend:TI 7354 (match_operand:DI 1 "nonimmediate_operand" "%a")) 7355 (sign_extend:TI 7356 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7357 (const_int 64)))) 7358 (clobber (match_scratch:DI 3 "=1")) 7359 (clobber (reg:CC FLAGS_REG))] 7360 "TARGET_64BIT 7361 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7362 "imul{q}\t%2" 7363 [(set_attr "type" "imul") 7364 (set (attr "athlon_decode") 7365 (if_then_else (eq_attr "cpu" "athlon") 7366 (const_string "vector") 7367 (const_string "double"))) 7368 (set_attr "amdfam10_decode" "double") 7369 (set_attr "mode" "DI")]) 7370 7371(define_expand "smulsi3_highpart" 7372 [(parallel [(set (match_operand:SI 0 "register_operand" "") 7373 (truncate:SI 7374 (lshiftrt:DI 7375 (mult:DI (sign_extend:DI 7376 (match_operand:SI 1 "nonimmediate_operand" "")) 7377 (sign_extend:DI 7378 (match_operand:SI 2 "register_operand" ""))) 7379 (const_int 32)))) 7380 (clobber (match_scratch:SI 3 "")) 7381 (clobber (reg:CC FLAGS_REG))])] 7382 "" 7383 "") 7384 7385(define_insn "*smulsi3_highpart_insn" 7386 [(set (match_operand:SI 0 "register_operand" "=d") 7387 (truncate:SI 7388 (lshiftrt:DI 7389 (mult:DI (sign_extend:DI 7390 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7391 (sign_extend:DI 7392 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7393 (const_int 32)))) 7394 (clobber (match_scratch:SI 3 "=1")) 7395 (clobber (reg:CC FLAGS_REG))] 7396 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 7397 "imul{l}\t%2" 7398 [(set_attr "type" "imul") 7399 (set (attr "athlon_decode") 7400 (if_then_else (eq_attr "cpu" "athlon") 7401 (const_string "vector") 7402 (const_string "double"))) 7403 (set_attr "amdfam10_decode" "double") 7404 (set_attr "mode" "SI")]) 7405 7406(define_insn "*smulsi3_highpart_zext" 7407 [(set (match_operand:DI 0 "register_operand" "=d") 7408 (zero_extend:DI (truncate:SI 7409 (lshiftrt:DI 7410 (mult:DI (sign_extend:DI 7411 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7412 (sign_extend:DI 7413 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7414 (const_int 32))))) 7415 (clobber (match_scratch:SI 3 "=1")) 7416 (clobber (reg:CC FLAGS_REG))] 7417 "TARGET_64BIT 7418 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7419 "imul{l}\t%2" 7420 [(set_attr "type" "imul") 7421 (set (attr "athlon_decode") 7422 (if_then_else (eq_attr "cpu" "athlon") 7423 (const_string "vector") 7424 (const_string "double"))) 7425 (set_attr "amdfam10_decode" "double") 7426 (set_attr "mode" "SI")]) 7427 7428;; The patterns that match these are at the end of this file. 7429 7430(define_expand "mulxf3" 7431 [(set (match_operand:XF 0 "register_operand" "") 7432 (mult:XF (match_operand:XF 1 "register_operand" "") 7433 (match_operand:XF 2 "register_operand" "")))] 7434 "TARGET_80387" 7435 "") 7436 7437(define_expand "muldf3" 7438 [(set (match_operand:DF 0 "register_operand" "") 7439 (mult:DF (match_operand:DF 1 "register_operand" "") 7440 (match_operand:DF 2 "nonimmediate_operand" "")))] 7441 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 7442 "") 7443 7444(define_expand "mulsf3" 7445 [(set (match_operand:SF 0 "register_operand" "") 7446 (mult:SF (match_operand:SF 1 "register_operand" "") 7447 (match_operand:SF 2 "nonimmediate_operand" "")))] 7448 "TARGET_80387 || TARGET_SSE_MATH" 7449 "") 7450 7451;; Divide instructions 7452 7453(define_insn "divqi3" 7454 [(set (match_operand:QI 0 "register_operand" "=a") 7455 (div:QI (match_operand:HI 1 "register_operand" "0") 7456 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 7457 (clobber (reg:CC FLAGS_REG))] 7458 "TARGET_QIMODE_MATH" 7459 "idiv{b}\t%2" 7460 [(set_attr "type" "idiv") 7461 (set_attr "mode" "QI")]) 7462 7463(define_insn "udivqi3" 7464 [(set (match_operand:QI 0 "register_operand" "=a") 7465 (udiv:QI (match_operand:HI 1 "register_operand" "0") 7466 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 7467 (clobber (reg:CC FLAGS_REG))] 7468 "TARGET_QIMODE_MATH" 7469 "div{b}\t%2" 7470 [(set_attr "type" "idiv") 7471 (set_attr "mode" "QI")]) 7472 7473;; The patterns that match these are at the end of this file. 7474 7475(define_expand "divxf3" 7476 [(set (match_operand:XF 0 "register_operand" "") 7477 (div:XF (match_operand:XF 1 "register_operand" "") 7478 (match_operand:XF 2 "register_operand" "")))] 7479 "TARGET_80387" 7480 "") 7481 7482(define_expand "divdf3" 7483 [(set (match_operand:DF 0 "register_operand" "") 7484 (div:DF (match_operand:DF 1 "register_operand" "") 7485 (match_operand:DF 2 "nonimmediate_operand" "")))] 7486 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 7487 "") 7488 7489(define_expand "divsf3" 7490 [(set (match_operand:SF 0 "register_operand" "") 7491 (div:SF (match_operand:SF 1 "register_operand" "") 7492 (match_operand:SF 2 "nonimmediate_operand" "")))] 7493 "TARGET_80387 || TARGET_SSE_MATH" 7494 "") 7495 7496;; Remainder instructions. 7497 7498(define_expand "divmoddi4" 7499 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7500 (div:DI (match_operand:DI 1 "register_operand" "") 7501 (match_operand:DI 2 "nonimmediate_operand" ""))) 7502 (set (match_operand:DI 3 "register_operand" "") 7503 (mod:DI (match_dup 1) (match_dup 2))) 7504 (clobber (reg:CC FLAGS_REG))])] 7505 "TARGET_64BIT" 7506 "") 7507 7508;; Allow to come the parameter in eax or edx to avoid extra moves. 7509;; Penalize eax case slightly because it results in worse scheduling 7510;; of code. 7511(define_insn "*divmoddi4_nocltd_rex64" 7512 [(set (match_operand:DI 0 "register_operand" "=&a,?a") 7513 (div:DI (match_operand:DI 2 "register_operand" "1,0") 7514 (match_operand:DI 3 "nonimmediate_operand" "rm,rm"))) 7515 (set (match_operand:DI 1 "register_operand" "=&d,&d") 7516 (mod:DI (match_dup 2) (match_dup 3))) 7517 (clobber (reg:CC FLAGS_REG))] 7518 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD" 7519 "#" 7520 [(set_attr "type" "multi")]) 7521 7522(define_insn "*divmoddi4_cltd_rex64" 7523 [(set (match_operand:DI 0 "register_operand" "=a") 7524 (div:DI (match_operand:DI 2 "register_operand" "a") 7525 (match_operand:DI 3 "nonimmediate_operand" "rm"))) 7526 (set (match_operand:DI 1 "register_operand" "=&d") 7527 (mod:DI (match_dup 2) (match_dup 3))) 7528 (clobber (reg:CC FLAGS_REG))] 7529 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)" 7530 "#" 7531 [(set_attr "type" "multi")]) 7532 7533(define_insn "*divmoddi_noext_rex64" 7534 [(set (match_operand:DI 0 "register_operand" "=a") 7535 (div:DI (match_operand:DI 1 "register_operand" "0") 7536 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7537 (set (match_operand:DI 3 "register_operand" "=d") 7538 (mod:DI (match_dup 1) (match_dup 2))) 7539 (use (match_operand:DI 4 "register_operand" "3")) 7540 (clobber (reg:CC FLAGS_REG))] 7541 "TARGET_64BIT" 7542 "idiv{q}\t%2" 7543 [(set_attr "type" "idiv") 7544 (set_attr "mode" "DI")]) 7545 7546(define_split 7547 [(set (match_operand:DI 0 "register_operand" "") 7548 (div:DI (match_operand:DI 1 "register_operand" "") 7549 (match_operand:DI 2 "nonimmediate_operand" ""))) 7550 (set (match_operand:DI 3 "register_operand" "") 7551 (mod:DI (match_dup 1) (match_dup 2))) 7552 (clobber (reg:CC FLAGS_REG))] 7553 "TARGET_64BIT && reload_completed" 7554 [(parallel [(set (match_dup 3) 7555 (ashiftrt:DI (match_dup 4) (const_int 63))) 7556 (clobber (reg:CC FLAGS_REG))]) 7557 (parallel [(set (match_dup 0) 7558 (div:DI (reg:DI 0) (match_dup 2))) 7559 (set (match_dup 3) 7560 (mod:DI (reg:DI 0) (match_dup 2))) 7561 (use (match_dup 3)) 7562 (clobber (reg:CC FLAGS_REG))])] 7563{ 7564 /* Avoid use of cltd in favor of a mov+shift. */ 7565 if (!TARGET_USE_CLTD && !optimize_size) 7566 { 7567 if (true_regnum (operands[1])) 7568 emit_move_insn (operands[0], operands[1]); 7569 else 7570 emit_move_insn (operands[3], operands[1]); 7571 operands[4] = operands[3]; 7572 } 7573 else 7574 { 7575 gcc_assert (!true_regnum (operands[1])); 7576 operands[4] = operands[1]; 7577 } 7578}) 7579 7580 7581(define_expand "divmodsi4" 7582 [(parallel [(set (match_operand:SI 0 "register_operand" "") 7583 (div:SI (match_operand:SI 1 "register_operand" "") 7584 (match_operand:SI 2 "nonimmediate_operand" ""))) 7585 (set (match_operand:SI 3 "register_operand" "") 7586 (mod:SI (match_dup 1) (match_dup 2))) 7587 (clobber (reg:CC FLAGS_REG))])] 7588 "" 7589 "") 7590 7591;; Allow to come the parameter in eax or edx to avoid extra moves. 7592;; Penalize eax case slightly because it results in worse scheduling 7593;; of code. 7594(define_insn "*divmodsi4_nocltd" 7595 [(set (match_operand:SI 0 "register_operand" "=&a,?a") 7596 (div:SI (match_operand:SI 2 "register_operand" "1,0") 7597 (match_operand:SI 3 "nonimmediate_operand" "rm,rm"))) 7598 (set (match_operand:SI 1 "register_operand" "=&d,&d") 7599 (mod:SI (match_dup 2) (match_dup 3))) 7600 (clobber (reg:CC FLAGS_REG))] 7601 "!optimize_size && !TARGET_USE_CLTD" 7602 "#" 7603 [(set_attr "type" "multi")]) 7604 7605(define_insn "*divmodsi4_cltd" 7606 [(set (match_operand:SI 0 "register_operand" "=a") 7607 (div:SI (match_operand:SI 2 "register_operand" "a") 7608 (match_operand:SI 3 "nonimmediate_operand" "rm"))) 7609 (set (match_operand:SI 1 "register_operand" "=&d") 7610 (mod:SI (match_dup 2) (match_dup 3))) 7611 (clobber (reg:CC FLAGS_REG))] 7612 "optimize_size || TARGET_USE_CLTD" 7613 "#" 7614 [(set_attr "type" "multi")]) 7615 7616(define_insn "*divmodsi_noext" 7617 [(set (match_operand:SI 0 "register_operand" "=a") 7618 (div:SI (match_operand:SI 1 "register_operand" "0") 7619 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7620 (set (match_operand:SI 3 "register_operand" "=d") 7621 (mod:SI (match_dup 1) (match_dup 2))) 7622 (use (match_operand:SI 4 "register_operand" "3")) 7623 (clobber (reg:CC FLAGS_REG))] 7624 "" 7625 "idiv{l}\t%2" 7626 [(set_attr "type" "idiv") 7627 (set_attr "mode" "SI")]) 7628 7629(define_split 7630 [(set (match_operand:SI 0 "register_operand" "") 7631 (div:SI (match_operand:SI 1 "register_operand" "") 7632 (match_operand:SI 2 "nonimmediate_operand" ""))) 7633 (set (match_operand:SI 3 "register_operand" "") 7634 (mod:SI (match_dup 1) (match_dup 2))) 7635 (clobber (reg:CC FLAGS_REG))] 7636 "reload_completed" 7637 [(parallel [(set (match_dup 3) 7638 (ashiftrt:SI (match_dup 4) (const_int 31))) 7639 (clobber (reg:CC FLAGS_REG))]) 7640 (parallel [(set (match_dup 0) 7641 (div:SI (reg:SI 0) (match_dup 2))) 7642 (set (match_dup 3) 7643 (mod:SI (reg:SI 0) (match_dup 2))) 7644 (use (match_dup 3)) 7645 (clobber (reg:CC FLAGS_REG))])] 7646{ 7647 /* Avoid use of cltd in favor of a mov+shift. */ 7648 if (!TARGET_USE_CLTD && !optimize_size) 7649 { 7650 if (true_regnum (operands[1])) 7651 emit_move_insn (operands[0], operands[1]); 7652 else 7653 emit_move_insn (operands[3], operands[1]); 7654 operands[4] = operands[3]; 7655 } 7656 else 7657 { 7658 gcc_assert (!true_regnum (operands[1])); 7659 operands[4] = operands[1]; 7660 } 7661}) 7662;; %%% Split me. 7663(define_insn "divmodhi4" 7664 [(set (match_operand:HI 0 "register_operand" "=a") 7665 (div:HI (match_operand:HI 1 "register_operand" "0") 7666 (match_operand:HI 2 "nonimmediate_operand" "rm"))) 7667 (set (match_operand:HI 3 "register_operand" "=&d") 7668 (mod:HI (match_dup 1) (match_dup 2))) 7669 (clobber (reg:CC FLAGS_REG))] 7670 "TARGET_HIMODE_MATH" 7671 "cwtd\;idiv{w}\t%2" 7672 [(set_attr "type" "multi") 7673 (set_attr "length_immediate" "0") 7674 (set_attr "mode" "SI")]) 7675 7676(define_insn "udivmoddi4" 7677 [(set (match_operand:DI 0 "register_operand" "=a") 7678 (udiv:DI (match_operand:DI 1 "register_operand" "0") 7679 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7680 (set (match_operand:DI 3 "register_operand" "=&d") 7681 (umod:DI (match_dup 1) (match_dup 2))) 7682 (clobber (reg:CC FLAGS_REG))] 7683 "TARGET_64BIT" 7684 "xor{q}\t%3, %3\;div{q}\t%2" 7685 [(set_attr "type" "multi") 7686 (set_attr "length_immediate" "0") 7687 (set_attr "mode" "DI")]) 7688 7689(define_insn "*udivmoddi4_noext" 7690 [(set (match_operand:DI 0 "register_operand" "=a") 7691 (udiv:DI (match_operand:DI 1 "register_operand" "0") 7692 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7693 (set (match_operand:DI 3 "register_operand" "=d") 7694 (umod:DI (match_dup 1) (match_dup 2))) 7695 (use (match_dup 3)) 7696 (clobber (reg:CC FLAGS_REG))] 7697 "TARGET_64BIT" 7698 "div{q}\t%2" 7699 [(set_attr "type" "idiv") 7700 (set_attr "mode" "DI")]) 7701 7702(define_split 7703 [(set (match_operand:DI 0 "register_operand" "") 7704 (udiv:DI (match_operand:DI 1 "register_operand" "") 7705 (match_operand:DI 2 "nonimmediate_operand" ""))) 7706 (set (match_operand:DI 3 "register_operand" "") 7707 (umod:DI (match_dup 1) (match_dup 2))) 7708 (clobber (reg:CC FLAGS_REG))] 7709 "TARGET_64BIT && reload_completed" 7710 [(set (match_dup 3) (const_int 0)) 7711 (parallel [(set (match_dup 0) 7712 (udiv:DI (match_dup 1) (match_dup 2))) 7713 (set (match_dup 3) 7714 (umod:DI (match_dup 1) (match_dup 2))) 7715 (use (match_dup 3)) 7716 (clobber (reg:CC FLAGS_REG))])] 7717 "") 7718 7719(define_insn "udivmodsi4" 7720 [(set (match_operand:SI 0 "register_operand" "=a") 7721 (udiv:SI (match_operand:SI 1 "register_operand" "0") 7722 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7723 (set (match_operand:SI 3 "register_operand" "=&d") 7724 (umod:SI (match_dup 1) (match_dup 2))) 7725 (clobber (reg:CC FLAGS_REG))] 7726 "" 7727 "xor{l}\t%3, %3\;div{l}\t%2" 7728 [(set_attr "type" "multi") 7729 (set_attr "length_immediate" "0") 7730 (set_attr "mode" "SI")]) 7731 7732(define_insn "*udivmodsi4_noext" 7733 [(set (match_operand:SI 0 "register_operand" "=a") 7734 (udiv:SI (match_operand:SI 1 "register_operand" "0") 7735 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7736 (set (match_operand:SI 3 "register_operand" "=d") 7737 (umod:SI (match_dup 1) (match_dup 2))) 7738 (use (match_dup 3)) 7739 (clobber (reg:CC FLAGS_REG))] 7740 "" 7741 "div{l}\t%2" 7742 [(set_attr "type" "idiv") 7743 (set_attr "mode" "SI")]) 7744 7745(define_split 7746 [(set (match_operand:SI 0 "register_operand" "") 7747 (udiv:SI (match_operand:SI 1 "register_operand" "") 7748 (match_operand:SI 2 "nonimmediate_operand" ""))) 7749 (set (match_operand:SI 3 "register_operand" "") 7750 (umod:SI (match_dup 1) (match_dup 2))) 7751 (clobber (reg:CC FLAGS_REG))] 7752 "reload_completed" 7753 [(set (match_dup 3) (const_int 0)) 7754 (parallel [(set (match_dup 0) 7755 (udiv:SI (match_dup 1) (match_dup 2))) 7756 (set (match_dup 3) 7757 (umod:SI (match_dup 1) (match_dup 2))) 7758 (use (match_dup 3)) 7759 (clobber (reg:CC FLAGS_REG))])] 7760 "") 7761 7762(define_expand "udivmodhi4" 7763 [(set (match_dup 4) (const_int 0)) 7764 (parallel [(set (match_operand:HI 0 "register_operand" "") 7765 (udiv:HI (match_operand:HI 1 "register_operand" "") 7766 (match_operand:HI 2 "nonimmediate_operand" ""))) 7767 (set (match_operand:HI 3 "register_operand" "") 7768 (umod:HI (match_dup 1) (match_dup 2))) 7769 (use (match_dup 4)) 7770 (clobber (reg:CC FLAGS_REG))])] 7771 "TARGET_HIMODE_MATH" 7772 "operands[4] = gen_reg_rtx (HImode);") 7773 7774(define_insn "*udivmodhi_noext" 7775 [(set (match_operand:HI 0 "register_operand" "=a") 7776 (udiv:HI (match_operand:HI 1 "register_operand" "0") 7777 (match_operand:HI 2 "nonimmediate_operand" "rm"))) 7778 (set (match_operand:HI 3 "register_operand" "=d") 7779 (umod:HI (match_dup 1) (match_dup 2))) 7780 (use (match_operand:HI 4 "register_operand" "3")) 7781 (clobber (reg:CC FLAGS_REG))] 7782 "" 7783 "div{w}\t%2" 7784 [(set_attr "type" "idiv") 7785 (set_attr "mode" "HI")]) 7786 7787;; We cannot use div/idiv for double division, because it causes 7788;; "division by zero" on the overflow and that's not what we expect 7789;; from truncate. Because true (non truncating) double division is 7790;; never generated, we can't create this insn anyway. 7791; 7792;(define_insn "" 7793; [(set (match_operand:SI 0 "register_operand" "=a") 7794; (truncate:SI 7795; (udiv:DI (match_operand:DI 1 "register_operand" "A") 7796; (zero_extend:DI 7797; (match_operand:SI 2 "nonimmediate_operand" "rm"))))) 7798; (set (match_operand:SI 3 "register_operand" "=d") 7799; (truncate:SI 7800; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2))))) 7801; (clobber (reg:CC FLAGS_REG))] 7802; "" 7803; "div{l}\t{%2, %0|%0, %2}" 7804; [(set_attr "type" "idiv")]) 7805 7806;;- Logical AND instructions 7807 7808;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al. 7809;; Note that this excludes ah. 7810 7811(define_insn "*testdi_1_rex64" 7812 [(set (reg FLAGS_REG) 7813 (compare 7814 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm") 7815 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re")) 7816 (const_int 0)))] 7817 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7818 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7819 "@ 7820 test{l}\t{%k1, %k0|%k0, %k1} 7821 test{l}\t{%k1, %k0|%k0, %k1} 7822 test{q}\t{%1, %0|%0, %1} 7823 test{q}\t{%1, %0|%0, %1} 7824 test{q}\t{%1, %0|%0, %1}" 7825 [(set_attr "type" "test") 7826 (set_attr "modrm" "0,1,0,1,1") 7827 (set_attr "mode" "SI,SI,DI,DI,DI") 7828 (set_attr "pent_pair" "uv,np,uv,np,uv")]) 7829 7830(define_insn "testsi_1" 7831 [(set (reg FLAGS_REG) 7832 (compare 7833 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm") 7834 (match_operand:SI 1 "general_operand" "in,in,rin")) 7835 (const_int 0)))] 7836 "ix86_match_ccmode (insn, CCNOmode) 7837 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7838 "test{l}\t{%1, %0|%0, %1}" 7839 [(set_attr "type" "test") 7840 (set_attr "modrm" "0,1,1") 7841 (set_attr "mode" "SI") 7842 (set_attr "pent_pair" "uv,np,uv")]) 7843 7844(define_expand "testsi_ccno_1" 7845 [(set (reg:CCNO FLAGS_REG) 7846 (compare:CCNO 7847 (and:SI (match_operand:SI 0 "nonimmediate_operand" "") 7848 (match_operand:SI 1 "nonmemory_operand" "")) 7849 (const_int 0)))] 7850 "" 7851 "") 7852 7853(define_insn "*testhi_1" 7854 [(set (reg FLAGS_REG) 7855 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm") 7856 (match_operand:HI 1 "general_operand" "n,n,rn")) 7857 (const_int 0)))] 7858 "ix86_match_ccmode (insn, CCNOmode) 7859 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7860 "test{w}\t{%1, %0|%0, %1}" 7861 [(set_attr "type" "test") 7862 (set_attr "modrm" "0,1,1") 7863 (set_attr "mode" "HI") 7864 (set_attr "pent_pair" "uv,np,uv")]) 7865 7866(define_expand "testqi_ccz_1" 7867 [(set (reg:CCZ FLAGS_REG) 7868 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "") 7869 (match_operand:QI 1 "nonmemory_operand" "")) 7870 (const_int 0)))] 7871 "" 7872 "") 7873 7874(define_insn "*testqi_1_maybe_si" 7875 [(set (reg FLAGS_REG) 7876 (compare 7877 (and:QI 7878 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r") 7879 (match_operand:QI 1 "general_operand" "n,n,qn,n")) 7880 (const_int 0)))] 7881 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 7882 && ix86_match_ccmode (insn, 7883 GET_CODE (operands[1]) == CONST_INT 7884 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)" 7885{ 7886 if (which_alternative == 3) 7887 { 7888 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0) 7889 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); 7890 return "test{l}\t{%1, %k0|%k0, %1}"; 7891 } 7892 return "test{b}\t{%1, %0|%0, %1}"; 7893} 7894 [(set_attr "type" "test") 7895 (set_attr "modrm" "0,1,1,1") 7896 (set_attr "mode" "QI,QI,QI,SI") 7897 (set_attr "pent_pair" "uv,np,uv,np")]) 7898 7899(define_insn "*testqi_1" 7900 [(set (reg FLAGS_REG) 7901 (compare 7902 (and:QI 7903 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm") 7904 (match_operand:QI 1 "general_operand" "n,n,qn")) 7905 (const_int 0)))] 7906 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 7907 && ix86_match_ccmode (insn, CCNOmode)" 7908 "test{b}\t{%1, %0|%0, %1}" 7909 [(set_attr "type" "test") 7910 (set_attr "modrm" "0,1,1") 7911 (set_attr "mode" "QI") 7912 (set_attr "pent_pair" "uv,np,uv")]) 7913 7914(define_expand "testqi_ext_ccno_0" 7915 [(set (reg:CCNO FLAGS_REG) 7916 (compare:CCNO 7917 (and:SI 7918 (zero_extract:SI 7919 (match_operand 0 "ext_register_operand" "") 7920 (const_int 8) 7921 (const_int 8)) 7922 (match_operand 1 "const_int_operand" "")) 7923 (const_int 0)))] 7924 "" 7925 "") 7926 7927(define_insn "*testqi_ext_0" 7928 [(set (reg FLAGS_REG) 7929 (compare 7930 (and:SI 7931 (zero_extract:SI 7932 (match_operand 0 "ext_register_operand" "Q") 7933 (const_int 8) 7934 (const_int 8)) 7935 (match_operand 1 "const_int_operand" "n")) 7936 (const_int 0)))] 7937 "ix86_match_ccmode (insn, CCNOmode)" 7938 "test{b}\t{%1, %h0|%h0, %1}" 7939 [(set_attr "type" "test") 7940 (set_attr "mode" "QI") 7941 (set_attr "length_immediate" "1") 7942 (set_attr "pent_pair" "np")]) 7943 7944(define_insn "*testqi_ext_1" 7945 [(set (reg FLAGS_REG) 7946 (compare 7947 (and:SI 7948 (zero_extract:SI 7949 (match_operand 0 "ext_register_operand" "Q") 7950 (const_int 8) 7951 (const_int 8)) 7952 (zero_extend:SI 7953 (match_operand:QI 1 "general_operand" "Qm"))) 7954 (const_int 0)))] 7955 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7956 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7957 "test{b}\t{%1, %h0|%h0, %1}" 7958 [(set_attr "type" "test") 7959 (set_attr "mode" "QI")]) 7960 7961(define_insn "*testqi_ext_1_rex64" 7962 [(set (reg FLAGS_REG) 7963 (compare 7964 (and:SI 7965 (zero_extract:SI 7966 (match_operand 0 "ext_register_operand" "Q") 7967 (const_int 8) 7968 (const_int 8)) 7969 (zero_extend:SI 7970 (match_operand:QI 1 "register_operand" "Q"))) 7971 (const_int 0)))] 7972 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 7973 "test{b}\t{%1, %h0|%h0, %1}" 7974 [(set_attr "type" "test") 7975 (set_attr "mode" "QI")]) 7976 7977(define_insn "*testqi_ext_2" 7978 [(set (reg FLAGS_REG) 7979 (compare 7980 (and:SI 7981 (zero_extract:SI 7982 (match_operand 0 "ext_register_operand" "Q") 7983 (const_int 8) 7984 (const_int 8)) 7985 (zero_extract:SI 7986 (match_operand 1 "ext_register_operand" "Q") 7987 (const_int 8) 7988 (const_int 8))) 7989 (const_int 0)))] 7990 "ix86_match_ccmode (insn, CCNOmode)" 7991 "test{b}\t{%h1, %h0|%h0, %h1}" 7992 [(set_attr "type" "test") 7993 (set_attr "mode" "QI")]) 7994 7995;; Combine likes to form bit extractions for some tests. Humor it. 7996(define_insn "*testqi_ext_3" 7997 [(set (reg FLAGS_REG) 7998 (compare (zero_extract:SI 7999 (match_operand 0 "nonimmediate_operand" "rm") 8000 (match_operand:SI 1 "const_int_operand" "") 8001 (match_operand:SI 2 "const_int_operand" "")) 8002 (const_int 0)))] 8003 "ix86_match_ccmode (insn, CCNOmode) 8004 && INTVAL (operands[1]) > 0 8005 && INTVAL (operands[2]) >= 0 8006 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 8007 && (GET_MODE (operands[0]) == SImode 8008 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode) 8009 || GET_MODE (operands[0]) == HImode 8010 || GET_MODE (operands[0]) == QImode)" 8011 "#") 8012 8013(define_insn "*testqi_ext_3_rex64" 8014 [(set (reg FLAGS_REG) 8015 (compare (zero_extract:DI 8016 (match_operand 0 "nonimmediate_operand" "rm") 8017 (match_operand:DI 1 "const_int_operand" "") 8018 (match_operand:DI 2 "const_int_operand" "")) 8019 (const_int 0)))] 8020 "TARGET_64BIT 8021 && ix86_match_ccmode (insn, CCNOmode) 8022 && INTVAL (operands[1]) > 0 8023 && INTVAL (operands[2]) >= 0 8024 /* Ensure that resulting mask is zero or sign extended operand. */ 8025 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 8026 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64 8027 && INTVAL (operands[1]) > 32)) 8028 && (GET_MODE (operands[0]) == SImode 8029 || GET_MODE (operands[0]) == DImode 8030 || GET_MODE (operands[0]) == HImode 8031 || GET_MODE (operands[0]) == QImode)" 8032 "#") 8033 8034(define_split 8035 [(set (match_operand 0 "flags_reg_operand" "") 8036 (match_operator 1 "compare_operator" 8037 [(zero_extract 8038 (match_operand 2 "nonimmediate_operand" "") 8039 (match_operand 3 "const_int_operand" "") 8040 (match_operand 4 "const_int_operand" "")) 8041 (const_int 0)]))] 8042 "ix86_match_ccmode (insn, CCNOmode)" 8043 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))] 8044{ 8045 rtx val = operands[2]; 8046 HOST_WIDE_INT len = INTVAL (operands[3]); 8047 HOST_WIDE_INT pos = INTVAL (operands[4]); 8048 HOST_WIDE_INT mask; 8049 enum machine_mode mode, submode; 8050 8051 mode = GET_MODE (val); 8052 if (GET_CODE (val) == MEM) 8053 { 8054 /* ??? Combine likes to put non-volatile mem extractions in QImode 8055 no matter the size of the test. So find a mode that works. */ 8056 if (! MEM_VOLATILE_P (val)) 8057 { 8058 mode = smallest_mode_for_size (pos + len, MODE_INT); 8059 val = adjust_address (val, mode, 0); 8060 } 8061 } 8062 else if (GET_CODE (val) == SUBREG 8063 && (submode = GET_MODE (SUBREG_REG (val)), 8064 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)) 8065 && pos + len <= GET_MODE_BITSIZE (submode)) 8066 { 8067 /* Narrow a paradoxical subreg to prevent partial register stalls. */ 8068 mode = submode; 8069 val = SUBREG_REG (val); 8070 } 8071 else if (mode == HImode && pos + len <= 8) 8072 { 8073 /* Small HImode tests can be converted to QImode. */ 8074 mode = QImode; 8075 val = gen_lowpart (QImode, val); 8076 } 8077 8078 if (len == HOST_BITS_PER_WIDE_INT) 8079 mask = -1; 8080 else 8081 mask = ((HOST_WIDE_INT)1 << len) - 1; 8082 mask <<= pos; 8083 8084 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode)); 8085}) 8086 8087;; Convert HImode/SImode test instructions with immediate to QImode ones. 8088;; i386 does not allow to encode test with 8bit sign extended immediate, so 8089;; this is relatively important trick. 8090;; Do the conversion only post-reload to avoid limiting of the register class 8091;; to QI regs. 8092(define_split 8093 [(set (match_operand 0 "flags_reg_operand" "") 8094 (match_operator 1 "compare_operator" 8095 [(and (match_operand 2 "register_operand" "") 8096 (match_operand 3 "const_int_operand" "")) 8097 (const_int 0)]))] 8098 "reload_completed 8099 && QI_REG_P (operands[2]) 8100 && GET_MODE (operands[2]) != QImode 8101 && ((ix86_match_ccmode (insn, CCZmode) 8102 && !(INTVAL (operands[3]) & ~(255 << 8))) 8103 || (ix86_match_ccmode (insn, CCNOmode) 8104 && !(INTVAL (operands[3]) & ~(127 << 8))))" 8105 [(set (match_dup 0) 8106 (match_op_dup 1 8107 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8)) 8108 (match_dup 3)) 8109 (const_int 0)]))] 8110 "operands[2] = gen_lowpart (SImode, operands[2]); 8111 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);") 8112 8113(define_split 8114 [(set (match_operand 0 "flags_reg_operand" "") 8115 (match_operator 1 "compare_operator" 8116 [(and (match_operand 2 "nonimmediate_operand" "") 8117 (match_operand 3 "const_int_operand" "")) 8118 (const_int 0)]))] 8119 "reload_completed 8120 && GET_MODE (operands[2]) != QImode 8121 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2])) 8122 && ((ix86_match_ccmode (insn, CCZmode) 8123 && !(INTVAL (operands[3]) & ~255)) 8124 || (ix86_match_ccmode (insn, CCNOmode) 8125 && !(INTVAL (operands[3]) & ~127)))" 8126 [(set (match_dup 0) 8127 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 8128 (const_int 0)]))] 8129 "operands[2] = gen_lowpart (QImode, operands[2]); 8130 operands[3] = gen_lowpart (QImode, operands[3]);") 8131 8132 8133;; %%% This used to optimize known byte-wide and operations to memory, 8134;; and sometimes to QImode registers. If this is considered useful, 8135;; it should be done with splitters. 8136 8137(define_expand "anddi3" 8138 [(set (match_operand:DI 0 "nonimmediate_operand" "") 8139 (and:DI (match_operand:DI 1 "nonimmediate_operand" "") 8140 (match_operand:DI 2 "x86_64_szext_general_operand" ""))) 8141 (clobber (reg:CC FLAGS_REG))] 8142 "TARGET_64BIT" 8143 "ix86_expand_binary_operator (AND, DImode, operands); DONE;") 8144 8145(define_insn "*anddi_1_rex64" 8146 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r") 8147 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm") 8148 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L"))) 8149 (clobber (reg:CC FLAGS_REG))] 8150 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)" 8151{ 8152 switch (get_attr_type (insn)) 8153 { 8154 case TYPE_IMOVX: 8155 { 8156 enum machine_mode mode; 8157 8158 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 8159 if (INTVAL (operands[2]) == 0xff) 8160 mode = QImode; 8161 else 8162 { 8163 gcc_assert (INTVAL (operands[2]) == 0xffff); 8164 mode = HImode; 8165 } 8166 8167 operands[1] = gen_lowpart (mode, operands[1]); 8168 if (mode == QImode) 8169 return "movz{bq|x}\t{%1,%0|%0, %1}"; 8170 else 8171 return "movz{wq|x}\t{%1,%0|%0, %1}"; 8172 } 8173 8174 default: 8175 gcc_assert (rtx_equal_p (operands[0], operands[1])); 8176 if (get_attr_mode (insn) == MODE_SI) 8177 return "and{l}\t{%k2, %k0|%k0, %k2}"; 8178 else 8179 return "and{q}\t{%2, %0|%0, %2}"; 8180 } 8181} 8182 [(set_attr "type" "alu,alu,alu,imovx") 8183 (set_attr "length_immediate" "*,*,*,0") 8184 (set_attr "mode" "SI,DI,DI,DI")]) 8185 8186(define_insn "*anddi_2" 8187 [(set (reg FLAGS_REG) 8188 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") 8189 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re")) 8190 (const_int 0))) 8191 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm") 8192 (and:DI (match_dup 1) (match_dup 2)))] 8193 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8194 && ix86_binary_operator_ok (AND, DImode, operands)" 8195 "@ 8196 and{l}\t{%k2, %k0|%k0, %k2} 8197 and{q}\t{%2, %0|%0, %2} 8198 and{q}\t{%2, %0|%0, %2}" 8199 [(set_attr "type" "alu") 8200 (set_attr "mode" "SI,DI,DI")]) 8201 8202(define_expand "andsi3" 8203 [(set (match_operand:SI 0 "nonimmediate_operand" "") 8204 (and:SI (match_operand:SI 1 "nonimmediate_operand" "") 8205 (match_operand:SI 2 "general_operand" ""))) 8206 (clobber (reg:CC FLAGS_REG))] 8207 "" 8208 "ix86_expand_binary_operator (AND, SImode, operands); DONE;") 8209 8210(define_insn "*andsi_1" 8211 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r") 8212 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm") 8213 (match_operand:SI 2 "general_operand" "ri,rm,L"))) 8214 (clobber (reg:CC FLAGS_REG))] 8215 "ix86_binary_operator_ok (AND, SImode, operands)" 8216{ 8217 switch (get_attr_type (insn)) 8218 { 8219 case TYPE_IMOVX: 8220 { 8221 enum machine_mode mode; 8222 8223 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 8224 if (INTVAL (operands[2]) == 0xff) 8225 mode = QImode; 8226 else 8227 { 8228 gcc_assert (INTVAL (operands[2]) == 0xffff); 8229 mode = HImode; 8230 } 8231 8232 operands[1] = gen_lowpart (mode, operands[1]); 8233 if (mode == QImode) 8234 return "movz{bl|x}\t{%1,%0|%0, %1}"; 8235 else 8236 return "movz{wl|x}\t{%1,%0|%0, %1}"; 8237 } 8238 8239 default: 8240 gcc_assert (rtx_equal_p (operands[0], operands[1])); 8241 return "and{l}\t{%2, %0|%0, %2}"; 8242 } 8243} 8244 [(set_attr "type" "alu,alu,imovx") 8245 (set_attr "length_immediate" "*,*,0") 8246 (set_attr "mode" "SI")]) 8247 8248(define_split 8249 [(set (match_operand 0 "register_operand" "") 8250 (and (match_dup 0) 8251 (const_int -65536))) 8252 (clobber (reg:CC FLAGS_REG))] 8253 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)" 8254 [(set (strict_low_part (match_dup 1)) (const_int 0))] 8255 "operands[1] = gen_lowpart (HImode, operands[0]);") 8256 8257(define_split 8258 [(set (match_operand 0 "ext_register_operand" "") 8259 (and (match_dup 0) 8260 (const_int -256))) 8261 (clobber (reg:CC FLAGS_REG))] 8262 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed" 8263 [(set (strict_low_part (match_dup 1)) (const_int 0))] 8264 "operands[1] = gen_lowpart (QImode, operands[0]);") 8265 8266(define_split 8267 [(set (match_operand 0 "ext_register_operand" "") 8268 (and (match_dup 0) 8269 (const_int -65281))) 8270 (clobber (reg:CC FLAGS_REG))] 8271 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed" 8272 [(parallel [(set (zero_extract:SI (match_dup 0) 8273 (const_int 8) 8274 (const_int 8)) 8275 (xor:SI 8276 (zero_extract:SI (match_dup 0) 8277 (const_int 8) 8278 (const_int 8)) 8279 (zero_extract:SI (match_dup 0) 8280 (const_int 8) 8281 (const_int 8)))) 8282 (clobber (reg:CC FLAGS_REG))])] 8283 "operands[0] = gen_lowpart (SImode, operands[0]);") 8284 8285;; See comment for addsi_1_zext why we do use nonimmediate_operand 8286(define_insn "*andsi_1_zext" 8287 [(set (match_operand:DI 0 "register_operand" "=r") 8288 (zero_extend:DI 8289 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8290 (match_operand:SI 2 "general_operand" "rim")))) 8291 (clobber (reg:CC FLAGS_REG))] 8292 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" 8293 "and{l}\t{%2, %k0|%k0, %2}" 8294 [(set_attr "type" "alu") 8295 (set_attr "mode" "SI")]) 8296 8297(define_insn "*andsi_2" 8298 [(set (reg FLAGS_REG) 8299 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8300 (match_operand:SI 2 "general_operand" "rim,ri")) 8301 (const_int 0))) 8302 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 8303 (and:SI (match_dup 1) (match_dup 2)))] 8304 "ix86_match_ccmode (insn, CCNOmode) 8305 && ix86_binary_operator_ok (AND, SImode, operands)" 8306 "and{l}\t{%2, %0|%0, %2}" 8307 [(set_attr "type" "alu") 8308 (set_attr "mode" "SI")]) 8309 8310;; See comment for addsi_1_zext why we do use nonimmediate_operand 8311(define_insn "*andsi_2_zext" 8312 [(set (reg FLAGS_REG) 8313 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8314 (match_operand:SI 2 "general_operand" "rim")) 8315 (const_int 0))) 8316 (set (match_operand:DI 0 "register_operand" "=r") 8317 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] 8318 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8319 && ix86_binary_operator_ok (AND, SImode, operands)" 8320 "and{l}\t{%2, %k0|%k0, %2}" 8321 [(set_attr "type" "alu") 8322 (set_attr "mode" "SI")]) 8323 8324(define_expand "andhi3" 8325 [(set (match_operand:HI 0 "nonimmediate_operand" "") 8326 (and:HI (match_operand:HI 1 "nonimmediate_operand" "") 8327 (match_operand:HI 2 "general_operand" ""))) 8328 (clobber (reg:CC FLAGS_REG))] 8329 "TARGET_HIMODE_MATH" 8330 "ix86_expand_binary_operator (AND, HImode, operands); DONE;") 8331 8332(define_insn "*andhi_1" 8333 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") 8334 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm") 8335 (match_operand:HI 2 "general_operand" "ri,rm,L"))) 8336 (clobber (reg:CC FLAGS_REG))] 8337 "ix86_binary_operator_ok (AND, HImode, operands)" 8338{ 8339 switch (get_attr_type (insn)) 8340 { 8341 case TYPE_IMOVX: 8342 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 8343 gcc_assert (INTVAL (operands[2]) == 0xff); 8344 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}"; 8345 8346 default: 8347 gcc_assert (rtx_equal_p (operands[0], operands[1])); 8348 8349 return "and{w}\t{%2, %0|%0, %2}"; 8350 } 8351} 8352 [(set_attr "type" "alu,alu,imovx") 8353 (set_attr "length_immediate" "*,*,0") 8354 (set_attr "mode" "HI,HI,SI")]) 8355 8356(define_insn "*andhi_2" 8357 [(set (reg FLAGS_REG) 8358 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 8359 (match_operand:HI 2 "general_operand" "rim,ri")) 8360 (const_int 0))) 8361 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 8362 (and:HI (match_dup 1) (match_dup 2)))] 8363 "ix86_match_ccmode (insn, CCNOmode) 8364 && ix86_binary_operator_ok (AND, HImode, operands)" 8365 "and{w}\t{%2, %0|%0, %2}" 8366 [(set_attr "type" "alu") 8367 (set_attr "mode" "HI")]) 8368 8369(define_expand "andqi3" 8370 [(set (match_operand:QI 0 "nonimmediate_operand" "") 8371 (and:QI (match_operand:QI 1 "nonimmediate_operand" "") 8372 (match_operand:QI 2 "general_operand" ""))) 8373 (clobber (reg:CC FLAGS_REG))] 8374 "TARGET_QIMODE_MATH" 8375 "ix86_expand_binary_operator (AND, QImode, operands); DONE;") 8376 8377;; %%% Potential partial reg stall on alternative 2. What to do? 8378(define_insn "*andqi_1" 8379 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 8380 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8381 (match_operand:QI 2 "general_operand" "qi,qmi,ri"))) 8382 (clobber (reg:CC FLAGS_REG))] 8383 "ix86_binary_operator_ok (AND, QImode, operands)" 8384 "@ 8385 and{b}\t{%2, %0|%0, %2} 8386 and{b}\t{%2, %0|%0, %2} 8387 and{l}\t{%k2, %k0|%k0, %k2}" 8388 [(set_attr "type" "alu") 8389 (set_attr "mode" "QI,QI,SI")]) 8390 8391(define_insn "*andqi_1_slp" 8392 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 8393 (and:QI (match_dup 0) 8394 (match_operand:QI 1 "general_operand" "qi,qmi"))) 8395 (clobber (reg:CC FLAGS_REG))] 8396 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8397 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8398 "and{b}\t{%1, %0|%0, %1}" 8399 [(set_attr "type" "alu1") 8400 (set_attr "mode" "QI")]) 8401 8402(define_insn "*andqi_2_maybe_si" 8403 [(set (reg FLAGS_REG) 8404 (compare (and:QI 8405 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8406 (match_operand:QI 2 "general_operand" "qim,qi,i")) 8407 (const_int 0))) 8408 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r") 8409 (and:QI (match_dup 1) (match_dup 2)))] 8410 "ix86_binary_operator_ok (AND, QImode, operands) 8411 && ix86_match_ccmode (insn, 8412 GET_CODE (operands[2]) == CONST_INT 8413 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)" 8414{ 8415 if (which_alternative == 2) 8416 { 8417 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) 8418 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); 8419 return "and{l}\t{%2, %k0|%k0, %2}"; 8420 } 8421 return "and{b}\t{%2, %0|%0, %2}"; 8422} 8423 [(set_attr "type" "alu") 8424 (set_attr "mode" "QI,QI,SI")]) 8425 8426(define_insn "*andqi_2" 8427 [(set (reg FLAGS_REG) 8428 (compare (and:QI 8429 (match_operand:QI 1 "nonimmediate_operand" "%0,0") 8430 (match_operand:QI 2 "general_operand" "qim,qi")) 8431 (const_int 0))) 8432 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 8433 (and:QI (match_dup 1) (match_dup 2)))] 8434 "ix86_match_ccmode (insn, CCNOmode) 8435 && ix86_binary_operator_ok (AND, QImode, operands)" 8436 "and{b}\t{%2, %0|%0, %2}" 8437 [(set_attr "type" "alu") 8438 (set_attr "mode" "QI")]) 8439 8440(define_insn "*andqi_2_slp" 8441 [(set (reg FLAGS_REG) 8442 (compare (and:QI 8443 (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 8444 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi")) 8445 (const_int 0))) 8446 (set (strict_low_part (match_dup 0)) 8447 (and:QI (match_dup 0) (match_dup 1)))] 8448 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8449 && ix86_match_ccmode (insn, CCNOmode) 8450 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8451 "and{b}\t{%1, %0|%0, %1}" 8452 [(set_attr "type" "alu1") 8453 (set_attr "mode" "QI")]) 8454 8455;; ??? A bug in recog prevents it from recognizing a const_int as an 8456;; operand to zero_extend in andqi_ext_1. It was checking explicitly 8457;; for a QImode operand, which of course failed. 8458 8459(define_insn "andqi_ext_0" 8460 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8461 (const_int 8) 8462 (const_int 8)) 8463 (and:SI 8464 (zero_extract:SI 8465 (match_operand 1 "ext_register_operand" "0") 8466 (const_int 8) 8467 (const_int 8)) 8468 (match_operand 2 "const_int_operand" "n"))) 8469 (clobber (reg:CC FLAGS_REG))] 8470 "" 8471 "and{b}\t{%2, %h0|%h0, %2}" 8472 [(set_attr "type" "alu") 8473 (set_attr "length_immediate" "1") 8474 (set_attr "mode" "QI")]) 8475 8476;; Generated by peephole translating test to and. This shows up 8477;; often in fp comparisons. 8478 8479(define_insn "*andqi_ext_0_cc" 8480 [(set (reg FLAGS_REG) 8481 (compare 8482 (and:SI 8483 (zero_extract:SI 8484 (match_operand 1 "ext_register_operand" "0") 8485 (const_int 8) 8486 (const_int 8)) 8487 (match_operand 2 "const_int_operand" "n")) 8488 (const_int 0))) 8489 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8490 (const_int 8) 8491 (const_int 8)) 8492 (and:SI 8493 (zero_extract:SI 8494 (match_dup 1) 8495 (const_int 8) 8496 (const_int 8)) 8497 (match_dup 2)))] 8498 "ix86_match_ccmode (insn, CCNOmode)" 8499 "and{b}\t{%2, %h0|%h0, %2}" 8500 [(set_attr "type" "alu") 8501 (set_attr "length_immediate" "1") 8502 (set_attr "mode" "QI")]) 8503 8504(define_insn "*andqi_ext_1" 8505 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8506 (const_int 8) 8507 (const_int 8)) 8508 (and:SI 8509 (zero_extract:SI 8510 (match_operand 1 "ext_register_operand" "0") 8511 (const_int 8) 8512 (const_int 8)) 8513 (zero_extend:SI 8514 (match_operand:QI 2 "general_operand" "Qm")))) 8515 (clobber (reg:CC FLAGS_REG))] 8516 "!TARGET_64BIT" 8517 "and{b}\t{%2, %h0|%h0, %2}" 8518 [(set_attr "type" "alu") 8519 (set_attr "length_immediate" "0") 8520 (set_attr "mode" "QI")]) 8521 8522(define_insn "*andqi_ext_1_rex64" 8523 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8524 (const_int 8) 8525 (const_int 8)) 8526 (and:SI 8527 (zero_extract:SI 8528 (match_operand 1 "ext_register_operand" "0") 8529 (const_int 8) 8530 (const_int 8)) 8531 (zero_extend:SI 8532 (match_operand 2 "ext_register_operand" "Q")))) 8533 (clobber (reg:CC FLAGS_REG))] 8534 "TARGET_64BIT" 8535 "and{b}\t{%2, %h0|%h0, %2}" 8536 [(set_attr "type" "alu") 8537 (set_attr "length_immediate" "0") 8538 (set_attr "mode" "QI")]) 8539 8540(define_insn "*andqi_ext_2" 8541 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8542 (const_int 8) 8543 (const_int 8)) 8544 (and:SI 8545 (zero_extract:SI 8546 (match_operand 1 "ext_register_operand" "%0") 8547 (const_int 8) 8548 (const_int 8)) 8549 (zero_extract:SI 8550 (match_operand 2 "ext_register_operand" "Q") 8551 (const_int 8) 8552 (const_int 8)))) 8553 (clobber (reg:CC FLAGS_REG))] 8554 "" 8555 "and{b}\t{%h2, %h0|%h0, %h2}" 8556 [(set_attr "type" "alu") 8557 (set_attr "length_immediate" "0") 8558 (set_attr "mode" "QI")]) 8559 8560;; Convert wide AND instructions with immediate operand to shorter QImode 8561;; equivalents when possible. 8562;; Don't do the splitting with memory operands, since it introduces risk 8563;; of memory mismatch stalls. We may want to do the splitting for optimizing 8564;; for size, but that can (should?) be handled by generic code instead. 8565(define_split 8566 [(set (match_operand 0 "register_operand" "") 8567 (and (match_operand 1 "register_operand" "") 8568 (match_operand 2 "const_int_operand" ""))) 8569 (clobber (reg:CC FLAGS_REG))] 8570 "reload_completed 8571 && QI_REG_P (operands[0]) 8572 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8573 && !(~INTVAL (operands[2]) & ~(255 << 8)) 8574 && GET_MODE (operands[0]) != QImode" 8575 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8576 (and:SI (zero_extract:SI (match_dup 1) 8577 (const_int 8) (const_int 8)) 8578 (match_dup 2))) 8579 (clobber (reg:CC FLAGS_REG))])] 8580 "operands[0] = gen_lowpart (SImode, operands[0]); 8581 operands[1] = gen_lowpart (SImode, operands[1]); 8582 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") 8583 8584;; Since AND can be encoded with sign extended immediate, this is only 8585;; profitable when 7th bit is not set. 8586(define_split 8587 [(set (match_operand 0 "register_operand" "") 8588 (and (match_operand 1 "general_operand" "") 8589 (match_operand 2 "const_int_operand" ""))) 8590 (clobber (reg:CC FLAGS_REG))] 8591 "reload_completed 8592 && ANY_QI_REG_P (operands[0]) 8593 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8594 && !(~INTVAL (operands[2]) & ~255) 8595 && !(INTVAL (operands[2]) & 128) 8596 && GET_MODE (operands[0]) != QImode" 8597 [(parallel [(set (strict_low_part (match_dup 0)) 8598 (and:QI (match_dup 1) 8599 (match_dup 2))) 8600 (clobber (reg:CC FLAGS_REG))])] 8601 "operands[0] = gen_lowpart (QImode, operands[0]); 8602 operands[1] = gen_lowpart (QImode, operands[1]); 8603 operands[2] = gen_lowpart (QImode, operands[2]);") 8604 8605;; Logical inclusive OR instructions 8606 8607;; %%% This used to optimize known byte-wide and operations to memory. 8608;; If this is considered useful, it should be done with splitters. 8609 8610(define_expand "iordi3" 8611 [(set (match_operand:DI 0 "nonimmediate_operand" "") 8612 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "") 8613 (match_operand:DI 2 "x86_64_general_operand" ""))) 8614 (clobber (reg:CC FLAGS_REG))] 8615 "TARGET_64BIT" 8616 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;") 8617 8618(define_insn "*iordi_1_rex64" 8619 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 8620 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8621 (match_operand:DI 2 "x86_64_general_operand" "re,rme"))) 8622 (clobber (reg:CC FLAGS_REG))] 8623 "TARGET_64BIT 8624 && ix86_binary_operator_ok (IOR, DImode, operands)" 8625 "or{q}\t{%2, %0|%0, %2}" 8626 [(set_attr "type" "alu") 8627 (set_attr "mode" "DI")]) 8628 8629(define_insn "*iordi_2_rex64" 8630 [(set (reg FLAGS_REG) 8631 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8632 (match_operand:DI 2 "x86_64_general_operand" "rem,re")) 8633 (const_int 0))) 8634 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") 8635 (ior:DI (match_dup 1) (match_dup 2)))] 8636 "TARGET_64BIT 8637 && ix86_match_ccmode (insn, CCNOmode) 8638 && ix86_binary_operator_ok (IOR, DImode, operands)" 8639 "or{q}\t{%2, %0|%0, %2}" 8640 [(set_attr "type" "alu") 8641 (set_attr "mode" "DI")]) 8642 8643(define_insn "*iordi_3_rex64" 8644 [(set (reg FLAGS_REG) 8645 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0") 8646 (match_operand:DI 2 "x86_64_general_operand" "rem")) 8647 (const_int 0))) 8648 (clobber (match_scratch:DI 0 "=r"))] 8649 "TARGET_64BIT 8650 && ix86_match_ccmode (insn, CCNOmode) 8651 && ix86_binary_operator_ok (IOR, DImode, operands)" 8652 "or{q}\t{%2, %0|%0, %2}" 8653 [(set_attr "type" "alu") 8654 (set_attr "mode" "DI")]) 8655 8656 8657(define_expand "iorsi3" 8658 [(set (match_operand:SI 0 "nonimmediate_operand" "") 8659 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "") 8660 (match_operand:SI 2 "general_operand" ""))) 8661 (clobber (reg:CC FLAGS_REG))] 8662 "" 8663 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;") 8664 8665(define_insn "*iorsi_1" 8666 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 8667 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8668 (match_operand:SI 2 "general_operand" "ri,rmi"))) 8669 (clobber (reg:CC FLAGS_REG))] 8670 "ix86_binary_operator_ok (IOR, SImode, operands)" 8671 "or{l}\t{%2, %0|%0, %2}" 8672 [(set_attr "type" "alu") 8673 (set_attr "mode" "SI")]) 8674 8675;; See comment for addsi_1_zext why we do use nonimmediate_operand 8676(define_insn "*iorsi_1_zext" 8677 [(set (match_operand:DI 0 "register_operand" "=rm") 8678 (zero_extend:DI 8679 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8680 (match_operand:SI 2 "general_operand" "rim")))) 8681 (clobber (reg:CC FLAGS_REG))] 8682 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)" 8683 "or{l}\t{%2, %k0|%k0, %2}" 8684 [(set_attr "type" "alu") 8685 (set_attr "mode" "SI")]) 8686 8687(define_insn "*iorsi_1_zext_imm" 8688 [(set (match_operand:DI 0 "register_operand" "=rm") 8689 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 8690 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 8691 (clobber (reg:CC FLAGS_REG))] 8692 "TARGET_64BIT" 8693 "or{l}\t{%2, %k0|%k0, %2}" 8694 [(set_attr "type" "alu") 8695 (set_attr "mode" "SI")]) 8696 8697(define_insn "*iorsi_2" 8698 [(set (reg FLAGS_REG) 8699 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8700 (match_operand:SI 2 "general_operand" "rim,ri")) 8701 (const_int 0))) 8702 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 8703 (ior:SI (match_dup 1) (match_dup 2)))] 8704 "ix86_match_ccmode (insn, CCNOmode) 8705 && ix86_binary_operator_ok (IOR, SImode, operands)" 8706 "or{l}\t{%2, %0|%0, %2}" 8707 [(set_attr "type" "alu") 8708 (set_attr "mode" "SI")]) 8709 8710;; See comment for addsi_1_zext why we do use nonimmediate_operand 8711;; ??? Special case for immediate operand is missing - it is tricky. 8712(define_insn "*iorsi_2_zext" 8713 [(set (reg FLAGS_REG) 8714 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8715 (match_operand:SI 2 "general_operand" "rim")) 8716 (const_int 0))) 8717 (set (match_operand:DI 0 "register_operand" "=r") 8718 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))] 8719 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8720 && ix86_binary_operator_ok (IOR, SImode, operands)" 8721 "or{l}\t{%2, %k0|%k0, %2}" 8722 [(set_attr "type" "alu") 8723 (set_attr "mode" "SI")]) 8724 8725(define_insn "*iorsi_2_zext_imm" 8726 [(set (reg FLAGS_REG) 8727 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8728 (match_operand 2 "x86_64_zext_immediate_operand" "Z")) 8729 (const_int 0))) 8730 (set (match_operand:DI 0 "register_operand" "=r") 8731 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 8732 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8733 && ix86_binary_operator_ok (IOR, SImode, operands)" 8734 "or{l}\t{%2, %k0|%k0, %2}" 8735 [(set_attr "type" "alu") 8736 (set_attr "mode" "SI")]) 8737 8738(define_insn "*iorsi_3" 8739 [(set (reg FLAGS_REG) 8740 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8741 (match_operand:SI 2 "general_operand" "rim")) 8742 (const_int 0))) 8743 (clobber (match_scratch:SI 0 "=r"))] 8744 "ix86_match_ccmode (insn, CCNOmode) 8745 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 8746 "or{l}\t{%2, %0|%0, %2}" 8747 [(set_attr "type" "alu") 8748 (set_attr "mode" "SI")]) 8749 8750(define_expand "iorhi3" 8751 [(set (match_operand:HI 0 "nonimmediate_operand" "") 8752 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "") 8753 (match_operand:HI 2 "general_operand" ""))) 8754 (clobber (reg:CC FLAGS_REG))] 8755 "TARGET_HIMODE_MATH" 8756 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;") 8757 8758(define_insn "*iorhi_1" 8759 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m") 8760 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 8761 (match_operand:HI 2 "general_operand" "rmi,ri"))) 8762 (clobber (reg:CC FLAGS_REG))] 8763 "ix86_binary_operator_ok (IOR, HImode, operands)" 8764 "or{w}\t{%2, %0|%0, %2}" 8765 [(set_attr "type" "alu") 8766 (set_attr "mode" "HI")]) 8767 8768(define_insn "*iorhi_2" 8769 [(set (reg FLAGS_REG) 8770 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 8771 (match_operand:HI 2 "general_operand" "rim,ri")) 8772 (const_int 0))) 8773 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 8774 (ior:HI (match_dup 1) (match_dup 2)))] 8775 "ix86_match_ccmode (insn, CCNOmode) 8776 && ix86_binary_operator_ok (IOR, HImode, operands)" 8777 "or{w}\t{%2, %0|%0, %2}" 8778 [(set_attr "type" "alu") 8779 (set_attr "mode" "HI")]) 8780 8781(define_insn "*iorhi_3" 8782 [(set (reg FLAGS_REG) 8783 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0") 8784 (match_operand:HI 2 "general_operand" "rim")) 8785 (const_int 0))) 8786 (clobber (match_scratch:HI 0 "=r"))] 8787 "ix86_match_ccmode (insn, CCNOmode) 8788 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 8789 "or{w}\t{%2, %0|%0, %2}" 8790 [(set_attr "type" "alu") 8791 (set_attr "mode" "HI")]) 8792 8793(define_expand "iorqi3" 8794 [(set (match_operand:QI 0 "nonimmediate_operand" "") 8795 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "") 8796 (match_operand:QI 2 "general_operand" ""))) 8797 (clobber (reg:CC FLAGS_REG))] 8798 "TARGET_QIMODE_MATH" 8799 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;") 8800 8801;; %%% Potential partial reg stall on alternative 2. What to do? 8802(define_insn "*iorqi_1" 8803 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") 8804 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8805 (match_operand:QI 2 "general_operand" "qmi,qi,ri"))) 8806 (clobber (reg:CC FLAGS_REG))] 8807 "ix86_binary_operator_ok (IOR, QImode, operands)" 8808 "@ 8809 or{b}\t{%2, %0|%0, %2} 8810 or{b}\t{%2, %0|%0, %2} 8811 or{l}\t{%k2, %k0|%k0, %k2}" 8812 [(set_attr "type" "alu") 8813 (set_attr "mode" "QI,QI,SI")]) 8814 8815(define_insn "*iorqi_1_slp" 8816 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m")) 8817 (ior:QI (match_dup 0) 8818 (match_operand:QI 1 "general_operand" "qmi,qi"))) 8819 (clobber (reg:CC FLAGS_REG))] 8820 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8821 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8822 "or{b}\t{%1, %0|%0, %1}" 8823 [(set_attr "type" "alu1") 8824 (set_attr "mode" "QI")]) 8825 8826(define_insn "*iorqi_2" 8827 [(set (reg FLAGS_REG) 8828 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 8829 (match_operand:QI 2 "general_operand" "qim,qi")) 8830 (const_int 0))) 8831 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 8832 (ior:QI (match_dup 1) (match_dup 2)))] 8833 "ix86_match_ccmode (insn, CCNOmode) 8834 && ix86_binary_operator_ok (IOR, QImode, operands)" 8835 "or{b}\t{%2, %0|%0, %2}" 8836 [(set_attr "type" "alu") 8837 (set_attr "mode" "QI")]) 8838 8839(define_insn "*iorqi_2_slp" 8840 [(set (reg FLAGS_REG) 8841 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 8842 (match_operand:QI 1 "general_operand" "qim,qi")) 8843 (const_int 0))) 8844 (set (strict_low_part (match_dup 0)) 8845 (ior:QI (match_dup 0) (match_dup 1)))] 8846 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8847 && ix86_match_ccmode (insn, CCNOmode) 8848 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8849 "or{b}\t{%1, %0|%0, %1}" 8850 [(set_attr "type" "alu1") 8851 (set_attr "mode" "QI")]) 8852 8853(define_insn "*iorqi_3" 8854 [(set (reg FLAGS_REG) 8855 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 8856 (match_operand:QI 2 "general_operand" "qim")) 8857 (const_int 0))) 8858 (clobber (match_scratch:QI 0 "=q"))] 8859 "ix86_match_ccmode (insn, CCNOmode) 8860 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 8861 "or{b}\t{%2, %0|%0, %2}" 8862 [(set_attr "type" "alu") 8863 (set_attr "mode" "QI")]) 8864 8865(define_insn "iorqi_ext_0" 8866 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8867 (const_int 8) 8868 (const_int 8)) 8869 (ior:SI 8870 (zero_extract:SI 8871 (match_operand 1 "ext_register_operand" "0") 8872 (const_int 8) 8873 (const_int 8)) 8874 (match_operand 2 "const_int_operand" "n"))) 8875 (clobber (reg:CC FLAGS_REG))] 8876 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 8877 "or{b}\t{%2, %h0|%h0, %2}" 8878 [(set_attr "type" "alu") 8879 (set_attr "length_immediate" "1") 8880 (set_attr "mode" "QI")]) 8881 8882(define_insn "*iorqi_ext_1" 8883 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8884 (const_int 8) 8885 (const_int 8)) 8886 (ior:SI 8887 (zero_extract:SI 8888 (match_operand 1 "ext_register_operand" "0") 8889 (const_int 8) 8890 (const_int 8)) 8891 (zero_extend:SI 8892 (match_operand:QI 2 "general_operand" "Qm")))) 8893 (clobber (reg:CC FLAGS_REG))] 8894 "!TARGET_64BIT 8895 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 8896 "or{b}\t{%2, %h0|%h0, %2}" 8897 [(set_attr "type" "alu") 8898 (set_attr "length_immediate" "0") 8899 (set_attr "mode" "QI")]) 8900 8901(define_insn "*iorqi_ext_1_rex64" 8902 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8903 (const_int 8) 8904 (const_int 8)) 8905 (ior:SI 8906 (zero_extract:SI 8907 (match_operand 1 "ext_register_operand" "0") 8908 (const_int 8) 8909 (const_int 8)) 8910 (zero_extend:SI 8911 (match_operand 2 "ext_register_operand" "Q")))) 8912 (clobber (reg:CC FLAGS_REG))] 8913 "TARGET_64BIT 8914 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 8915 "or{b}\t{%2, %h0|%h0, %2}" 8916 [(set_attr "type" "alu") 8917 (set_attr "length_immediate" "0") 8918 (set_attr "mode" "QI")]) 8919 8920(define_insn "*iorqi_ext_2" 8921 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8922 (const_int 8) 8923 (const_int 8)) 8924 (ior:SI 8925 (zero_extract:SI (match_operand 1 "ext_register_operand" "0") 8926 (const_int 8) 8927 (const_int 8)) 8928 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 8929 (const_int 8) 8930 (const_int 8)))) 8931 (clobber (reg:CC FLAGS_REG))] 8932 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 8933 "ior{b}\t{%h2, %h0|%h0, %h2}" 8934 [(set_attr "type" "alu") 8935 (set_attr "length_immediate" "0") 8936 (set_attr "mode" "QI")]) 8937 8938(define_split 8939 [(set (match_operand 0 "register_operand" "") 8940 (ior (match_operand 1 "register_operand" "") 8941 (match_operand 2 "const_int_operand" ""))) 8942 (clobber (reg:CC FLAGS_REG))] 8943 "reload_completed 8944 && QI_REG_P (operands[0]) 8945 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8946 && !(INTVAL (operands[2]) & ~(255 << 8)) 8947 && GET_MODE (operands[0]) != QImode" 8948 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8949 (ior:SI (zero_extract:SI (match_dup 1) 8950 (const_int 8) (const_int 8)) 8951 (match_dup 2))) 8952 (clobber (reg:CC FLAGS_REG))])] 8953 "operands[0] = gen_lowpart (SImode, operands[0]); 8954 operands[1] = gen_lowpart (SImode, operands[1]); 8955 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") 8956 8957;; Since OR can be encoded with sign extended immediate, this is only 8958;; profitable when 7th bit is set. 8959(define_split 8960 [(set (match_operand 0 "register_operand" "") 8961 (ior (match_operand 1 "general_operand" "") 8962 (match_operand 2 "const_int_operand" ""))) 8963 (clobber (reg:CC FLAGS_REG))] 8964 "reload_completed 8965 && ANY_QI_REG_P (operands[0]) 8966 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8967 && !(INTVAL (operands[2]) & ~255) 8968 && (INTVAL (operands[2]) & 128) 8969 && GET_MODE (operands[0]) != QImode" 8970 [(parallel [(set (strict_low_part (match_dup 0)) 8971 (ior:QI (match_dup 1) 8972 (match_dup 2))) 8973 (clobber (reg:CC FLAGS_REG))])] 8974 "operands[0] = gen_lowpart (QImode, operands[0]); 8975 operands[1] = gen_lowpart (QImode, operands[1]); 8976 operands[2] = gen_lowpart (QImode, operands[2]);") 8977 8978;; Logical XOR instructions 8979 8980;; %%% This used to optimize known byte-wide and operations to memory. 8981;; If this is considered useful, it should be done with splitters. 8982 8983(define_expand "xordi3" 8984 [(set (match_operand:DI 0 "nonimmediate_operand" "") 8985 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "") 8986 (match_operand:DI 2 "x86_64_general_operand" ""))) 8987 (clobber (reg:CC FLAGS_REG))] 8988 "TARGET_64BIT" 8989 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;") 8990 8991(define_insn "*xordi_1_rex64" 8992 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 8993 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8994 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 8995 (clobber (reg:CC FLAGS_REG))] 8996 "TARGET_64BIT 8997 && ix86_binary_operator_ok (XOR, DImode, operands)" 8998 "@ 8999 xor{q}\t{%2, %0|%0, %2} 9000 xor{q}\t{%2, %0|%0, %2}" 9001 [(set_attr "type" "alu") 9002 (set_attr "mode" "DI,DI")]) 9003 9004(define_insn "*xordi_2_rex64" 9005 [(set (reg FLAGS_REG) 9006 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 9007 (match_operand:DI 2 "x86_64_general_operand" "rem,re")) 9008 (const_int 0))) 9009 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") 9010 (xor:DI (match_dup 1) (match_dup 2)))] 9011 "TARGET_64BIT 9012 && ix86_match_ccmode (insn, CCNOmode) 9013 && ix86_binary_operator_ok (XOR, DImode, operands)" 9014 "@ 9015 xor{q}\t{%2, %0|%0, %2} 9016 xor{q}\t{%2, %0|%0, %2}" 9017 [(set_attr "type" "alu") 9018 (set_attr "mode" "DI,DI")]) 9019 9020(define_insn "*xordi_3_rex64" 9021 [(set (reg FLAGS_REG) 9022 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0") 9023 (match_operand:DI 2 "x86_64_general_operand" "rem")) 9024 (const_int 0))) 9025 (clobber (match_scratch:DI 0 "=r"))] 9026 "TARGET_64BIT 9027 && ix86_match_ccmode (insn, CCNOmode) 9028 && ix86_binary_operator_ok (XOR, DImode, operands)" 9029 "xor{q}\t{%2, %0|%0, %2}" 9030 [(set_attr "type" "alu") 9031 (set_attr "mode" "DI")]) 9032 9033(define_expand "xorsi3" 9034 [(set (match_operand:SI 0 "nonimmediate_operand" "") 9035 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "") 9036 (match_operand:SI 2 "general_operand" ""))) 9037 (clobber (reg:CC FLAGS_REG))] 9038 "" 9039 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;") 9040 9041(define_insn "*xorsi_1" 9042 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 9043 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 9044 (match_operand:SI 2 "general_operand" "ri,rm"))) 9045 (clobber (reg:CC FLAGS_REG))] 9046 "ix86_binary_operator_ok (XOR, SImode, operands)" 9047 "xor{l}\t{%2, %0|%0, %2}" 9048 [(set_attr "type" "alu") 9049 (set_attr "mode" "SI")]) 9050 9051;; See comment for addsi_1_zext why we do use nonimmediate_operand 9052;; Add speccase for immediates 9053(define_insn "*xorsi_1_zext" 9054 [(set (match_operand:DI 0 "register_operand" "=r") 9055 (zero_extend:DI 9056 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9057 (match_operand:SI 2 "general_operand" "rim")))) 9058 (clobber (reg:CC FLAGS_REG))] 9059 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)" 9060 "xor{l}\t{%2, %k0|%k0, %2}" 9061 [(set_attr "type" "alu") 9062 (set_attr "mode" "SI")]) 9063 9064(define_insn "*xorsi_1_zext_imm" 9065 [(set (match_operand:DI 0 "register_operand" "=r") 9066 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 9067 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 9068 (clobber (reg:CC FLAGS_REG))] 9069 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)" 9070 "xor{l}\t{%2, %k0|%k0, %2}" 9071 [(set_attr "type" "alu") 9072 (set_attr "mode" "SI")]) 9073 9074(define_insn "*xorsi_2" 9075 [(set (reg FLAGS_REG) 9076 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 9077 (match_operand:SI 2 "general_operand" "rim,ri")) 9078 (const_int 0))) 9079 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 9080 (xor:SI (match_dup 1) (match_dup 2)))] 9081 "ix86_match_ccmode (insn, CCNOmode) 9082 && ix86_binary_operator_ok (XOR, SImode, operands)" 9083 "xor{l}\t{%2, %0|%0, %2}" 9084 [(set_attr "type" "alu") 9085 (set_attr "mode" "SI")]) 9086 9087;; See comment for addsi_1_zext why we do use nonimmediate_operand 9088;; ??? Special case for immediate operand is missing - it is tricky. 9089(define_insn "*xorsi_2_zext" 9090 [(set (reg FLAGS_REG) 9091 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9092 (match_operand:SI 2 "general_operand" "rim")) 9093 (const_int 0))) 9094 (set (match_operand:DI 0 "register_operand" "=r") 9095 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))] 9096 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9097 && ix86_binary_operator_ok (XOR, SImode, operands)" 9098 "xor{l}\t{%2, %k0|%k0, %2}" 9099 [(set_attr "type" "alu") 9100 (set_attr "mode" "SI")]) 9101 9102(define_insn "*xorsi_2_zext_imm" 9103 [(set (reg FLAGS_REG) 9104 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9105 (match_operand 2 "x86_64_zext_immediate_operand" "Z")) 9106 (const_int 0))) 9107 (set (match_operand:DI 0 "register_operand" "=r") 9108 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 9109 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9110 && ix86_binary_operator_ok (XOR, SImode, operands)" 9111 "xor{l}\t{%2, %k0|%k0, %2}" 9112 [(set_attr "type" "alu") 9113 (set_attr "mode" "SI")]) 9114 9115(define_insn "*xorsi_3" 9116 [(set (reg FLAGS_REG) 9117 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9118 (match_operand:SI 2 "general_operand" "rim")) 9119 (const_int 0))) 9120 (clobber (match_scratch:SI 0 "=r"))] 9121 "ix86_match_ccmode (insn, CCNOmode) 9122 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 9123 "xor{l}\t{%2, %0|%0, %2}" 9124 [(set_attr "type" "alu") 9125 (set_attr "mode" "SI")]) 9126 9127(define_expand "xorhi3" 9128 [(set (match_operand:HI 0 "nonimmediate_operand" "") 9129 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "") 9130 (match_operand:HI 2 "general_operand" ""))) 9131 (clobber (reg:CC FLAGS_REG))] 9132 "TARGET_HIMODE_MATH" 9133 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;") 9134 9135(define_insn "*xorhi_1" 9136 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m") 9137 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 9138 (match_operand:HI 2 "general_operand" "rmi,ri"))) 9139 (clobber (reg:CC FLAGS_REG))] 9140 "ix86_binary_operator_ok (XOR, HImode, operands)" 9141 "xor{w}\t{%2, %0|%0, %2}" 9142 [(set_attr "type" "alu") 9143 (set_attr "mode" "HI")]) 9144 9145(define_insn "*xorhi_2" 9146 [(set (reg FLAGS_REG) 9147 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 9148 (match_operand:HI 2 "general_operand" "rim,ri")) 9149 (const_int 0))) 9150 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 9151 (xor:HI (match_dup 1) (match_dup 2)))] 9152 "ix86_match_ccmode (insn, CCNOmode) 9153 && ix86_binary_operator_ok (XOR, HImode, operands)" 9154 "xor{w}\t{%2, %0|%0, %2}" 9155 [(set_attr "type" "alu") 9156 (set_attr "mode" "HI")]) 9157 9158(define_insn "*xorhi_3" 9159 [(set (reg FLAGS_REG) 9160 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0") 9161 (match_operand:HI 2 "general_operand" "rim")) 9162 (const_int 0))) 9163 (clobber (match_scratch:HI 0 "=r"))] 9164 "ix86_match_ccmode (insn, CCNOmode) 9165 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 9166 "xor{w}\t{%2, %0|%0, %2}" 9167 [(set_attr "type" "alu") 9168 (set_attr "mode" "HI")]) 9169 9170(define_expand "xorqi3" 9171 [(set (match_operand:QI 0 "nonimmediate_operand" "") 9172 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "") 9173 (match_operand:QI 2 "general_operand" ""))) 9174 (clobber (reg:CC FLAGS_REG))] 9175 "TARGET_QIMODE_MATH" 9176 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;") 9177 9178;; %%% Potential partial reg stall on alternative 2. What to do? 9179(define_insn "*xorqi_1" 9180 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") 9181 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 9182 (match_operand:QI 2 "general_operand" "qmi,qi,ri"))) 9183 (clobber (reg:CC FLAGS_REG))] 9184 "ix86_binary_operator_ok (XOR, QImode, operands)" 9185 "@ 9186 xor{b}\t{%2, %0|%0, %2} 9187 xor{b}\t{%2, %0|%0, %2} 9188 xor{l}\t{%k2, %k0|%k0, %k2}" 9189 [(set_attr "type" "alu") 9190 (set_attr "mode" "QI,QI,SI")]) 9191 9192(define_insn "*xorqi_1_slp" 9193 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 9194 (xor:QI (match_dup 0) 9195 (match_operand:QI 1 "general_operand" "qi,qmi"))) 9196 (clobber (reg:CC FLAGS_REG))] 9197 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 9198 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 9199 "xor{b}\t{%1, %0|%0, %1}" 9200 [(set_attr "type" "alu1") 9201 (set_attr "mode" "QI")]) 9202 9203(define_insn "xorqi_ext_0" 9204 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9205 (const_int 8) 9206 (const_int 8)) 9207 (xor:SI 9208 (zero_extract:SI 9209 (match_operand 1 "ext_register_operand" "0") 9210 (const_int 8) 9211 (const_int 8)) 9212 (match_operand 2 "const_int_operand" "n"))) 9213 (clobber (reg:CC FLAGS_REG))] 9214 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 9215 "xor{b}\t{%2, %h0|%h0, %2}" 9216 [(set_attr "type" "alu") 9217 (set_attr "length_immediate" "1") 9218 (set_attr "mode" "QI")]) 9219 9220(define_insn "*xorqi_ext_1" 9221 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9222 (const_int 8) 9223 (const_int 8)) 9224 (xor:SI 9225 (zero_extract:SI 9226 (match_operand 1 "ext_register_operand" "0") 9227 (const_int 8) 9228 (const_int 8)) 9229 (zero_extend:SI 9230 (match_operand:QI 2 "general_operand" "Qm")))) 9231 (clobber (reg:CC FLAGS_REG))] 9232 "!TARGET_64BIT 9233 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 9234 "xor{b}\t{%2, %h0|%h0, %2}" 9235 [(set_attr "type" "alu") 9236 (set_attr "length_immediate" "0") 9237 (set_attr "mode" "QI")]) 9238 9239(define_insn "*xorqi_ext_1_rex64" 9240 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9241 (const_int 8) 9242 (const_int 8)) 9243 (xor:SI 9244 (zero_extract:SI 9245 (match_operand 1 "ext_register_operand" "0") 9246 (const_int 8) 9247 (const_int 8)) 9248 (zero_extend:SI 9249 (match_operand 2 "ext_register_operand" "Q")))) 9250 (clobber (reg:CC FLAGS_REG))] 9251 "TARGET_64BIT 9252 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 9253 "xor{b}\t{%2, %h0|%h0, %2}" 9254 [(set_attr "type" "alu") 9255 (set_attr "length_immediate" "0") 9256 (set_attr "mode" "QI")]) 9257 9258(define_insn "*xorqi_ext_2" 9259 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9260 (const_int 8) 9261 (const_int 8)) 9262 (xor:SI 9263 (zero_extract:SI (match_operand 1 "ext_register_operand" "0") 9264 (const_int 8) 9265 (const_int 8)) 9266 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 9267 (const_int 8) 9268 (const_int 8)))) 9269 (clobber (reg:CC FLAGS_REG))] 9270 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 9271 "xor{b}\t{%h2, %h0|%h0, %h2}" 9272 [(set_attr "type" "alu") 9273 (set_attr "length_immediate" "0") 9274 (set_attr "mode" "QI")]) 9275 9276(define_insn "*xorqi_cc_1" 9277 [(set (reg FLAGS_REG) 9278 (compare 9279 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 9280 (match_operand:QI 2 "general_operand" "qim,qi")) 9281 (const_int 0))) 9282 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 9283 (xor:QI (match_dup 1) (match_dup 2)))] 9284 "ix86_match_ccmode (insn, CCNOmode) 9285 && ix86_binary_operator_ok (XOR, QImode, operands)" 9286 "xor{b}\t{%2, %0|%0, %2}" 9287 [(set_attr "type" "alu") 9288 (set_attr "mode" "QI")]) 9289 9290(define_insn "*xorqi_2_slp" 9291 [(set (reg FLAGS_REG) 9292 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 9293 (match_operand:QI 1 "general_operand" "qim,qi")) 9294 (const_int 0))) 9295 (set (strict_low_part (match_dup 0)) 9296 (xor:QI (match_dup 0) (match_dup 1)))] 9297 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 9298 && ix86_match_ccmode (insn, CCNOmode) 9299 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 9300 "xor{b}\t{%1, %0|%0, %1}" 9301 [(set_attr "type" "alu1") 9302 (set_attr "mode" "QI")]) 9303 9304(define_insn "*xorqi_cc_2" 9305 [(set (reg FLAGS_REG) 9306 (compare 9307 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 9308 (match_operand:QI 2 "general_operand" "qim")) 9309 (const_int 0))) 9310 (clobber (match_scratch:QI 0 "=q"))] 9311 "ix86_match_ccmode (insn, CCNOmode) 9312 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 9313 "xor{b}\t{%2, %0|%0, %2}" 9314 [(set_attr "type" "alu") 9315 (set_attr "mode" "QI")]) 9316 9317(define_insn "*xorqi_cc_ext_1" 9318 [(set (reg FLAGS_REG) 9319 (compare 9320 (xor:SI 9321 (zero_extract:SI 9322 (match_operand 1 "ext_register_operand" "0") 9323 (const_int 8) 9324 (const_int 8)) 9325 (match_operand:QI 2 "general_operand" "qmn")) 9326 (const_int 0))) 9327 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q") 9328 (const_int 8) 9329 (const_int 8)) 9330 (xor:SI 9331 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) 9332 (match_dup 2)))] 9333 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 9334 "xor{b}\t{%2, %h0|%h0, %2}" 9335 [(set_attr "type" "alu") 9336 (set_attr "mode" "QI")]) 9337 9338(define_insn "*xorqi_cc_ext_1_rex64" 9339 [(set (reg FLAGS_REG) 9340 (compare 9341 (xor:SI 9342 (zero_extract:SI 9343 (match_operand 1 "ext_register_operand" "0") 9344 (const_int 8) 9345 (const_int 8)) 9346 (match_operand:QI 2 "nonmemory_operand" "Qn")) 9347 (const_int 0))) 9348 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9349 (const_int 8) 9350 (const_int 8)) 9351 (xor:SI 9352 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) 9353 (match_dup 2)))] 9354 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 9355 "xor{b}\t{%2, %h0|%h0, %2}" 9356 [(set_attr "type" "alu") 9357 (set_attr "mode" "QI")]) 9358 9359(define_expand "xorqi_cc_ext_1" 9360 [(parallel [ 9361 (set (reg:CCNO FLAGS_REG) 9362 (compare:CCNO 9363 (xor:SI 9364 (zero_extract:SI 9365 (match_operand 1 "ext_register_operand" "") 9366 (const_int 8) 9367 (const_int 8)) 9368 (match_operand:QI 2 "general_operand" "")) 9369 (const_int 0))) 9370 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "") 9371 (const_int 8) 9372 (const_int 8)) 9373 (xor:SI 9374 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) 9375 (match_dup 2)))])] 9376 "" 9377 "") 9378 9379(define_split 9380 [(set (match_operand 0 "register_operand" "") 9381 (xor (match_operand 1 "register_operand" "") 9382 (match_operand 2 "const_int_operand" ""))) 9383 (clobber (reg:CC FLAGS_REG))] 9384 "reload_completed 9385 && QI_REG_P (operands[0]) 9386 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 9387 && !(INTVAL (operands[2]) & ~(255 << 8)) 9388 && GET_MODE (operands[0]) != QImode" 9389 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 9390 (xor:SI (zero_extract:SI (match_dup 1) 9391 (const_int 8) (const_int 8)) 9392 (match_dup 2))) 9393 (clobber (reg:CC FLAGS_REG))])] 9394 "operands[0] = gen_lowpart (SImode, operands[0]); 9395 operands[1] = gen_lowpart (SImode, operands[1]); 9396 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") 9397 9398;; Since XOR can be encoded with sign extended immediate, this is only 9399;; profitable when 7th bit is set. 9400(define_split 9401 [(set (match_operand 0 "register_operand" "") 9402 (xor (match_operand 1 "general_operand" "") 9403 (match_operand 2 "const_int_operand" ""))) 9404 (clobber (reg:CC FLAGS_REG))] 9405 "reload_completed 9406 && ANY_QI_REG_P (operands[0]) 9407 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 9408 && !(INTVAL (operands[2]) & ~255) 9409 && (INTVAL (operands[2]) & 128) 9410 && GET_MODE (operands[0]) != QImode" 9411 [(parallel [(set (strict_low_part (match_dup 0)) 9412 (xor:QI (match_dup 1) 9413 (match_dup 2))) 9414 (clobber (reg:CC FLAGS_REG))])] 9415 "operands[0] = gen_lowpart (QImode, operands[0]); 9416 operands[1] = gen_lowpart (QImode, operands[1]); 9417 operands[2] = gen_lowpart (QImode, operands[2]);") 9418 9419;; Negation instructions 9420 9421(define_expand "negti2" 9422 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "") 9423 (neg:TI (match_operand:TI 1 "nonimmediate_operand" ""))) 9424 (clobber (reg:CC FLAGS_REG))])] 9425 "TARGET_64BIT" 9426 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;") 9427 9428(define_insn "*negti2_1" 9429 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro") 9430 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0"))) 9431 (clobber (reg:CC FLAGS_REG))] 9432 "TARGET_64BIT 9433 && ix86_unary_operator_ok (NEG, TImode, operands)" 9434 "#") 9435 9436(define_split 9437 [(set (match_operand:TI 0 "nonimmediate_operand" "") 9438 (neg:TI (match_operand:TI 1 "nonimmediate_operand" ""))) 9439 (clobber (reg:CC FLAGS_REG))] 9440 "TARGET_64BIT && reload_completed" 9441 [(parallel 9442 [(set (reg:CCZ FLAGS_REG) 9443 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0))) 9444 (set (match_dup 0) (neg:DI (match_dup 2)))]) 9445 (parallel 9446 [(set (match_dup 1) 9447 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) 9448 (match_dup 3)) 9449 (const_int 0))) 9450 (clobber (reg:CC FLAGS_REG))]) 9451 (parallel 9452 [(set (match_dup 1) 9453 (neg:DI (match_dup 1))) 9454 (clobber (reg:CC FLAGS_REG))])] 9455 "split_ti (operands+1, 1, operands+2, operands+3); 9456 split_ti (operands+0, 1, operands+0, operands+1);") 9457 9458(define_expand "negdi2" 9459 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 9460 (neg:DI (match_operand:DI 1 "nonimmediate_operand" ""))) 9461 (clobber (reg:CC FLAGS_REG))])] 9462 "" 9463 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;") 9464 9465(define_insn "*negdi2_1" 9466 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro") 9467 (neg:DI (match_operand:DI 1 "general_operand" "0"))) 9468 (clobber (reg:CC FLAGS_REG))] 9469 "!TARGET_64BIT 9470 && ix86_unary_operator_ok (NEG, DImode, operands)" 9471 "#") 9472 9473(define_split 9474 [(set (match_operand:DI 0 "nonimmediate_operand" "") 9475 (neg:DI (match_operand:DI 1 "general_operand" ""))) 9476 (clobber (reg:CC FLAGS_REG))] 9477 "!TARGET_64BIT && reload_completed" 9478 [(parallel 9479 [(set (reg:CCZ FLAGS_REG) 9480 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0))) 9481 (set (match_dup 0) (neg:SI (match_dup 2)))]) 9482 (parallel 9483 [(set (match_dup 1) 9484 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) 9485 (match_dup 3)) 9486 (const_int 0))) 9487 (clobber (reg:CC FLAGS_REG))]) 9488 (parallel 9489 [(set (match_dup 1) 9490 (neg:SI (match_dup 1))) 9491 (clobber (reg:CC FLAGS_REG))])] 9492 "split_di (operands+1, 1, operands+2, operands+3); 9493 split_di (operands+0, 1, operands+0, operands+1);") 9494 9495(define_insn "*negdi2_1_rex64" 9496 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9497 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))) 9498 (clobber (reg:CC FLAGS_REG))] 9499 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)" 9500 "neg{q}\t%0" 9501 [(set_attr "type" "negnot") 9502 (set_attr "mode" "DI")]) 9503 9504;; The problem with neg is that it does not perform (compare x 0), 9505;; it really performs (compare 0 x), which leaves us with the zero 9506;; flag being the only useful item. 9507 9508(define_insn "*negdi2_cmpz_rex64" 9509 [(set (reg:CCZ FLAGS_REG) 9510 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")) 9511 (const_int 0))) 9512 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9513 (neg:DI (match_dup 1)))] 9514 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)" 9515 "neg{q}\t%0" 9516 [(set_attr "type" "negnot") 9517 (set_attr "mode" "DI")]) 9518 9519 9520(define_expand "negsi2" 9521 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 9522 (neg:SI (match_operand:SI 1 "nonimmediate_operand" ""))) 9523 (clobber (reg:CC FLAGS_REG))])] 9524 "" 9525 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;") 9526 9527(define_insn "*negsi2_1" 9528 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 9529 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))) 9530 (clobber (reg:CC FLAGS_REG))] 9531 "ix86_unary_operator_ok (NEG, SImode, operands)" 9532 "neg{l}\t%0" 9533 [(set_attr "type" "negnot") 9534 (set_attr "mode" "SI")]) 9535 9536;; Combine is quite creative about this pattern. 9537(define_insn "*negsi2_1_zext" 9538 [(set (match_operand:DI 0 "register_operand" "=r") 9539 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0") 9540 (const_int 32))) 9541 (const_int 32))) 9542 (clobber (reg:CC FLAGS_REG))] 9543 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9544 "neg{l}\t%k0" 9545 [(set_attr "type" "negnot") 9546 (set_attr "mode" "SI")]) 9547 9548;; The problem with neg is that it does not perform (compare x 0), 9549;; it really performs (compare 0 x), which leaves us with the zero 9550;; flag being the only useful item. 9551 9552(define_insn "*negsi2_cmpz" 9553 [(set (reg:CCZ FLAGS_REG) 9554 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")) 9555 (const_int 0))) 9556 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 9557 (neg:SI (match_dup 1)))] 9558 "ix86_unary_operator_ok (NEG, SImode, operands)" 9559 "neg{l}\t%0" 9560 [(set_attr "type" "negnot") 9561 (set_attr "mode" "SI")]) 9562 9563(define_insn "*negsi2_cmpz_zext" 9564 [(set (reg:CCZ FLAGS_REG) 9565 (compare:CCZ (lshiftrt:DI 9566 (neg:DI (ashift:DI 9567 (match_operand:DI 1 "register_operand" "0") 9568 (const_int 32))) 9569 (const_int 32)) 9570 (const_int 0))) 9571 (set (match_operand:DI 0 "register_operand" "=r") 9572 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1) 9573 (const_int 32))) 9574 (const_int 32)))] 9575 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9576 "neg{l}\t%k0" 9577 [(set_attr "type" "negnot") 9578 (set_attr "mode" "SI")]) 9579 9580(define_expand "neghi2" 9581 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 9582 (neg:HI (match_operand:HI 1 "nonimmediate_operand" ""))) 9583 (clobber (reg:CC FLAGS_REG))])] 9584 "TARGET_HIMODE_MATH" 9585 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;") 9586 9587(define_insn "*neghi2_1" 9588 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 9589 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))) 9590 (clobber (reg:CC FLAGS_REG))] 9591 "ix86_unary_operator_ok (NEG, HImode, operands)" 9592 "neg{w}\t%0" 9593 [(set_attr "type" "negnot") 9594 (set_attr "mode" "HI")]) 9595 9596(define_insn "*neghi2_cmpz" 9597 [(set (reg:CCZ FLAGS_REG) 9598 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")) 9599 (const_int 0))) 9600 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 9601 (neg:HI (match_dup 1)))] 9602 "ix86_unary_operator_ok (NEG, HImode, operands)" 9603 "neg{w}\t%0" 9604 [(set_attr "type" "negnot") 9605 (set_attr "mode" "HI")]) 9606 9607(define_expand "negqi2" 9608 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") 9609 (neg:QI (match_operand:QI 1 "nonimmediate_operand" ""))) 9610 (clobber (reg:CC FLAGS_REG))])] 9611 "TARGET_QIMODE_MATH" 9612 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;") 9613 9614(define_insn "*negqi2_1" 9615 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 9616 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))) 9617 (clobber (reg:CC FLAGS_REG))] 9618 "ix86_unary_operator_ok (NEG, QImode, operands)" 9619 "neg{b}\t%0" 9620 [(set_attr "type" "negnot") 9621 (set_attr "mode" "QI")]) 9622 9623(define_insn "*negqi2_cmpz" 9624 [(set (reg:CCZ FLAGS_REG) 9625 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")) 9626 (const_int 0))) 9627 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 9628 (neg:QI (match_dup 1)))] 9629 "ix86_unary_operator_ok (NEG, QImode, operands)" 9630 "neg{b}\t%0" 9631 [(set_attr "type" "negnot") 9632 (set_attr "mode" "QI")]) 9633 9634;; Changing of sign for FP values is doable using integer unit too. 9635 9636(define_expand "negsf2" 9637 [(set (match_operand:SF 0 "nonimmediate_operand" "") 9638 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))] 9639 "TARGET_80387 || TARGET_SSE_MATH" 9640 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;") 9641 9642(define_expand "abssf2" 9643 [(set (match_operand:SF 0 "nonimmediate_operand" "") 9644 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))] 9645 "TARGET_80387 || TARGET_SSE_MATH" 9646 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;") 9647 9648(define_insn "*absnegsf2_mixed" 9649 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm") 9650 (match_operator:SF 3 "absneg_operator" 9651 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")])) 9652 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X ")) 9653 (clobber (reg:CC FLAGS_REG))] 9654 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387 9655 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)" 9656 "#") 9657 9658(define_insn "*absnegsf2_sse" 9659 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm") 9660 (match_operator:SF 3 "absneg_operator" 9661 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")])) 9662 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X")) 9663 (clobber (reg:CC FLAGS_REG))] 9664 "TARGET_SSE_MATH 9665 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)" 9666 "#") 9667 9668(define_insn "*absnegsf2_i387" 9669 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm") 9670 (match_operator:SF 3 "absneg_operator" 9671 [(match_operand:SF 1 "nonimmediate_operand" "0,0")])) 9672 (use (match_operand 2 "" "")) 9673 (clobber (reg:CC FLAGS_REG))] 9674 "TARGET_80387 && !TARGET_SSE_MATH 9675 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)" 9676 "#") 9677 9678(define_expand "copysignsf3" 9679 [(match_operand:SF 0 "register_operand" "") 9680 (match_operand:SF 1 "nonmemory_operand" "") 9681 (match_operand:SF 2 "register_operand" "")] 9682 "TARGET_SSE_MATH" 9683{ 9684 ix86_expand_copysign (operands); 9685 DONE; 9686}) 9687 9688(define_insn_and_split "copysignsf3_const" 9689 [(set (match_operand:SF 0 "register_operand" "=x") 9690 (unspec:SF 9691 [(match_operand:V4SF 1 "vector_move_operand" "xmC") 9692 (match_operand:SF 2 "register_operand" "0") 9693 (match_operand:V4SF 3 "nonimmediate_operand" "xm")] 9694 UNSPEC_COPYSIGN))] 9695 "TARGET_SSE_MATH" 9696 "#" 9697 "&& reload_completed" 9698 [(const_int 0)] 9699{ 9700 ix86_split_copysign_const (operands); 9701 DONE; 9702}) 9703 9704(define_insn "copysignsf3_var" 9705 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x") 9706 (unspec:SF 9707 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x") 9708 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x") 9709 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0") 9710 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")] 9711 UNSPEC_COPYSIGN)) 9712 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))] 9713 "TARGET_SSE_MATH" 9714 "#") 9715 9716(define_split 9717 [(set (match_operand:SF 0 "register_operand" "") 9718 (unspec:SF 9719 [(match_operand:SF 2 "register_operand" "") 9720 (match_operand:SF 3 "register_operand" "") 9721 (match_operand:V4SF 4 "" "") 9722 (match_operand:V4SF 5 "" "")] 9723 UNSPEC_COPYSIGN)) 9724 (clobber (match_scratch:V4SF 1 ""))] 9725 "TARGET_SSE_MATH && reload_completed" 9726 [(const_int 0)] 9727{ 9728 ix86_split_copysign_var (operands); 9729 DONE; 9730}) 9731 9732(define_expand "negdf2" 9733 [(set (match_operand:DF 0 "nonimmediate_operand" "") 9734 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))] 9735 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 9736 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;") 9737 9738(define_expand "absdf2" 9739 [(set (match_operand:DF 0 "nonimmediate_operand" "") 9740 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))] 9741 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 9742 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;") 9743 9744(define_insn "*absnegdf2_mixed" 9745 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm") 9746 (match_operator:DF 3 "absneg_operator" 9747 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")])) 9748 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X")) 9749 (clobber (reg:CC FLAGS_REG))] 9750 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387 9751 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)" 9752 "#") 9753 9754(define_insn "*absnegdf2_sse" 9755 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm") 9756 (match_operator:DF 3 "absneg_operator" 9757 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")])) 9758 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X ")) 9759 (clobber (reg:CC FLAGS_REG))] 9760 "TARGET_SSE2 && TARGET_SSE_MATH 9761 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)" 9762 "#") 9763 9764(define_insn "*absnegdf2_i387" 9765 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm") 9766 (match_operator:DF 3 "absneg_operator" 9767 [(match_operand:DF 1 "nonimmediate_operand" "0,0")])) 9768 (use (match_operand 2 "" "")) 9769 (clobber (reg:CC FLAGS_REG))] 9770 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH) 9771 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)" 9772 "#") 9773 9774(define_expand "copysigndf3" 9775 [(match_operand:DF 0 "register_operand" "") 9776 (match_operand:DF 1 "nonmemory_operand" "") 9777 (match_operand:DF 2 "register_operand" "")] 9778 "TARGET_SSE2 && TARGET_SSE_MATH" 9779{ 9780 ix86_expand_copysign (operands); 9781 DONE; 9782}) 9783 9784(define_insn_and_split "copysigndf3_const" 9785 [(set (match_operand:DF 0 "register_operand" "=x") 9786 (unspec:DF 9787 [(match_operand:V2DF 1 "vector_move_operand" "xmC") 9788 (match_operand:DF 2 "register_operand" "0") 9789 (match_operand:V2DF 3 "nonimmediate_operand" "xm")] 9790 UNSPEC_COPYSIGN))] 9791 "TARGET_SSE2 && TARGET_SSE_MATH" 9792 "#" 9793 "&& reload_completed" 9794 [(const_int 0)] 9795{ 9796 ix86_split_copysign_const (operands); 9797 DONE; 9798}) 9799 9800(define_insn "copysigndf3_var" 9801 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x") 9802 (unspec:DF 9803 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x") 9804 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x") 9805 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0") 9806 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")] 9807 UNSPEC_COPYSIGN)) 9808 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))] 9809 "TARGET_SSE2 && TARGET_SSE_MATH" 9810 "#") 9811 9812(define_split 9813 [(set (match_operand:DF 0 "register_operand" "") 9814 (unspec:DF 9815 [(match_operand:DF 2 "register_operand" "") 9816 (match_operand:DF 3 "register_operand" "") 9817 (match_operand:V2DF 4 "" "") 9818 (match_operand:V2DF 5 "" "")] 9819 UNSPEC_COPYSIGN)) 9820 (clobber (match_scratch:V2DF 1 ""))] 9821 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed" 9822 [(const_int 0)] 9823{ 9824 ix86_split_copysign_var (operands); 9825 DONE; 9826}) 9827 9828(define_expand "negxf2" 9829 [(set (match_operand:XF 0 "nonimmediate_operand" "") 9830 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))] 9831 "TARGET_80387" 9832 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;") 9833 9834(define_expand "absxf2" 9835 [(set (match_operand:XF 0 "nonimmediate_operand" "") 9836 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))] 9837 "TARGET_80387" 9838 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;") 9839 9840(define_insn "*absnegxf2_i387" 9841 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm") 9842 (match_operator:XF 3 "absneg_operator" 9843 [(match_operand:XF 1 "nonimmediate_operand" "0,0")])) 9844 (use (match_operand 2 "" "")) 9845 (clobber (reg:CC FLAGS_REG))] 9846 "TARGET_80387 9847 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)" 9848 "#") 9849 9850;; Splitters for fp abs and neg. 9851 9852(define_split 9853 [(set (match_operand 0 "fp_register_operand" "") 9854 (match_operator 1 "absneg_operator" [(match_dup 0)])) 9855 (use (match_operand 2 "" "")) 9856 (clobber (reg:CC FLAGS_REG))] 9857 "reload_completed" 9858 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))]) 9859 9860(define_split 9861 [(set (match_operand 0 "register_operand" "") 9862 (match_operator 3 "absneg_operator" 9863 [(match_operand 1 "register_operand" "")])) 9864 (use (match_operand 2 "nonimmediate_operand" "")) 9865 (clobber (reg:CC FLAGS_REG))] 9866 "reload_completed && SSE_REG_P (operands[0])" 9867 [(set (match_dup 0) (match_dup 3))] 9868{ 9869 enum machine_mode mode = GET_MODE (operands[0]); 9870 enum machine_mode vmode = GET_MODE (operands[2]); 9871 rtx tmp; 9872 9873 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0); 9874 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0); 9875 if (operands_match_p (operands[0], operands[2])) 9876 { 9877 tmp = operands[1]; 9878 operands[1] = operands[2]; 9879 operands[2] = tmp; 9880 } 9881 if (GET_CODE (operands[3]) == ABS) 9882 tmp = gen_rtx_AND (vmode, operands[1], operands[2]); 9883 else 9884 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]); 9885 operands[3] = tmp; 9886}) 9887 9888(define_split 9889 [(set (match_operand:SF 0 "register_operand" "") 9890 (match_operator:SF 1 "absneg_operator" [(match_dup 0)])) 9891 (use (match_operand:V4SF 2 "" "")) 9892 (clobber (reg:CC FLAGS_REG))] 9893 "reload_completed" 9894 [(parallel [(set (match_dup 0) (match_dup 1)) 9895 (clobber (reg:CC FLAGS_REG))])] 9896{ 9897 rtx tmp; 9898 operands[0] = gen_lowpart (SImode, operands[0]); 9899 if (GET_CODE (operands[1]) == ABS) 9900 { 9901 tmp = gen_int_mode (0x7fffffff, SImode); 9902 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9903 } 9904 else 9905 { 9906 tmp = gen_int_mode (0x80000000, SImode); 9907 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 9908 } 9909 operands[1] = tmp; 9910}) 9911 9912(define_split 9913 [(set (match_operand:DF 0 "register_operand" "") 9914 (match_operator:DF 1 "absneg_operator" [(match_dup 0)])) 9915 (use (match_operand 2 "" "")) 9916 (clobber (reg:CC FLAGS_REG))] 9917 "reload_completed" 9918 [(parallel [(set (match_dup 0) (match_dup 1)) 9919 (clobber (reg:CC FLAGS_REG))])] 9920{ 9921 rtx tmp; 9922 if (TARGET_64BIT) 9923 { 9924 tmp = gen_lowpart (DImode, operands[0]); 9925 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63)); 9926 operands[0] = tmp; 9927 9928 if (GET_CODE (operands[1]) == ABS) 9929 tmp = const0_rtx; 9930 else 9931 tmp = gen_rtx_NOT (DImode, tmp); 9932 } 9933 else 9934 { 9935 operands[0] = gen_highpart (SImode, operands[0]); 9936 if (GET_CODE (operands[1]) == ABS) 9937 { 9938 tmp = gen_int_mode (0x7fffffff, SImode); 9939 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9940 } 9941 else 9942 { 9943 tmp = gen_int_mode (0x80000000, SImode); 9944 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 9945 } 9946 } 9947 operands[1] = tmp; 9948}) 9949 9950(define_split 9951 [(set (match_operand:XF 0 "register_operand" "") 9952 (match_operator:XF 1 "absneg_operator" [(match_dup 0)])) 9953 (use (match_operand 2 "" "")) 9954 (clobber (reg:CC FLAGS_REG))] 9955 "reload_completed" 9956 [(parallel [(set (match_dup 0) (match_dup 1)) 9957 (clobber (reg:CC FLAGS_REG))])] 9958{ 9959 rtx tmp; 9960 operands[0] = gen_rtx_REG (SImode, 9961 true_regnum (operands[0]) 9962 + (TARGET_64BIT ? 1 : 2)); 9963 if (GET_CODE (operands[1]) == ABS) 9964 { 9965 tmp = GEN_INT (0x7fff); 9966 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9967 } 9968 else 9969 { 9970 tmp = GEN_INT (0x8000); 9971 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 9972 } 9973 operands[1] = tmp; 9974}) 9975 9976(define_split 9977 [(set (match_operand 0 "memory_operand" "") 9978 (match_operator 1 "absneg_operator" [(match_dup 0)])) 9979 (use (match_operand 2 "" "")) 9980 (clobber (reg:CC FLAGS_REG))] 9981 "reload_completed" 9982 [(parallel [(set (match_dup 0) (match_dup 1)) 9983 (clobber (reg:CC FLAGS_REG))])] 9984{ 9985 enum machine_mode mode = GET_MODE (operands[0]); 9986 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode); 9987 rtx tmp; 9988 9989 operands[0] = adjust_address (operands[0], QImode, size - 1); 9990 if (GET_CODE (operands[1]) == ABS) 9991 { 9992 tmp = gen_int_mode (0x7f, QImode); 9993 tmp = gen_rtx_AND (QImode, operands[0], tmp); 9994 } 9995 else 9996 { 9997 tmp = gen_int_mode (0x80, QImode); 9998 tmp = gen_rtx_XOR (QImode, operands[0], tmp); 9999 } 10000 operands[1] = tmp; 10001}) 10002 10003;; Conditionalize these after reload. If they match before reload, we 10004;; lose the clobber and ability to use integer instructions. 10005 10006(define_insn "*negsf2_1" 10007 [(set (match_operand:SF 0 "register_operand" "=f") 10008 (neg:SF (match_operand:SF 1 "register_operand" "0")))] 10009 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)" 10010 "fchs" 10011 [(set_attr "type" "fsgn") 10012 (set_attr "mode" "SF")]) 10013 10014(define_insn "*negdf2_1" 10015 [(set (match_operand:DF 0 "register_operand" "=f") 10016 (neg:DF (match_operand:DF 1 "register_operand" "0")))] 10017 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))" 10018 "fchs" 10019 [(set_attr "type" "fsgn") 10020 (set_attr "mode" "DF")]) 10021 10022(define_insn "*negxf2_1" 10023 [(set (match_operand:XF 0 "register_operand" "=f") 10024 (neg:XF (match_operand:XF 1 "register_operand" "0")))] 10025 "TARGET_80387" 10026 "fchs" 10027 [(set_attr "type" "fsgn") 10028 (set_attr "mode" "XF")]) 10029 10030(define_insn "*abssf2_1" 10031 [(set (match_operand:SF 0 "register_operand" "=f") 10032 (abs:SF (match_operand:SF 1 "register_operand" "0")))] 10033 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)" 10034 "fabs" 10035 [(set_attr "type" "fsgn") 10036 (set_attr "mode" "SF")]) 10037 10038(define_insn "*absdf2_1" 10039 [(set (match_operand:DF 0 "register_operand" "=f") 10040 (abs:DF (match_operand:DF 1 "register_operand" "0")))] 10041 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))" 10042 "fabs" 10043 [(set_attr "type" "fsgn") 10044 (set_attr "mode" "DF")]) 10045 10046(define_insn "*absxf2_1" 10047 [(set (match_operand:XF 0 "register_operand" "=f") 10048 (abs:XF (match_operand:XF 1 "register_operand" "0")))] 10049 "TARGET_80387" 10050 "fabs" 10051 [(set_attr "type" "fsgn") 10052 (set_attr "mode" "DF")]) 10053 10054(define_insn "*negextendsfdf2" 10055 [(set (match_operand:DF 0 "register_operand" "=f") 10056 (neg:DF (float_extend:DF 10057 (match_operand:SF 1 "register_operand" "0"))))] 10058 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 10059 "fchs" 10060 [(set_attr "type" "fsgn") 10061 (set_attr "mode" "DF")]) 10062 10063(define_insn "*negextenddfxf2" 10064 [(set (match_operand:XF 0 "register_operand" "=f") 10065 (neg:XF (float_extend:XF 10066 (match_operand:DF 1 "register_operand" "0"))))] 10067 "TARGET_80387" 10068 "fchs" 10069 [(set_attr "type" "fsgn") 10070 (set_attr "mode" "XF")]) 10071 10072(define_insn "*negextendsfxf2" 10073 [(set (match_operand:XF 0 "register_operand" "=f") 10074 (neg:XF (float_extend:XF 10075 (match_operand:SF 1 "register_operand" "0"))))] 10076 "TARGET_80387" 10077 "fchs" 10078 [(set_attr "type" "fsgn") 10079 (set_attr "mode" "XF")]) 10080 10081(define_insn "*absextendsfdf2" 10082 [(set (match_operand:DF 0 "register_operand" "=f") 10083 (abs:DF (float_extend:DF 10084 (match_operand:SF 1 "register_operand" "0"))))] 10085 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 10086 "fabs" 10087 [(set_attr "type" "fsgn") 10088 (set_attr "mode" "DF")]) 10089 10090(define_insn "*absextenddfxf2" 10091 [(set (match_operand:XF 0 "register_operand" "=f") 10092 (abs:XF (float_extend:XF 10093 (match_operand:DF 1 "register_operand" "0"))))] 10094 "TARGET_80387" 10095 "fabs" 10096 [(set_attr "type" "fsgn") 10097 (set_attr "mode" "XF")]) 10098 10099(define_insn "*absextendsfxf2" 10100 [(set (match_operand:XF 0 "register_operand" "=f") 10101 (abs:XF (float_extend:XF 10102 (match_operand:SF 1 "register_operand" "0"))))] 10103 "TARGET_80387" 10104 "fabs" 10105 [(set_attr "type" "fsgn") 10106 (set_attr "mode" "XF")]) 10107 10108;; One complement instructions 10109 10110(define_expand "one_cmpldi2" 10111 [(set (match_operand:DI 0 "nonimmediate_operand" "") 10112 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))] 10113 "TARGET_64BIT" 10114 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;") 10115 10116(define_insn "*one_cmpldi2_1_rex64" 10117 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 10118 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))] 10119 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)" 10120 "not{q}\t%0" 10121 [(set_attr "type" "negnot") 10122 (set_attr "mode" "DI")]) 10123 10124(define_insn "*one_cmpldi2_2_rex64" 10125 [(set (reg FLAGS_REG) 10126 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")) 10127 (const_int 0))) 10128 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 10129 (not:DI (match_dup 1)))] 10130 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 10131 && ix86_unary_operator_ok (NOT, DImode, operands)" 10132 "#" 10133 [(set_attr "type" "alu1") 10134 (set_attr "mode" "DI")]) 10135 10136(define_split 10137 [(set (match_operand 0 "flags_reg_operand" "") 10138 (match_operator 2 "compare_operator" 10139 [(not:DI (match_operand:DI 3 "nonimmediate_operand" "")) 10140 (const_int 0)])) 10141 (set (match_operand:DI 1 "nonimmediate_operand" "") 10142 (not:DI (match_dup 3)))] 10143 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 10144 [(parallel [(set (match_dup 0) 10145 (match_op_dup 2 10146 [(xor:DI (match_dup 3) (const_int -1)) 10147 (const_int 0)])) 10148 (set (match_dup 1) 10149 (xor:DI (match_dup 3) (const_int -1)))])] 10150 "") 10151 10152(define_expand "one_cmplsi2" 10153 [(set (match_operand:SI 0 "nonimmediate_operand" "") 10154 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))] 10155 "" 10156 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;") 10157 10158(define_insn "*one_cmplsi2_1" 10159 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 10160 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))] 10161 "ix86_unary_operator_ok (NOT, SImode, operands)" 10162 "not{l}\t%0" 10163 [(set_attr "type" "negnot") 10164 (set_attr "mode" "SI")]) 10165 10166;; ??? Currently never generated - xor is used instead. 10167(define_insn "*one_cmplsi2_1_zext" 10168 [(set (match_operand:DI 0 "register_operand" "=r") 10169 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))] 10170 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)" 10171 "not{l}\t%k0" 10172 [(set_attr "type" "negnot") 10173 (set_attr "mode" "SI")]) 10174 10175(define_insn "*one_cmplsi2_2" 10176 [(set (reg FLAGS_REG) 10177 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")) 10178 (const_int 0))) 10179 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 10180 (not:SI (match_dup 1)))] 10181 "ix86_match_ccmode (insn, CCNOmode) 10182 && ix86_unary_operator_ok (NOT, SImode, operands)" 10183 "#" 10184 [(set_attr "type" "alu1") 10185 (set_attr "mode" "SI")]) 10186 10187(define_split 10188 [(set (match_operand 0 "flags_reg_operand" "") 10189 (match_operator 2 "compare_operator" 10190 [(not:SI (match_operand:SI 3 "nonimmediate_operand" "")) 10191 (const_int 0)])) 10192 (set (match_operand:SI 1 "nonimmediate_operand" "") 10193 (not:SI (match_dup 3)))] 10194 "ix86_match_ccmode (insn, CCNOmode)" 10195 [(parallel [(set (match_dup 0) 10196 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 10197 (const_int 0)])) 10198 (set (match_dup 1) 10199 (xor:SI (match_dup 3) (const_int -1)))])] 10200 "") 10201 10202;; ??? Currently never generated - xor is used instead. 10203(define_insn "*one_cmplsi2_2_zext" 10204 [(set (reg FLAGS_REG) 10205 (compare (not:SI (match_operand:SI 1 "register_operand" "0")) 10206 (const_int 0))) 10207 (set (match_operand:DI 0 "register_operand" "=r") 10208 (zero_extend:DI (not:SI (match_dup 1))))] 10209 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 10210 && ix86_unary_operator_ok (NOT, SImode, operands)" 10211 "#" 10212 [(set_attr "type" "alu1") 10213 (set_attr "mode" "SI")]) 10214 10215(define_split 10216 [(set (match_operand 0 "flags_reg_operand" "") 10217 (match_operator 2 "compare_operator" 10218 [(not:SI (match_operand:SI 3 "register_operand" "")) 10219 (const_int 0)])) 10220 (set (match_operand:DI 1 "register_operand" "") 10221 (zero_extend:DI (not:SI (match_dup 3))))] 10222 "ix86_match_ccmode (insn, CCNOmode)" 10223 [(parallel [(set (match_dup 0) 10224 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 10225 (const_int 0)])) 10226 (set (match_dup 1) 10227 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])] 10228 "") 10229 10230(define_expand "one_cmplhi2" 10231 [(set (match_operand:HI 0 "nonimmediate_operand" "") 10232 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))] 10233 "TARGET_HIMODE_MATH" 10234 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;") 10235 10236(define_insn "*one_cmplhi2_1" 10237 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10238 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] 10239 "ix86_unary_operator_ok (NOT, HImode, operands)" 10240 "not{w}\t%0" 10241 [(set_attr "type" "negnot") 10242 (set_attr "mode" "HI")]) 10243 10244(define_insn "*one_cmplhi2_2" 10245 [(set (reg FLAGS_REG) 10246 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")) 10247 (const_int 0))) 10248 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10249 (not:HI (match_dup 1)))] 10250 "ix86_match_ccmode (insn, CCNOmode) 10251 && ix86_unary_operator_ok (NEG, HImode, operands)" 10252 "#" 10253 [(set_attr "type" "alu1") 10254 (set_attr "mode" "HI")]) 10255 10256(define_split 10257 [(set (match_operand 0 "flags_reg_operand" "") 10258 (match_operator 2 "compare_operator" 10259 [(not:HI (match_operand:HI 3 "nonimmediate_operand" "")) 10260 (const_int 0)])) 10261 (set (match_operand:HI 1 "nonimmediate_operand" "") 10262 (not:HI (match_dup 3)))] 10263 "ix86_match_ccmode (insn, CCNOmode)" 10264 [(parallel [(set (match_dup 0) 10265 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1)) 10266 (const_int 0)])) 10267 (set (match_dup 1) 10268 (xor:HI (match_dup 3) (const_int -1)))])] 10269 "") 10270 10271;; %%% Potential partial reg stall on alternative 1. What to do? 10272(define_expand "one_cmplqi2" 10273 [(set (match_operand:QI 0 "nonimmediate_operand" "") 10274 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))] 10275 "TARGET_QIMODE_MATH" 10276 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;") 10277 10278(define_insn "*one_cmplqi2_1" 10279 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") 10280 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] 10281 "ix86_unary_operator_ok (NOT, QImode, operands)" 10282 "@ 10283 not{b}\t%0 10284 not{l}\t%k0" 10285 [(set_attr "type" "negnot") 10286 (set_attr "mode" "QI,SI")]) 10287 10288(define_insn "*one_cmplqi2_2" 10289 [(set (reg FLAGS_REG) 10290 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")) 10291 (const_int 0))) 10292 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 10293 (not:QI (match_dup 1)))] 10294 "ix86_match_ccmode (insn, CCNOmode) 10295 && ix86_unary_operator_ok (NOT, QImode, operands)" 10296 "#" 10297 [(set_attr "type" "alu1") 10298 (set_attr "mode" "QI")]) 10299 10300(define_split 10301 [(set (match_operand 0 "flags_reg_operand" "") 10302 (match_operator 2 "compare_operator" 10303 [(not:QI (match_operand:QI 3 "nonimmediate_operand" "")) 10304 (const_int 0)])) 10305 (set (match_operand:QI 1 "nonimmediate_operand" "") 10306 (not:QI (match_dup 3)))] 10307 "ix86_match_ccmode (insn, CCNOmode)" 10308 [(parallel [(set (match_dup 0) 10309 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1)) 10310 (const_int 0)])) 10311 (set (match_dup 1) 10312 (xor:QI (match_dup 3) (const_int -1)))])] 10313 "") 10314 10315;; Arithmetic shift instructions 10316 10317;; DImode shifts are implemented using the i386 "shift double" opcode, 10318;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count 10319;; is variable, then the count is in %cl and the "imm" operand is dropped 10320;; from the assembler input. 10321;; 10322;; This instruction shifts the target reg/mem as usual, but instead of 10323;; shifting in zeros, bits are shifted in from reg operand. If the insn 10324;; is a left shift double, bits are taken from the high order bits of 10325;; reg, else if the insn is a shift right double, bits are taken from the 10326;; low order bits of reg. So if %eax is "1234" and %edx is "5678", 10327;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". 10328;; 10329;; Since sh[lr]d does not change the `reg' operand, that is done 10330;; separately, making all shifts emit pairs of shift double and normal 10331;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to 10332;; support a 63 bit shift, each shift where the count is in a reg expands 10333;; to a pair of shifts, a branch, a shift by 32 and a label. 10334;; 10335;; If the shift count is a constant, we need never emit more than one 10336;; shift pair, instead using moves and sign extension for counts greater 10337;; than 31. 10338 10339(define_expand "ashlti3" 10340 [(parallel [(set (match_operand:TI 0 "register_operand" "") 10341 (ashift:TI (match_operand:TI 1 "register_operand" "") 10342 (match_operand:QI 2 "nonmemory_operand" ""))) 10343 (clobber (reg:CC FLAGS_REG))])] 10344 "TARGET_64BIT" 10345{ 10346 if (! immediate_operand (operands[2], QImode)) 10347 { 10348 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2])); 10349 DONE; 10350 } 10351 ix86_expand_binary_operator (ASHIFT, TImode, operands); 10352 DONE; 10353}) 10354 10355(define_insn "ashlti3_1" 10356 [(set (match_operand:TI 0 "register_operand" "=r") 10357 (ashift:TI (match_operand:TI 1 "register_operand" "0") 10358 (match_operand:QI 2 "register_operand" "c"))) 10359 (clobber (match_scratch:DI 3 "=&r")) 10360 (clobber (reg:CC FLAGS_REG))] 10361 "TARGET_64BIT" 10362 "#" 10363 [(set_attr "type" "multi")]) 10364 10365(define_insn "*ashlti3_2" 10366 [(set (match_operand:TI 0 "register_operand" "=r") 10367 (ashift:TI (match_operand:TI 1 "register_operand" "0") 10368 (match_operand:QI 2 "immediate_operand" "O"))) 10369 (clobber (reg:CC FLAGS_REG))] 10370 "TARGET_64BIT" 10371 "#" 10372 [(set_attr "type" "multi")]) 10373 10374(define_split 10375 [(set (match_operand:TI 0 "register_operand" "") 10376 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "") 10377 (match_operand:QI 2 "register_operand" ""))) 10378 (clobber (match_scratch:DI 3 "")) 10379 (clobber (reg:CC FLAGS_REG))] 10380 "TARGET_64BIT && reload_completed" 10381 [(const_int 0)] 10382 "ix86_split_ashl (operands, operands[3], TImode); DONE;") 10383 10384(define_split 10385 [(set (match_operand:TI 0 "register_operand" "") 10386 (ashift:TI (match_operand:TI 1 "register_operand" "") 10387 (match_operand:QI 2 "immediate_operand" ""))) 10388 (clobber (reg:CC FLAGS_REG))] 10389 "TARGET_64BIT && reload_completed" 10390 [(const_int 0)] 10391 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;") 10392 10393(define_insn "x86_64_shld" 10394 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m") 10395 (ior:DI (ashift:DI (match_dup 0) 10396 (match_operand:QI 2 "nonmemory_operand" "J,c")) 10397 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r") 10398 (minus:QI (const_int 64) (match_dup 2))))) 10399 (clobber (reg:CC FLAGS_REG))] 10400 "TARGET_64BIT" 10401 "@ 10402 shld{q}\t{%2, %1, %0|%0, %1, %2} 10403 shld{q}\t{%s2%1, %0|%0, %1, %2}" 10404 [(set_attr "type" "ishift") 10405 (set_attr "prefix_0f" "1") 10406 (set_attr "mode" "DI") 10407 (set_attr "athlon_decode" "vector") 10408 (set_attr "amdfam10_decode" "vector")]) 10409 10410(define_expand "x86_64_shift_adj" 10411 [(set (reg:CCZ FLAGS_REG) 10412 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "") 10413 (const_int 64)) 10414 (const_int 0))) 10415 (set (match_operand:DI 0 "register_operand" "") 10416 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10417 (match_operand:DI 1 "register_operand" "") 10418 (match_dup 0))) 10419 (set (match_dup 1) 10420 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10421 (match_operand:DI 3 "register_operand" "r") 10422 (match_dup 1)))] 10423 "TARGET_64BIT" 10424 "") 10425 10426(define_expand "ashldi3" 10427 [(set (match_operand:DI 0 "shiftdi_operand" "") 10428 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "") 10429 (match_operand:QI 2 "nonmemory_operand" "")))] 10430 "" 10431 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;") 10432 10433(define_insn "*ashldi3_1_rex64" 10434 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 10435 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l") 10436 (match_operand:QI 2 "nonmemory_operand" "cJ,M"))) 10437 (clobber (reg:CC FLAGS_REG))] 10438 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)" 10439{ 10440 switch (get_attr_type (insn)) 10441 { 10442 case TYPE_ALU: 10443 gcc_assert (operands[2] == const1_rtx); 10444 gcc_assert (rtx_equal_p (operands[0], operands[1])); 10445 return "add{q}\t{%0, %0|%0, %0}"; 10446 10447 case TYPE_LEA: 10448 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 10449 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3); 10450 operands[1] = gen_rtx_MULT (DImode, operands[1], 10451 GEN_INT (1 << INTVAL (operands[2]))); 10452 return "lea{q}\t{%a1, %0|%0, %a1}"; 10453 10454 default: 10455 if (REG_P (operands[2])) 10456 return "sal{q}\t{%b2, %0|%0, %b2}"; 10457 else if (operands[2] == const1_rtx 10458 && (TARGET_SHIFT1 || optimize_size)) 10459 return "sal{q}\t%0"; 10460 else 10461 return "sal{q}\t{%2, %0|%0, %2}"; 10462 } 10463} 10464 [(set (attr "type") 10465 (cond [(eq_attr "alternative" "1") 10466 (const_string "lea") 10467 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10468 (const_int 0)) 10469 (match_operand 0 "register_operand" "")) 10470 (match_operand 2 "const1_operand" "")) 10471 (const_string "alu") 10472 ] 10473 (const_string "ishift"))) 10474 (set_attr "mode" "DI")]) 10475 10476;; Convert lea to the lea pattern to avoid flags dependency. 10477(define_split 10478 [(set (match_operand:DI 0 "register_operand" "") 10479 (ashift:DI (match_operand:DI 1 "index_register_operand" "") 10480 (match_operand:QI 2 "immediate_operand" ""))) 10481 (clobber (reg:CC FLAGS_REG))] 10482 "TARGET_64BIT && reload_completed 10483 && true_regnum (operands[0]) != true_regnum (operands[1])" 10484 [(set (match_dup 0) 10485 (mult:DI (match_dup 1) 10486 (match_dup 2)))] 10487 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);") 10488 10489;; This pattern can't accept a variable shift count, since shifts by 10490;; zero don't affect the flags. We assume that shifts by constant 10491;; zero are optimized away. 10492(define_insn "*ashldi3_cmp_rex64" 10493 [(set (reg FLAGS_REG) 10494 (compare 10495 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0") 10496 (match_operand:QI 2 "immediate_operand" "e")) 10497 (const_int 0))) 10498 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 10499 (ashift:DI (match_dup 1) (match_dup 2)))] 10500 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 10501 && ix86_binary_operator_ok (ASHIFT, DImode, operands) 10502 && (optimize_size 10503 || !TARGET_PARTIAL_FLAG_REG_STALL 10504 || (operands[2] == const1_rtx 10505 && (TARGET_SHIFT1 10506 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 10507{ 10508 switch (get_attr_type (insn)) 10509 { 10510 case TYPE_ALU: 10511 gcc_assert (operands[2] == const1_rtx); 10512 return "add{q}\t{%0, %0|%0, %0}"; 10513 10514 default: 10515 if (REG_P (operands[2])) 10516 return "sal{q}\t{%b2, %0|%0, %b2}"; 10517 else if (operands[2] == const1_rtx 10518 && (TARGET_SHIFT1 || optimize_size)) 10519 return "sal{q}\t%0"; 10520 else 10521 return "sal{q}\t{%2, %0|%0, %2}"; 10522 } 10523} 10524 [(set (attr "type") 10525 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10526 (const_int 0)) 10527 (match_operand 0 "register_operand" "")) 10528 (match_operand 2 "const1_operand" "")) 10529 (const_string "alu") 10530 ] 10531 (const_string "ishift"))) 10532 (set_attr "mode" "DI")]) 10533 10534(define_insn "*ashldi3_cconly_rex64" 10535 [(set (reg FLAGS_REG) 10536 (compare 10537 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0") 10538 (match_operand:QI 2 "immediate_operand" "e")) 10539 (const_int 0))) 10540 (clobber (match_scratch:DI 0 "=r"))] 10541 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 10542 && ix86_binary_operator_ok (ASHIFT, DImode, operands) 10543 && (optimize_size 10544 || !TARGET_PARTIAL_FLAG_REG_STALL 10545 || (operands[2] == const1_rtx 10546 && (TARGET_SHIFT1 10547 || TARGET_DOUBLE_WITH_ADD)))" 10548{ 10549 switch (get_attr_type (insn)) 10550 { 10551 case TYPE_ALU: 10552 gcc_assert (operands[2] == const1_rtx); 10553 return "add{q}\t{%0, %0|%0, %0}"; 10554 10555 default: 10556 if (REG_P (operands[2])) 10557 return "sal{q}\t{%b2, %0|%0, %b2}"; 10558 else if (operands[2] == const1_rtx 10559 && (TARGET_SHIFT1 || optimize_size)) 10560 return "sal{q}\t%0"; 10561 else 10562 return "sal{q}\t{%2, %0|%0, %2}"; 10563 } 10564} 10565 [(set (attr "type") 10566 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10567 (const_int 0)) 10568 (match_operand 0 "register_operand" "")) 10569 (match_operand 2 "const1_operand" "")) 10570 (const_string "alu") 10571 ] 10572 (const_string "ishift"))) 10573 (set_attr "mode" "DI")]) 10574 10575(define_insn "*ashldi3_1" 10576 [(set (match_operand:DI 0 "register_operand" "=&r,r") 10577 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0") 10578 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc"))) 10579 (clobber (reg:CC FLAGS_REG))] 10580 "!TARGET_64BIT" 10581 "#" 10582 [(set_attr "type" "multi")]) 10583 10584;; By default we don't ask for a scratch register, because when DImode 10585;; values are manipulated, registers are already at a premium. But if 10586;; we have one handy, we won't turn it away. 10587(define_peephole2 10588 [(match_scratch:SI 3 "r") 10589 (parallel [(set (match_operand:DI 0 "register_operand" "") 10590 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "") 10591 (match_operand:QI 2 "nonmemory_operand" ""))) 10592 (clobber (reg:CC FLAGS_REG))]) 10593 (match_dup 3)] 10594 "!TARGET_64BIT && TARGET_CMOVE" 10595 [(const_int 0)] 10596 "ix86_split_ashl (operands, operands[3], DImode); DONE;") 10597 10598(define_split 10599 [(set (match_operand:DI 0 "register_operand" "") 10600 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "") 10601 (match_operand:QI 2 "nonmemory_operand" ""))) 10602 (clobber (reg:CC FLAGS_REG))] 10603 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) 10604 ? flow2_completed : reload_completed)" 10605 [(const_int 0)] 10606 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;") 10607 10608(define_insn "x86_shld_1" 10609 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m") 10610 (ior:SI (ashift:SI (match_dup 0) 10611 (match_operand:QI 2 "nonmemory_operand" "I,c")) 10612 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") 10613 (minus:QI (const_int 32) (match_dup 2))))) 10614 (clobber (reg:CC FLAGS_REG))] 10615 "" 10616 "@ 10617 shld{l}\t{%2, %1, %0|%0, %1, %2} 10618 shld{l}\t{%s2%1, %0|%0, %1, %2}" 10619 [(set_attr "type" "ishift") 10620 (set_attr "prefix_0f" "1") 10621 (set_attr "mode" "SI") 10622 (set_attr "pent_pair" "np") 10623 (set_attr "athlon_decode" "vector") 10624 (set_attr "amdfam10_decode" "vector")]) 10625 10626(define_expand "x86_shift_adj_1" 10627 [(set (reg:CCZ FLAGS_REG) 10628 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "") 10629 (const_int 32)) 10630 (const_int 0))) 10631 (set (match_operand:SI 0 "register_operand" "") 10632 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10633 (match_operand:SI 1 "register_operand" "") 10634 (match_dup 0))) 10635 (set (match_dup 1) 10636 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10637 (match_operand:SI 3 "register_operand" "r") 10638 (match_dup 1)))] 10639 "TARGET_CMOVE" 10640 "") 10641 10642(define_expand "x86_shift_adj_2" 10643 [(use (match_operand:SI 0 "register_operand" "")) 10644 (use (match_operand:SI 1 "register_operand" "")) 10645 (use (match_operand:QI 2 "register_operand" ""))] 10646 "" 10647{ 10648 rtx label = gen_label_rtx (); 10649 rtx tmp; 10650 10651 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32))); 10652 10653 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 10654 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 10655 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 10656 gen_rtx_LABEL_REF (VOIDmode, label), 10657 pc_rtx); 10658 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 10659 JUMP_LABEL (tmp) = label; 10660 10661 emit_move_insn (operands[0], operands[1]); 10662 ix86_expand_clear (operands[1]); 10663 10664 emit_label (label); 10665 LABEL_NUSES (label) = 1; 10666 10667 DONE; 10668}) 10669 10670(define_expand "ashlsi3" 10671 [(set (match_operand:SI 0 "nonimmediate_operand" "") 10672 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "") 10673 (match_operand:QI 2 "nonmemory_operand" ""))) 10674 (clobber (reg:CC FLAGS_REG))] 10675 "" 10676 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;") 10677 10678(define_insn "*ashlsi3_1" 10679 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 10680 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l") 10681 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 10682 (clobber (reg:CC FLAGS_REG))] 10683 "ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10684{ 10685 switch (get_attr_type (insn)) 10686 { 10687 case TYPE_ALU: 10688 gcc_assert (operands[2] == const1_rtx); 10689 gcc_assert (rtx_equal_p (operands[0], operands[1])); 10690 return "add{l}\t{%0, %0|%0, %0}"; 10691 10692 case TYPE_LEA: 10693 return "#"; 10694 10695 default: 10696 if (REG_P (operands[2])) 10697 return "sal{l}\t{%b2, %0|%0, %b2}"; 10698 else if (operands[2] == const1_rtx 10699 && (TARGET_SHIFT1 || optimize_size)) 10700 return "sal{l}\t%0"; 10701 else 10702 return "sal{l}\t{%2, %0|%0, %2}"; 10703 } 10704} 10705 [(set (attr "type") 10706 (cond [(eq_attr "alternative" "1") 10707 (const_string "lea") 10708 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10709 (const_int 0)) 10710 (match_operand 0 "register_operand" "")) 10711 (match_operand 2 "const1_operand" "")) 10712 (const_string "alu") 10713 ] 10714 (const_string "ishift"))) 10715 (set_attr "mode" "SI")]) 10716 10717;; Convert lea to the lea pattern to avoid flags dependency. 10718(define_split 10719 [(set (match_operand 0 "register_operand" "") 10720 (ashift (match_operand 1 "index_register_operand" "") 10721 (match_operand:QI 2 "const_int_operand" ""))) 10722 (clobber (reg:CC FLAGS_REG))] 10723 "reload_completed 10724 && true_regnum (operands[0]) != true_regnum (operands[1]) 10725 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4" 10726 [(const_int 0)] 10727{ 10728 rtx pat; 10729 enum machine_mode mode = GET_MODE (operands[0]); 10730 10731 if (GET_MODE_SIZE (mode) < 4) 10732 operands[0] = gen_lowpart (SImode, operands[0]); 10733 if (mode != Pmode) 10734 operands[1] = gen_lowpart (Pmode, operands[1]); 10735 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode); 10736 10737 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]); 10738 if (Pmode != SImode) 10739 pat = gen_rtx_SUBREG (SImode, pat, 0); 10740 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 10741 DONE; 10742}) 10743 10744;; Rare case of shifting RSP is handled by generating move and shift 10745(define_split 10746 [(set (match_operand 0 "register_operand" "") 10747 (ashift (match_operand 1 "register_operand" "") 10748 (match_operand:QI 2 "const_int_operand" ""))) 10749 (clobber (reg:CC FLAGS_REG))] 10750 "reload_completed 10751 && true_regnum (operands[0]) != true_regnum (operands[1])" 10752 [(const_int 0)] 10753{ 10754 rtx pat, clob; 10755 emit_move_insn (operands[0], operands[1]); 10756 pat = gen_rtx_SET (VOIDmode, operands[0], 10757 gen_rtx_ASHIFT (GET_MODE (operands[0]), 10758 operands[0], operands[2])); 10759 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); 10760 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob))); 10761 DONE; 10762}) 10763 10764(define_insn "*ashlsi3_1_zext" 10765 [(set (match_operand:DI 0 "register_operand" "=r,r") 10766 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l") 10767 (match_operand:QI 2 "nonmemory_operand" "cI,M")))) 10768 (clobber (reg:CC FLAGS_REG))] 10769 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10770{ 10771 switch (get_attr_type (insn)) 10772 { 10773 case TYPE_ALU: 10774 gcc_assert (operands[2] == const1_rtx); 10775 return "add{l}\t{%k0, %k0|%k0, %k0}"; 10776 10777 case TYPE_LEA: 10778 return "#"; 10779 10780 default: 10781 if (REG_P (operands[2])) 10782 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 10783 else if (operands[2] == const1_rtx 10784 && (TARGET_SHIFT1 || optimize_size)) 10785 return "sal{l}\t%k0"; 10786 else 10787 return "sal{l}\t{%2, %k0|%k0, %2}"; 10788 } 10789} 10790 [(set (attr "type") 10791 (cond [(eq_attr "alternative" "1") 10792 (const_string "lea") 10793 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10794 (const_int 0)) 10795 (match_operand 2 "const1_operand" "")) 10796 (const_string "alu") 10797 ] 10798 (const_string "ishift"))) 10799 (set_attr "mode" "SI")]) 10800 10801;; Convert lea to the lea pattern to avoid flags dependency. 10802(define_split 10803 [(set (match_operand:DI 0 "register_operand" "") 10804 (zero_extend:DI (ashift (match_operand 1 "register_operand" "") 10805 (match_operand:QI 2 "const_int_operand" "")))) 10806 (clobber (reg:CC FLAGS_REG))] 10807 "TARGET_64BIT && reload_completed 10808 && true_regnum (operands[0]) != true_regnum (operands[1])" 10809 [(set (match_dup 0) (zero_extend:DI 10810 (subreg:SI (mult:SI (match_dup 1) 10811 (match_dup 2)) 0)))] 10812{ 10813 operands[1] = gen_lowpart (Pmode, operands[1]); 10814 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode); 10815}) 10816 10817;; This pattern can't accept a variable shift count, since shifts by 10818;; zero don't affect the flags. We assume that shifts by constant 10819;; zero are optimized away. 10820(define_insn "*ashlsi3_cmp" 10821 [(set (reg FLAGS_REG) 10822 (compare 10823 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0") 10824 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10825 (const_int 0))) 10826 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 10827 (ashift:SI (match_dup 1) (match_dup 2)))] 10828 "ix86_match_ccmode (insn, CCGOCmode) 10829 && ix86_binary_operator_ok (ASHIFT, SImode, operands) 10830 && (optimize_size 10831 || !TARGET_PARTIAL_FLAG_REG_STALL 10832 || (operands[2] == const1_rtx 10833 && (TARGET_SHIFT1 10834 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 10835{ 10836 switch (get_attr_type (insn)) 10837 { 10838 case TYPE_ALU: 10839 gcc_assert (operands[2] == const1_rtx); 10840 return "add{l}\t{%0, %0|%0, %0}"; 10841 10842 default: 10843 if (REG_P (operands[2])) 10844 return "sal{l}\t{%b2, %0|%0, %b2}"; 10845 else if (operands[2] == const1_rtx 10846 && (TARGET_SHIFT1 || optimize_size)) 10847 return "sal{l}\t%0"; 10848 else 10849 return "sal{l}\t{%2, %0|%0, %2}"; 10850 } 10851} 10852 [(set (attr "type") 10853 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10854 (const_int 0)) 10855 (match_operand 0 "register_operand" "")) 10856 (match_operand 2 "const1_operand" "")) 10857 (const_string "alu") 10858 ] 10859 (const_string "ishift"))) 10860 (set_attr "mode" "SI")]) 10861 10862(define_insn "*ashlsi3_cconly" 10863 [(set (reg FLAGS_REG) 10864 (compare 10865 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0") 10866 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10867 (const_int 0))) 10868 (clobber (match_scratch:SI 0 "=r"))] 10869 "ix86_match_ccmode (insn, CCGOCmode) 10870 && ix86_binary_operator_ok (ASHIFT, SImode, operands) 10871 && (optimize_size 10872 || !TARGET_PARTIAL_FLAG_REG_STALL 10873 || (operands[2] == const1_rtx 10874 && (TARGET_SHIFT1 10875 || TARGET_DOUBLE_WITH_ADD)))" 10876{ 10877 switch (get_attr_type (insn)) 10878 { 10879 case TYPE_ALU: 10880 gcc_assert (operands[2] == const1_rtx); 10881 return "add{l}\t{%0, %0|%0, %0}"; 10882 10883 default: 10884 if (REG_P (operands[2])) 10885 return "sal{l}\t{%b2, %0|%0, %b2}"; 10886 else if (operands[2] == const1_rtx 10887 && (TARGET_SHIFT1 || optimize_size)) 10888 return "sal{l}\t%0"; 10889 else 10890 return "sal{l}\t{%2, %0|%0, %2}"; 10891 } 10892} 10893 [(set (attr "type") 10894 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10895 (const_int 0)) 10896 (match_operand 0 "register_operand" "")) 10897 (match_operand 2 "const1_operand" "")) 10898 (const_string "alu") 10899 ] 10900 (const_string "ishift"))) 10901 (set_attr "mode" "SI")]) 10902 10903(define_insn "*ashlsi3_cmp_zext" 10904 [(set (reg FLAGS_REG) 10905 (compare 10906 (ashift:SI (match_operand:SI 1 "register_operand" "0") 10907 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10908 (const_int 0))) 10909 (set (match_operand:DI 0 "register_operand" "=r") 10910 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 10911 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 10912 && ix86_binary_operator_ok (ASHIFT, SImode, operands) 10913 && (optimize_size 10914 || !TARGET_PARTIAL_FLAG_REG_STALL 10915 || (operands[2] == const1_rtx 10916 && (TARGET_SHIFT1 10917 || TARGET_DOUBLE_WITH_ADD)))" 10918{ 10919 switch (get_attr_type (insn)) 10920 { 10921 case TYPE_ALU: 10922 gcc_assert (operands[2] == const1_rtx); 10923 return "add{l}\t{%k0, %k0|%k0, %k0}"; 10924 10925 default: 10926 if (REG_P (operands[2])) 10927 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 10928 else if (operands[2] == const1_rtx 10929 && (TARGET_SHIFT1 || optimize_size)) 10930 return "sal{l}\t%k0"; 10931 else 10932 return "sal{l}\t{%2, %k0|%k0, %2}"; 10933 } 10934} 10935 [(set (attr "type") 10936 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10937 (const_int 0)) 10938 (match_operand 2 "const1_operand" "")) 10939 (const_string "alu") 10940 ] 10941 (const_string "ishift"))) 10942 (set_attr "mode" "SI")]) 10943 10944(define_expand "ashlhi3" 10945 [(set (match_operand:HI 0 "nonimmediate_operand" "") 10946 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "") 10947 (match_operand:QI 2 "nonmemory_operand" ""))) 10948 (clobber (reg:CC FLAGS_REG))] 10949 "TARGET_HIMODE_MATH" 10950 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;") 10951 10952(define_insn "*ashlhi3_1_lea" 10953 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 10954 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l") 10955 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 10956 (clobber (reg:CC FLAGS_REG))] 10957 "!TARGET_PARTIAL_REG_STALL 10958 && ix86_binary_operator_ok (ASHIFT, HImode, operands)" 10959{ 10960 switch (get_attr_type (insn)) 10961 { 10962 case TYPE_LEA: 10963 return "#"; 10964 case TYPE_ALU: 10965 gcc_assert (operands[2] == const1_rtx); 10966 return "add{w}\t{%0, %0|%0, %0}"; 10967 10968 default: 10969 if (REG_P (operands[2])) 10970 return "sal{w}\t{%b2, %0|%0, %b2}"; 10971 else if (operands[2] == const1_rtx 10972 && (TARGET_SHIFT1 || optimize_size)) 10973 return "sal{w}\t%0"; 10974 else 10975 return "sal{w}\t{%2, %0|%0, %2}"; 10976 } 10977} 10978 [(set (attr "type") 10979 (cond [(eq_attr "alternative" "1") 10980 (const_string "lea") 10981 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10982 (const_int 0)) 10983 (match_operand 0 "register_operand" "")) 10984 (match_operand 2 "const1_operand" "")) 10985 (const_string "alu") 10986 ] 10987 (const_string "ishift"))) 10988 (set_attr "mode" "HI,SI")]) 10989 10990(define_insn "*ashlhi3_1" 10991 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10992 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") 10993 (match_operand:QI 2 "nonmemory_operand" "cI"))) 10994 (clobber (reg:CC FLAGS_REG))] 10995 "TARGET_PARTIAL_REG_STALL 10996 && ix86_binary_operator_ok (ASHIFT, HImode, operands)" 10997{ 10998 switch (get_attr_type (insn)) 10999 { 11000 case TYPE_ALU: 11001 gcc_assert (operands[2] == const1_rtx); 11002 return "add{w}\t{%0, %0|%0, %0}"; 11003 11004 default: 11005 if (REG_P (operands[2])) 11006 return "sal{w}\t{%b2, %0|%0, %b2}"; 11007 else if (operands[2] == const1_rtx 11008 && (TARGET_SHIFT1 || optimize_size)) 11009 return "sal{w}\t%0"; 11010 else 11011 return "sal{w}\t{%2, %0|%0, %2}"; 11012 } 11013} 11014 [(set (attr "type") 11015 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11016 (const_int 0)) 11017 (match_operand 0 "register_operand" "")) 11018 (match_operand 2 "const1_operand" "")) 11019 (const_string "alu") 11020 ] 11021 (const_string "ishift"))) 11022 (set_attr "mode" "HI")]) 11023 11024;; This pattern can't accept a variable shift count, since shifts by 11025;; zero don't affect the flags. We assume that shifts by constant 11026;; zero are optimized away. 11027(define_insn "*ashlhi3_cmp" 11028 [(set (reg FLAGS_REG) 11029 (compare 11030 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11031 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11032 (const_int 0))) 11033 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 11034 (ashift:HI (match_dup 1) (match_dup 2)))] 11035 "ix86_match_ccmode (insn, CCGOCmode) 11036 && ix86_binary_operator_ok (ASHIFT, HImode, operands) 11037 && (optimize_size 11038 || !TARGET_PARTIAL_FLAG_REG_STALL 11039 || (operands[2] == const1_rtx 11040 && (TARGET_SHIFT1 11041 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 11042{ 11043 switch (get_attr_type (insn)) 11044 { 11045 case TYPE_ALU: 11046 gcc_assert (operands[2] == const1_rtx); 11047 return "add{w}\t{%0, %0|%0, %0}"; 11048 11049 default: 11050 if (REG_P (operands[2])) 11051 return "sal{w}\t{%b2, %0|%0, %b2}"; 11052 else if (operands[2] == const1_rtx 11053 && (TARGET_SHIFT1 || optimize_size)) 11054 return "sal{w}\t%0"; 11055 else 11056 return "sal{w}\t{%2, %0|%0, %2}"; 11057 } 11058} 11059 [(set (attr "type") 11060 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11061 (const_int 0)) 11062 (match_operand 0 "register_operand" "")) 11063 (match_operand 2 "const1_operand" "")) 11064 (const_string "alu") 11065 ] 11066 (const_string "ishift"))) 11067 (set_attr "mode" "HI")]) 11068 11069(define_insn "*ashlhi3_cconly" 11070 [(set (reg FLAGS_REG) 11071 (compare 11072 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11073 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11074 (const_int 0))) 11075 (clobber (match_scratch:HI 0 "=r"))] 11076 "ix86_match_ccmode (insn, CCGOCmode) 11077 && ix86_binary_operator_ok (ASHIFT, HImode, operands) 11078 && (optimize_size 11079 || !TARGET_PARTIAL_FLAG_REG_STALL 11080 || (operands[2] == const1_rtx 11081 && (TARGET_SHIFT1 11082 || TARGET_DOUBLE_WITH_ADD)))" 11083{ 11084 switch (get_attr_type (insn)) 11085 { 11086 case TYPE_ALU: 11087 gcc_assert (operands[2] == const1_rtx); 11088 return "add{w}\t{%0, %0|%0, %0}"; 11089 11090 default: 11091 if (REG_P (operands[2])) 11092 return "sal{w}\t{%b2, %0|%0, %b2}"; 11093 else if (operands[2] == const1_rtx 11094 && (TARGET_SHIFT1 || optimize_size)) 11095 return "sal{w}\t%0"; 11096 else 11097 return "sal{w}\t{%2, %0|%0, %2}"; 11098 } 11099} 11100 [(set (attr "type") 11101 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11102 (const_int 0)) 11103 (match_operand 0 "register_operand" "")) 11104 (match_operand 2 "const1_operand" "")) 11105 (const_string "alu") 11106 ] 11107 (const_string "ishift"))) 11108 (set_attr "mode" "HI")]) 11109 11110(define_expand "ashlqi3" 11111 [(set (match_operand:QI 0 "nonimmediate_operand" "") 11112 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "") 11113 (match_operand:QI 2 "nonmemory_operand" ""))) 11114 (clobber (reg:CC FLAGS_REG))] 11115 "TARGET_QIMODE_MATH" 11116 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;") 11117 11118;; %%% Potential partial reg stall on alternative 2. What to do? 11119 11120(define_insn "*ashlqi3_1_lea" 11121 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r") 11122 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l") 11123 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M"))) 11124 (clobber (reg:CC FLAGS_REG))] 11125 "!TARGET_PARTIAL_REG_STALL 11126 && ix86_binary_operator_ok (ASHIFT, QImode, operands)" 11127{ 11128 switch (get_attr_type (insn)) 11129 { 11130 case TYPE_LEA: 11131 return "#"; 11132 case TYPE_ALU: 11133 gcc_assert (operands[2] == const1_rtx); 11134 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) 11135 return "add{l}\t{%k0, %k0|%k0, %k0}"; 11136 else 11137 return "add{b}\t{%0, %0|%0, %0}"; 11138 11139 default: 11140 if (REG_P (operands[2])) 11141 { 11142 if (get_attr_mode (insn) == MODE_SI) 11143 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 11144 else 11145 return "sal{b}\t{%b2, %0|%0, %b2}"; 11146 } 11147 else if (operands[2] == const1_rtx 11148 && (TARGET_SHIFT1 || optimize_size)) 11149 { 11150 if (get_attr_mode (insn) == MODE_SI) 11151 return "sal{l}\t%0"; 11152 else 11153 return "sal{b}\t%0"; 11154 } 11155 else 11156 { 11157 if (get_attr_mode (insn) == MODE_SI) 11158 return "sal{l}\t{%2, %k0|%k0, %2}"; 11159 else 11160 return "sal{b}\t{%2, %0|%0, %2}"; 11161 } 11162 } 11163} 11164 [(set (attr "type") 11165 (cond [(eq_attr "alternative" "2") 11166 (const_string "lea") 11167 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11168 (const_int 0)) 11169 (match_operand 0 "register_operand" "")) 11170 (match_operand 2 "const1_operand" "")) 11171 (const_string "alu") 11172 ] 11173 (const_string "ishift"))) 11174 (set_attr "mode" "QI,SI,SI")]) 11175 11176(define_insn "*ashlqi3_1" 11177 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") 11178 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 11179 (match_operand:QI 2 "nonmemory_operand" "cI,cI"))) 11180 (clobber (reg:CC FLAGS_REG))] 11181 "TARGET_PARTIAL_REG_STALL 11182 && ix86_binary_operator_ok (ASHIFT, QImode, operands)" 11183{ 11184 switch (get_attr_type (insn)) 11185 { 11186 case TYPE_ALU: 11187 gcc_assert (operands[2] == const1_rtx); 11188 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) 11189 return "add{l}\t{%k0, %k0|%k0, %k0}"; 11190 else 11191 return "add{b}\t{%0, %0|%0, %0}"; 11192 11193 default: 11194 if (REG_P (operands[2])) 11195 { 11196 if (get_attr_mode (insn) == MODE_SI) 11197 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 11198 else 11199 return "sal{b}\t{%b2, %0|%0, %b2}"; 11200 } 11201 else if (operands[2] == const1_rtx 11202 && (TARGET_SHIFT1 || optimize_size)) 11203 { 11204 if (get_attr_mode (insn) == MODE_SI) 11205 return "sal{l}\t%0"; 11206 else 11207 return "sal{b}\t%0"; 11208 } 11209 else 11210 { 11211 if (get_attr_mode (insn) == MODE_SI) 11212 return "sal{l}\t{%2, %k0|%k0, %2}"; 11213 else 11214 return "sal{b}\t{%2, %0|%0, %2}"; 11215 } 11216 } 11217} 11218 [(set (attr "type") 11219 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11220 (const_int 0)) 11221 (match_operand 0 "register_operand" "")) 11222 (match_operand 2 "const1_operand" "")) 11223 (const_string "alu") 11224 ] 11225 (const_string "ishift"))) 11226 (set_attr "mode" "QI,SI")]) 11227 11228;; This pattern can't accept a variable shift count, since shifts by 11229;; zero don't affect the flags. We assume that shifts by constant 11230;; zero are optimized away. 11231(define_insn "*ashlqi3_cmp" 11232 [(set (reg FLAGS_REG) 11233 (compare 11234 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11235 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11236 (const_int 0))) 11237 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11238 (ashift:QI (match_dup 1) (match_dup 2)))] 11239 "ix86_match_ccmode (insn, CCGOCmode) 11240 && ix86_binary_operator_ok (ASHIFT, QImode, operands) 11241 && (optimize_size 11242 || !TARGET_PARTIAL_FLAG_REG_STALL 11243 || (operands[2] == const1_rtx 11244 && (TARGET_SHIFT1 11245 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 11246{ 11247 switch (get_attr_type (insn)) 11248 { 11249 case TYPE_ALU: 11250 gcc_assert (operands[2] == const1_rtx); 11251 return "add{b}\t{%0, %0|%0, %0}"; 11252 11253 default: 11254 if (REG_P (operands[2])) 11255 return "sal{b}\t{%b2, %0|%0, %b2}"; 11256 else if (operands[2] == const1_rtx 11257 && (TARGET_SHIFT1 || optimize_size)) 11258 return "sal{b}\t%0"; 11259 else 11260 return "sal{b}\t{%2, %0|%0, %2}"; 11261 } 11262} 11263 [(set (attr "type") 11264 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11265 (const_int 0)) 11266 (match_operand 0 "register_operand" "")) 11267 (match_operand 2 "const1_operand" "")) 11268 (const_string "alu") 11269 ] 11270 (const_string "ishift"))) 11271 (set_attr "mode" "QI")]) 11272 11273(define_insn "*ashlqi3_cconly" 11274 [(set (reg FLAGS_REG) 11275 (compare 11276 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11277 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11278 (const_int 0))) 11279 (clobber (match_scratch:QI 0 "=q"))] 11280 "ix86_match_ccmode (insn, CCGOCmode) 11281 && ix86_binary_operator_ok (ASHIFT, QImode, operands) 11282 && (optimize_size 11283 || !TARGET_PARTIAL_FLAG_REG_STALL 11284 || (operands[2] == const1_rtx 11285 && (TARGET_SHIFT1 11286 || TARGET_DOUBLE_WITH_ADD)))" 11287{ 11288 switch (get_attr_type (insn)) 11289 { 11290 case TYPE_ALU: 11291 gcc_assert (operands[2] == const1_rtx); 11292 return "add{b}\t{%0, %0|%0, %0}"; 11293 11294 default: 11295 if (REG_P (operands[2])) 11296 return "sal{b}\t{%b2, %0|%0, %b2}"; 11297 else if (operands[2] == const1_rtx 11298 && (TARGET_SHIFT1 || optimize_size)) 11299 return "sal{b}\t%0"; 11300 else 11301 return "sal{b}\t{%2, %0|%0, %2}"; 11302 } 11303} 11304 [(set (attr "type") 11305 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11306 (const_int 0)) 11307 (match_operand 0 "register_operand" "")) 11308 (match_operand 2 "const1_operand" "")) 11309 (const_string "alu") 11310 ] 11311 (const_string "ishift"))) 11312 (set_attr "mode" "QI")]) 11313 11314;; See comment above `ashldi3' about how this works. 11315 11316(define_expand "ashrti3" 11317 [(parallel [(set (match_operand:TI 0 "register_operand" "") 11318 (ashiftrt:TI (match_operand:TI 1 "register_operand" "") 11319 (match_operand:QI 2 "nonmemory_operand" ""))) 11320 (clobber (reg:CC FLAGS_REG))])] 11321 "TARGET_64BIT" 11322{ 11323 if (! immediate_operand (operands[2], QImode)) 11324 { 11325 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2])); 11326 DONE; 11327 } 11328 ix86_expand_binary_operator (ASHIFTRT, TImode, operands); 11329 DONE; 11330}) 11331 11332(define_insn "ashrti3_1" 11333 [(set (match_operand:TI 0 "register_operand" "=r") 11334 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0") 11335 (match_operand:QI 2 "register_operand" "c"))) 11336 (clobber (match_scratch:DI 3 "=&r")) 11337 (clobber (reg:CC FLAGS_REG))] 11338 "TARGET_64BIT" 11339 "#" 11340 [(set_attr "type" "multi")]) 11341 11342(define_insn "*ashrti3_2" 11343 [(set (match_operand:TI 0 "register_operand" "=r") 11344 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0") 11345 (match_operand:QI 2 "immediate_operand" "O"))) 11346 (clobber (reg:CC FLAGS_REG))] 11347 "TARGET_64BIT" 11348 "#" 11349 [(set_attr "type" "multi")]) 11350 11351(define_split 11352 [(set (match_operand:TI 0 "register_operand" "") 11353 (ashiftrt:TI (match_operand:TI 1 "register_operand" "") 11354 (match_operand:QI 2 "register_operand" ""))) 11355 (clobber (match_scratch:DI 3 "")) 11356 (clobber (reg:CC FLAGS_REG))] 11357 "TARGET_64BIT && reload_completed" 11358 [(const_int 0)] 11359 "ix86_split_ashr (operands, operands[3], TImode); DONE;") 11360 11361(define_split 11362 [(set (match_operand:TI 0 "register_operand" "") 11363 (ashiftrt:TI (match_operand:TI 1 "register_operand" "") 11364 (match_operand:QI 2 "immediate_operand" ""))) 11365 (clobber (reg:CC FLAGS_REG))] 11366 "TARGET_64BIT && reload_completed" 11367 [(const_int 0)] 11368 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;") 11369 11370(define_insn "x86_64_shrd" 11371 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m") 11372 (ior:DI (ashiftrt:DI (match_dup 0) 11373 (match_operand:QI 2 "nonmemory_operand" "J,c")) 11374 (ashift:DI (match_operand:DI 1 "register_operand" "r,r") 11375 (minus:QI (const_int 64) (match_dup 2))))) 11376 (clobber (reg:CC FLAGS_REG))] 11377 "TARGET_64BIT" 11378 "@ 11379 shrd{q}\t{%2, %1, %0|%0, %1, %2} 11380 shrd{q}\t{%s2%1, %0|%0, %1, %2}" 11381 [(set_attr "type" "ishift") 11382 (set_attr "prefix_0f" "1") 11383 (set_attr "mode" "DI") 11384 (set_attr "athlon_decode" "vector") 11385 (set_attr "amdfam10_decode" "vector")]) 11386 11387(define_expand "ashrdi3" 11388 [(set (match_operand:DI 0 "shiftdi_operand" "") 11389 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") 11390 (match_operand:QI 2 "nonmemory_operand" "")))] 11391 "" 11392 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;") 11393 11394(define_insn "*ashrdi3_63_rex64" 11395 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm") 11396 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0") 11397 (match_operand:DI 2 "const_int_operand" "i,i"))) 11398 (clobber (reg:CC FLAGS_REG))] 11399 "TARGET_64BIT && INTVAL (operands[2]) == 63 11400 && (TARGET_USE_CLTD || optimize_size) 11401 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11402 "@ 11403 {cqto|cqo} 11404 sar{q}\t{%2, %0|%0, %2}" 11405 [(set_attr "type" "imovx,ishift") 11406 (set_attr "prefix_0f" "0,*") 11407 (set_attr "length_immediate" "0,*") 11408 (set_attr "modrm" "0,1") 11409 (set_attr "mode" "DI")]) 11410 11411(define_insn "*ashrdi3_1_one_bit_rex64" 11412 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11413 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11414 (match_operand:QI 2 "const1_operand" ""))) 11415 (clobber (reg:CC FLAGS_REG))] 11416 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands) 11417 && (TARGET_SHIFT1 || optimize_size)" 11418 "sar{q}\t%0" 11419 [(set_attr "type" "ishift") 11420 (set (attr "length") 11421 (if_then_else (match_operand:DI 0 "register_operand" "") 11422 (const_string "2") 11423 (const_string "*")))]) 11424 11425(define_insn "*ashrdi3_1_rex64" 11426 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 11427 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 11428 (match_operand:QI 2 "nonmemory_operand" "J,c"))) 11429 (clobber (reg:CC FLAGS_REG))] 11430 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11431 "@ 11432 sar{q}\t{%2, %0|%0, %2} 11433 sar{q}\t{%b2, %0|%0, %b2}" 11434 [(set_attr "type" "ishift") 11435 (set_attr "mode" "DI")]) 11436 11437;; This pattern can't accept a variable shift count, since shifts by 11438;; zero don't affect the flags. We assume that shifts by constant 11439;; zero are optimized away. 11440(define_insn "*ashrdi3_one_bit_cmp_rex64" 11441 [(set (reg FLAGS_REG) 11442 (compare 11443 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11444 (match_operand:QI 2 "const1_operand" "")) 11445 (const_int 0))) 11446 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11447 (ashiftrt:DI (match_dup 1) (match_dup 2)))] 11448 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11449 && (TARGET_SHIFT1 || optimize_size) 11450 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11451 "sar{q}\t%0" 11452 [(set_attr "type" "ishift") 11453 (set (attr "length") 11454 (if_then_else (match_operand:DI 0 "register_operand" "") 11455 (const_string "2") 11456 (const_string "*")))]) 11457 11458(define_insn "*ashrdi3_one_bit_cconly_rex64" 11459 [(set (reg FLAGS_REG) 11460 (compare 11461 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11462 (match_operand:QI 2 "const1_operand" "")) 11463 (const_int 0))) 11464 (clobber (match_scratch:DI 0 "=r"))] 11465 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11466 && (TARGET_SHIFT1 || optimize_size) 11467 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11468 "sar{q}\t%0" 11469 [(set_attr "type" "ishift") 11470 (set_attr "length" "2")]) 11471 11472;; This pattern can't accept a variable shift count, since shifts by 11473;; zero don't affect the flags. We assume that shifts by constant 11474;; zero are optimized away. 11475(define_insn "*ashrdi3_cmp_rex64" 11476 [(set (reg FLAGS_REG) 11477 (compare 11478 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11479 (match_operand:QI 2 "const_int_operand" "n")) 11480 (const_int 0))) 11481 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11482 (ashiftrt:DI (match_dup 1) (match_dup 2)))] 11483 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11484 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands) 11485 && (optimize_size 11486 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11487 "sar{q}\t{%2, %0|%0, %2}" 11488 [(set_attr "type" "ishift") 11489 (set_attr "mode" "DI")]) 11490 11491(define_insn "*ashrdi3_cconly_rex64" 11492 [(set (reg FLAGS_REG) 11493 (compare 11494 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11495 (match_operand:QI 2 "const_int_operand" "n")) 11496 (const_int 0))) 11497 (clobber (match_scratch:DI 0 "=r"))] 11498 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11499 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands) 11500 && (optimize_size 11501 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11502 "sar{q}\t{%2, %0|%0, %2}" 11503 [(set_attr "type" "ishift") 11504 (set_attr "mode" "DI")]) 11505 11506(define_insn "*ashrdi3_1" 11507 [(set (match_operand:DI 0 "register_operand" "=r") 11508 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") 11509 (match_operand:QI 2 "nonmemory_operand" "Jc"))) 11510 (clobber (reg:CC FLAGS_REG))] 11511 "!TARGET_64BIT" 11512 "#" 11513 [(set_attr "type" "multi")]) 11514 11515;; By default we don't ask for a scratch register, because when DImode 11516;; values are manipulated, registers are already at a premium. But if 11517;; we have one handy, we won't turn it away. 11518(define_peephole2 11519 [(match_scratch:SI 3 "r") 11520 (parallel [(set (match_operand:DI 0 "register_operand" "") 11521 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 11522 (match_operand:QI 2 "nonmemory_operand" ""))) 11523 (clobber (reg:CC FLAGS_REG))]) 11524 (match_dup 3)] 11525 "!TARGET_64BIT && TARGET_CMOVE" 11526 [(const_int 0)] 11527 "ix86_split_ashr (operands, operands[3], DImode); DONE;") 11528 11529(define_split 11530 [(set (match_operand:DI 0 "register_operand" "") 11531 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 11532 (match_operand:QI 2 "nonmemory_operand" ""))) 11533 (clobber (reg:CC FLAGS_REG))] 11534 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) 11535 ? flow2_completed : reload_completed)" 11536 [(const_int 0)] 11537 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;") 11538 11539(define_insn "x86_shrd_1" 11540 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m") 11541 (ior:SI (ashiftrt:SI (match_dup 0) 11542 (match_operand:QI 2 "nonmemory_operand" "I,c")) 11543 (ashift:SI (match_operand:SI 1 "register_operand" "r,r") 11544 (minus:QI (const_int 32) (match_dup 2))))) 11545 (clobber (reg:CC FLAGS_REG))] 11546 "" 11547 "@ 11548 shrd{l}\t{%2, %1, %0|%0, %1, %2} 11549 shrd{l}\t{%s2%1, %0|%0, %1, %2}" 11550 [(set_attr "type" "ishift") 11551 (set_attr "prefix_0f" "1") 11552 (set_attr "pent_pair" "np") 11553 (set_attr "mode" "SI")]) 11554 11555(define_expand "x86_shift_adj_3" 11556 [(use (match_operand:SI 0 "register_operand" "")) 11557 (use (match_operand:SI 1 "register_operand" "")) 11558 (use (match_operand:QI 2 "register_operand" ""))] 11559 "" 11560{ 11561 rtx label = gen_label_rtx (); 11562 rtx tmp; 11563 11564 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32))); 11565 11566 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 11567 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 11568 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 11569 gen_rtx_LABEL_REF (VOIDmode, label), 11570 pc_rtx); 11571 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 11572 JUMP_LABEL (tmp) = label; 11573 11574 emit_move_insn (operands[0], operands[1]); 11575 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31))); 11576 11577 emit_label (label); 11578 LABEL_NUSES (label) = 1; 11579 11580 DONE; 11581}) 11582 11583(define_insn "ashrsi3_31" 11584 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm") 11585 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0") 11586 (match_operand:SI 2 "const_int_operand" "i,i"))) 11587 (clobber (reg:CC FLAGS_REG))] 11588 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size) 11589 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11590 "@ 11591 {cltd|cdq} 11592 sar{l}\t{%2, %0|%0, %2}" 11593 [(set_attr "type" "imovx,ishift") 11594 (set_attr "prefix_0f" "0,*") 11595 (set_attr "length_immediate" "0,*") 11596 (set_attr "modrm" "0,1") 11597 (set_attr "mode" "SI")]) 11598 11599(define_insn "*ashrsi3_31_zext" 11600 [(set (match_operand:DI 0 "register_operand" "=*d,r") 11601 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0") 11602 (match_operand:SI 2 "const_int_operand" "i,i")))) 11603 (clobber (reg:CC FLAGS_REG))] 11604 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size) 11605 && INTVAL (operands[2]) == 31 11606 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11607 "@ 11608 {cltd|cdq} 11609 sar{l}\t{%2, %k0|%k0, %2}" 11610 [(set_attr "type" "imovx,ishift") 11611 (set_attr "prefix_0f" "0,*") 11612 (set_attr "length_immediate" "0,*") 11613 (set_attr "modrm" "0,1") 11614 (set_attr "mode" "SI")]) 11615 11616(define_expand "ashrsi3" 11617 [(set (match_operand:SI 0 "nonimmediate_operand" "") 11618 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") 11619 (match_operand:QI 2 "nonmemory_operand" ""))) 11620 (clobber (reg:CC FLAGS_REG))] 11621 "" 11622 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;") 11623 11624(define_insn "*ashrsi3_1_one_bit" 11625 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 11626 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11627 (match_operand:QI 2 "const1_operand" ""))) 11628 (clobber (reg:CC FLAGS_REG))] 11629 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11630 && (TARGET_SHIFT1 || optimize_size)" 11631 "sar{l}\t%0" 11632 [(set_attr "type" "ishift") 11633 (set (attr "length") 11634 (if_then_else (match_operand:SI 0 "register_operand" "") 11635 (const_string "2") 11636 (const_string "*")))]) 11637 11638(define_insn "*ashrsi3_1_one_bit_zext" 11639 [(set (match_operand:DI 0 "register_operand" "=r") 11640 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 11641 (match_operand:QI 2 "const1_operand" "")))) 11642 (clobber (reg:CC FLAGS_REG))] 11643 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11644 && (TARGET_SHIFT1 || optimize_size)" 11645 "sar{l}\t%k0" 11646 [(set_attr "type" "ishift") 11647 (set_attr "length" "2")]) 11648 11649(define_insn "*ashrsi3_1" 11650 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 11651 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 11652 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 11653 (clobber (reg:CC FLAGS_REG))] 11654 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11655 "@ 11656 sar{l}\t{%2, %0|%0, %2} 11657 sar{l}\t{%b2, %0|%0, %b2}" 11658 [(set_attr "type" "ishift") 11659 (set_attr "mode" "SI")]) 11660 11661(define_insn "*ashrsi3_1_zext" 11662 [(set (match_operand:DI 0 "register_operand" "=r,r") 11663 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0") 11664 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 11665 (clobber (reg:CC FLAGS_REG))] 11666 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11667 "@ 11668 sar{l}\t{%2, %k0|%k0, %2} 11669 sar{l}\t{%b2, %k0|%k0, %b2}" 11670 [(set_attr "type" "ishift") 11671 (set_attr "mode" "SI")]) 11672 11673;; This pattern can't accept a variable shift count, since shifts by 11674;; zero don't affect the flags. We assume that shifts by constant 11675;; zero are optimized away. 11676(define_insn "*ashrsi3_one_bit_cmp" 11677 [(set (reg FLAGS_REG) 11678 (compare 11679 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11680 (match_operand:QI 2 "const1_operand" "")) 11681 (const_int 0))) 11682 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 11683 (ashiftrt:SI (match_dup 1) (match_dup 2)))] 11684 "ix86_match_ccmode (insn, CCGOCmode) 11685 && (TARGET_SHIFT1 || optimize_size) 11686 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11687 "sar{l}\t%0" 11688 [(set_attr "type" "ishift") 11689 (set (attr "length") 11690 (if_then_else (match_operand:SI 0 "register_operand" "") 11691 (const_string "2") 11692 (const_string "*")))]) 11693 11694(define_insn "*ashrsi3_one_bit_cconly" 11695 [(set (reg FLAGS_REG) 11696 (compare 11697 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11698 (match_operand:QI 2 "const1_operand" "")) 11699 (const_int 0))) 11700 (clobber (match_scratch:SI 0 "=r"))] 11701 "ix86_match_ccmode (insn, CCGOCmode) 11702 && (TARGET_SHIFT1 || optimize_size) 11703 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11704 "sar{l}\t%0" 11705 [(set_attr "type" "ishift") 11706 (set_attr "length" "2")]) 11707 11708(define_insn "*ashrsi3_one_bit_cmp_zext" 11709 [(set (reg FLAGS_REG) 11710 (compare 11711 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 11712 (match_operand:QI 2 "const1_operand" "")) 11713 (const_int 0))) 11714 (set (match_operand:DI 0 "register_operand" "=r") 11715 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))] 11716 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 11717 && (TARGET_SHIFT1 || optimize_size) 11718 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11719 "sar{l}\t%k0" 11720 [(set_attr "type" "ishift") 11721 (set_attr "length" "2")]) 11722 11723;; This pattern can't accept a variable shift count, since shifts by 11724;; zero don't affect the flags. We assume that shifts by constant 11725;; zero are optimized away. 11726(define_insn "*ashrsi3_cmp" 11727 [(set (reg FLAGS_REG) 11728 (compare 11729 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11730 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11731 (const_int 0))) 11732 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 11733 (ashiftrt:SI (match_dup 1) (match_dup 2)))] 11734 "ix86_match_ccmode (insn, CCGOCmode) 11735 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11736 && (optimize_size 11737 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11738 "sar{l}\t{%2, %0|%0, %2}" 11739 [(set_attr "type" "ishift") 11740 (set_attr "mode" "SI")]) 11741 11742(define_insn "*ashrsi3_cconly" 11743 [(set (reg FLAGS_REG) 11744 (compare 11745 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11746 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11747 (const_int 0))) 11748 (clobber (match_scratch:SI 0 "=r"))] 11749 "ix86_match_ccmode (insn, CCGOCmode) 11750 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11751 && (optimize_size 11752 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11753 "sar{l}\t{%2, %0|%0, %2}" 11754 [(set_attr "type" "ishift") 11755 (set_attr "mode" "SI")]) 11756 11757(define_insn "*ashrsi3_cmp_zext" 11758 [(set (reg FLAGS_REG) 11759 (compare 11760 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 11761 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11762 (const_int 0))) 11763 (set (match_operand:DI 0 "register_operand" "=r") 11764 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))] 11765 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11766 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11767 && (optimize_size 11768 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11769 "sar{l}\t{%2, %k0|%k0, %2}" 11770 [(set_attr "type" "ishift") 11771 (set_attr "mode" "SI")]) 11772 11773(define_expand "ashrhi3" 11774 [(set (match_operand:HI 0 "nonimmediate_operand" "") 11775 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") 11776 (match_operand:QI 2 "nonmemory_operand" ""))) 11777 (clobber (reg:CC FLAGS_REG))] 11778 "TARGET_HIMODE_MATH" 11779 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;") 11780 11781(define_insn "*ashrhi3_1_one_bit" 11782 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 11783 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11784 (match_operand:QI 2 "const1_operand" ""))) 11785 (clobber (reg:CC FLAGS_REG))] 11786 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands) 11787 && (TARGET_SHIFT1 || optimize_size)" 11788 "sar{w}\t%0" 11789 [(set_attr "type" "ishift") 11790 (set (attr "length") 11791 (if_then_else (match_operand 0 "register_operand" "") 11792 (const_string "2") 11793 (const_string "*")))]) 11794 11795(define_insn "*ashrhi3_1" 11796 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 11797 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 11798 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 11799 (clobber (reg:CC FLAGS_REG))] 11800 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" 11801 "@ 11802 sar{w}\t{%2, %0|%0, %2} 11803 sar{w}\t{%b2, %0|%0, %b2}" 11804 [(set_attr "type" "ishift") 11805 (set_attr "mode" "HI")]) 11806 11807;; This pattern can't accept a variable shift count, since shifts by 11808;; zero don't affect the flags. We assume that shifts by constant 11809;; zero are optimized away. 11810(define_insn "*ashrhi3_one_bit_cmp" 11811 [(set (reg FLAGS_REG) 11812 (compare 11813 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11814 (match_operand:QI 2 "const1_operand" "")) 11815 (const_int 0))) 11816 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 11817 (ashiftrt:HI (match_dup 1) (match_dup 2)))] 11818 "ix86_match_ccmode (insn, CCGOCmode) 11819 && (TARGET_SHIFT1 || optimize_size) 11820 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" 11821 "sar{w}\t%0" 11822 [(set_attr "type" "ishift") 11823 (set (attr "length") 11824 (if_then_else (match_operand 0 "register_operand" "") 11825 (const_string "2") 11826 (const_string "*")))]) 11827 11828(define_insn "*ashrhi3_one_bit_cconly" 11829 [(set (reg FLAGS_REG) 11830 (compare 11831 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11832 (match_operand:QI 2 "const1_operand" "")) 11833 (const_int 0))) 11834 (clobber (match_scratch:HI 0 "=r"))] 11835 "ix86_match_ccmode (insn, CCGOCmode) 11836 && (TARGET_SHIFT1 || optimize_size) 11837 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" 11838 "sar{w}\t%0" 11839 [(set_attr "type" "ishift") 11840 (set_attr "length" "2")]) 11841 11842;; This pattern can't accept a variable shift count, since shifts by 11843;; zero don't affect the flags. We assume that shifts by constant 11844;; zero are optimized away. 11845(define_insn "*ashrhi3_cmp" 11846 [(set (reg FLAGS_REG) 11847 (compare 11848 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11849 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11850 (const_int 0))) 11851 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 11852 (ashiftrt:HI (match_dup 1) (match_dup 2)))] 11853 "ix86_match_ccmode (insn, CCGOCmode) 11854 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands) 11855 && (optimize_size 11856 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11857 "sar{w}\t{%2, %0|%0, %2}" 11858 [(set_attr "type" "ishift") 11859 (set_attr "mode" "HI")]) 11860 11861(define_insn "*ashrhi3_cconly" 11862 [(set (reg FLAGS_REG) 11863 (compare 11864 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11865 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11866 (const_int 0))) 11867 (clobber (match_scratch:HI 0 "=r"))] 11868 "ix86_match_ccmode (insn, CCGOCmode) 11869 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands) 11870 && (optimize_size 11871 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11872 "sar{w}\t{%2, %0|%0, %2}" 11873 [(set_attr "type" "ishift") 11874 (set_attr "mode" "HI")]) 11875 11876(define_expand "ashrqi3" 11877 [(set (match_operand:QI 0 "nonimmediate_operand" "") 11878 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "") 11879 (match_operand:QI 2 "nonmemory_operand" ""))) 11880 (clobber (reg:CC FLAGS_REG))] 11881 "TARGET_QIMODE_MATH" 11882 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;") 11883 11884(define_insn "*ashrqi3_1_one_bit" 11885 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11886 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11887 (match_operand:QI 2 "const1_operand" ""))) 11888 (clobber (reg:CC FLAGS_REG))] 11889 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 11890 && (TARGET_SHIFT1 || optimize_size)" 11891 "sar{b}\t%0" 11892 [(set_attr "type" "ishift") 11893 (set (attr "length") 11894 (if_then_else (match_operand 0 "register_operand" "") 11895 (const_string "2") 11896 (const_string "*")))]) 11897 11898(define_insn "*ashrqi3_1_one_bit_slp" 11899 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 11900 (ashiftrt:QI (match_dup 0) 11901 (match_operand:QI 1 "const1_operand" ""))) 11902 (clobber (reg:CC FLAGS_REG))] 11903 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 11904 && (! TARGET_PARTIAL_REG_STALL || optimize_size) 11905 && (TARGET_SHIFT1 || optimize_size)" 11906 "sar{b}\t%0" 11907 [(set_attr "type" "ishift1") 11908 (set (attr "length") 11909 (if_then_else (match_operand 0 "register_operand" "") 11910 (const_string "2") 11911 (const_string "*")))]) 11912 11913(define_insn "*ashrqi3_1" 11914 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 11915 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 11916 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 11917 (clobber (reg:CC FLAGS_REG))] 11918 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" 11919 "@ 11920 sar{b}\t{%2, %0|%0, %2} 11921 sar{b}\t{%b2, %0|%0, %b2}" 11922 [(set_attr "type" "ishift") 11923 (set_attr "mode" "QI")]) 11924 11925(define_insn "*ashrqi3_1_slp" 11926 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 11927 (ashiftrt:QI (match_dup 0) 11928 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 11929 (clobber (reg:CC FLAGS_REG))] 11930 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 11931 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 11932 "@ 11933 sar{b}\t{%1, %0|%0, %1} 11934 sar{b}\t{%b1, %0|%0, %b1}" 11935 [(set_attr "type" "ishift1") 11936 (set_attr "mode" "QI")]) 11937 11938;; This pattern can't accept a variable shift count, since shifts by 11939;; zero don't affect the flags. We assume that shifts by constant 11940;; zero are optimized away. 11941(define_insn "*ashrqi3_one_bit_cmp" 11942 [(set (reg FLAGS_REG) 11943 (compare 11944 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11945 (match_operand:QI 2 "const1_operand" "I")) 11946 (const_int 0))) 11947 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11948 (ashiftrt:QI (match_dup 1) (match_dup 2)))] 11949 "ix86_match_ccmode (insn, CCGOCmode) 11950 && (TARGET_SHIFT1 || optimize_size) 11951 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" 11952 "sar{b}\t%0" 11953 [(set_attr "type" "ishift") 11954 (set (attr "length") 11955 (if_then_else (match_operand 0 "register_operand" "") 11956 (const_string "2") 11957 (const_string "*")))]) 11958 11959(define_insn "*ashrqi3_one_bit_cconly" 11960 [(set (reg FLAGS_REG) 11961 (compare 11962 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11963 (match_operand:QI 2 "const1_operand" "I")) 11964 (const_int 0))) 11965 (clobber (match_scratch:QI 0 "=q"))] 11966 "ix86_match_ccmode (insn, CCGOCmode) 11967 && (TARGET_SHIFT1 || optimize_size) 11968 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" 11969 "sar{b}\t%0" 11970 [(set_attr "type" "ishift") 11971 (set_attr "length" "2")]) 11972 11973;; This pattern can't accept a variable shift count, since shifts by 11974;; zero don't affect the flags. We assume that shifts by constant 11975;; zero are optimized away. 11976(define_insn "*ashrqi3_cmp" 11977 [(set (reg FLAGS_REG) 11978 (compare 11979 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11980 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11981 (const_int 0))) 11982 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11983 (ashiftrt:QI (match_dup 1) (match_dup 2)))] 11984 "ix86_match_ccmode (insn, CCGOCmode) 11985 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 11986 && (optimize_size 11987 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11988 "sar{b}\t{%2, %0|%0, %2}" 11989 [(set_attr "type" "ishift") 11990 (set_attr "mode" "QI")]) 11991 11992(define_insn "*ashrqi3_cconly" 11993 [(set (reg FLAGS_REG) 11994 (compare 11995 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11996 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11997 (const_int 0))) 11998 (clobber (match_scratch:QI 0 "=q"))] 11999 "ix86_match_ccmode (insn, CCGOCmode) 12000 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 12001 && (optimize_size 12002 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12003 "sar{b}\t{%2, %0|%0, %2}" 12004 [(set_attr "type" "ishift") 12005 (set_attr "mode" "QI")]) 12006 12007 12008;; Logical shift instructions 12009 12010;; See comment above `ashldi3' about how this works. 12011 12012(define_expand "lshrti3" 12013 [(parallel [(set (match_operand:TI 0 "register_operand" "") 12014 (lshiftrt:TI (match_operand:TI 1 "register_operand" "") 12015 (match_operand:QI 2 "nonmemory_operand" ""))) 12016 (clobber (reg:CC FLAGS_REG))])] 12017 "TARGET_64BIT" 12018{ 12019 if (! immediate_operand (operands[2], QImode)) 12020 { 12021 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2])); 12022 DONE; 12023 } 12024 ix86_expand_binary_operator (LSHIFTRT, TImode, operands); 12025 DONE; 12026}) 12027 12028(define_insn "lshrti3_1" 12029 [(set (match_operand:TI 0 "register_operand" "=r") 12030 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0") 12031 (match_operand:QI 2 "register_operand" "c"))) 12032 (clobber (match_scratch:DI 3 "=&r")) 12033 (clobber (reg:CC FLAGS_REG))] 12034 "TARGET_64BIT" 12035 "#" 12036 [(set_attr "type" "multi")]) 12037 12038(define_insn "*lshrti3_2" 12039 [(set (match_operand:TI 0 "register_operand" "=r") 12040 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0") 12041 (match_operand:QI 2 "immediate_operand" "O"))) 12042 (clobber (reg:CC FLAGS_REG))] 12043 "TARGET_64BIT" 12044 "#" 12045 [(set_attr "type" "multi")]) 12046 12047(define_split 12048 [(set (match_operand:TI 0 "register_operand" "") 12049 (lshiftrt:TI (match_operand:TI 1 "register_operand" "") 12050 (match_operand:QI 2 "register_operand" ""))) 12051 (clobber (match_scratch:DI 3 "")) 12052 (clobber (reg:CC FLAGS_REG))] 12053 "TARGET_64BIT && reload_completed" 12054 [(const_int 0)] 12055 "ix86_split_lshr (operands, operands[3], TImode); DONE;") 12056 12057(define_split 12058 [(set (match_operand:TI 0 "register_operand" "") 12059 (lshiftrt:TI (match_operand:TI 1 "register_operand" "") 12060 (match_operand:QI 2 "immediate_operand" ""))) 12061 (clobber (reg:CC FLAGS_REG))] 12062 "TARGET_64BIT && reload_completed" 12063 [(const_int 0)] 12064 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;") 12065 12066(define_expand "lshrdi3" 12067 [(set (match_operand:DI 0 "shiftdi_operand" "") 12068 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") 12069 (match_operand:QI 2 "nonmemory_operand" "")))] 12070 "" 12071 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;") 12072 12073(define_insn "*lshrdi3_1_one_bit_rex64" 12074 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12075 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12076 (match_operand:QI 2 "const1_operand" ""))) 12077 (clobber (reg:CC FLAGS_REG))] 12078 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12079 && (TARGET_SHIFT1 || optimize_size)" 12080 "shr{q}\t%0" 12081 [(set_attr "type" "ishift") 12082 (set (attr "length") 12083 (if_then_else (match_operand:DI 0 "register_operand" "") 12084 (const_string "2") 12085 (const_string "*")))]) 12086 12087(define_insn "*lshrdi3_1_rex64" 12088 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 12089 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 12090 (match_operand:QI 2 "nonmemory_operand" "J,c"))) 12091 (clobber (reg:CC FLAGS_REG))] 12092 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12093 "@ 12094 shr{q}\t{%2, %0|%0, %2} 12095 shr{q}\t{%b2, %0|%0, %b2}" 12096 [(set_attr "type" "ishift") 12097 (set_attr "mode" "DI")]) 12098 12099;; This pattern can't accept a variable shift count, since shifts by 12100;; zero don't affect the flags. We assume that shifts by constant 12101;; zero are optimized away. 12102(define_insn "*lshrdi3_cmp_one_bit_rex64" 12103 [(set (reg FLAGS_REG) 12104 (compare 12105 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12106 (match_operand:QI 2 "const1_operand" "")) 12107 (const_int 0))) 12108 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12109 (lshiftrt:DI (match_dup 1) (match_dup 2)))] 12110 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12111 && (TARGET_SHIFT1 || optimize_size) 12112 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12113 "shr{q}\t%0" 12114 [(set_attr "type" "ishift") 12115 (set (attr "length") 12116 (if_then_else (match_operand:DI 0 "register_operand" "") 12117 (const_string "2") 12118 (const_string "*")))]) 12119 12120(define_insn "*lshrdi3_cconly_one_bit_rex64" 12121 [(set (reg FLAGS_REG) 12122 (compare 12123 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12124 (match_operand:QI 2 "const1_operand" "")) 12125 (const_int 0))) 12126 (clobber (match_scratch:DI 0 "=r"))] 12127 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12128 && (TARGET_SHIFT1 || optimize_size) 12129 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12130 "shr{q}\t%0" 12131 [(set_attr "type" "ishift") 12132 (set_attr "length" "2")]) 12133 12134;; This pattern can't accept a variable shift count, since shifts by 12135;; zero don't affect the flags. We assume that shifts by constant 12136;; zero are optimized away. 12137(define_insn "*lshrdi3_cmp_rex64" 12138 [(set (reg FLAGS_REG) 12139 (compare 12140 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12141 (match_operand:QI 2 "const_int_operand" "e")) 12142 (const_int 0))) 12143 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12144 (lshiftrt:DI (match_dup 1) (match_dup 2)))] 12145 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12146 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12147 && (optimize_size 12148 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12149 "shr{q}\t{%2, %0|%0, %2}" 12150 [(set_attr "type" "ishift") 12151 (set_attr "mode" "DI")]) 12152 12153(define_insn "*lshrdi3_cconly_rex64" 12154 [(set (reg FLAGS_REG) 12155 (compare 12156 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12157 (match_operand:QI 2 "const_int_operand" "e")) 12158 (const_int 0))) 12159 (clobber (match_scratch:DI 0 "=r"))] 12160 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12161 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12162 && (optimize_size 12163 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12164 "shr{q}\t{%2, %0|%0, %2}" 12165 [(set_attr "type" "ishift") 12166 (set_attr "mode" "DI")]) 12167 12168(define_insn "*lshrdi3_1" 12169 [(set (match_operand:DI 0 "register_operand" "=r") 12170 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") 12171 (match_operand:QI 2 "nonmemory_operand" "Jc"))) 12172 (clobber (reg:CC FLAGS_REG))] 12173 "!TARGET_64BIT" 12174 "#" 12175 [(set_attr "type" "multi")]) 12176 12177;; By default we don't ask for a scratch register, because when DImode 12178;; values are manipulated, registers are already at a premium. But if 12179;; we have one handy, we won't turn it away. 12180(define_peephole2 12181 [(match_scratch:SI 3 "r") 12182 (parallel [(set (match_operand:DI 0 "register_operand" "") 12183 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 12184 (match_operand:QI 2 "nonmemory_operand" ""))) 12185 (clobber (reg:CC FLAGS_REG))]) 12186 (match_dup 3)] 12187 "!TARGET_64BIT && TARGET_CMOVE" 12188 [(const_int 0)] 12189 "ix86_split_lshr (operands, operands[3], DImode); DONE;") 12190 12191(define_split 12192 [(set (match_operand:DI 0 "register_operand" "") 12193 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 12194 (match_operand:QI 2 "nonmemory_operand" ""))) 12195 (clobber (reg:CC FLAGS_REG))] 12196 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) 12197 ? flow2_completed : reload_completed)" 12198 [(const_int 0)] 12199 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;") 12200 12201(define_expand "lshrsi3" 12202 [(set (match_operand:SI 0 "nonimmediate_operand" "") 12203 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") 12204 (match_operand:QI 2 "nonmemory_operand" ""))) 12205 (clobber (reg:CC FLAGS_REG))] 12206 "" 12207 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;") 12208 12209(define_insn "*lshrsi3_1_one_bit" 12210 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12211 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12212 (match_operand:QI 2 "const1_operand" ""))) 12213 (clobber (reg:CC FLAGS_REG))] 12214 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12215 && (TARGET_SHIFT1 || optimize_size)" 12216 "shr{l}\t%0" 12217 [(set_attr "type" "ishift") 12218 (set (attr "length") 12219 (if_then_else (match_operand:SI 0 "register_operand" "") 12220 (const_string "2") 12221 (const_string "*")))]) 12222 12223(define_insn "*lshrsi3_1_one_bit_zext" 12224 [(set (match_operand:DI 0 "register_operand" "=r") 12225 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0")) 12226 (match_operand:QI 2 "const1_operand" ""))) 12227 (clobber (reg:CC FLAGS_REG))] 12228 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12229 && (TARGET_SHIFT1 || optimize_size)" 12230 "shr{l}\t%k0" 12231 [(set_attr "type" "ishift") 12232 (set_attr "length" "2")]) 12233 12234(define_insn "*lshrsi3_1" 12235 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 12236 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12237 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12238 (clobber (reg:CC FLAGS_REG))] 12239 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12240 "@ 12241 shr{l}\t{%2, %0|%0, %2} 12242 shr{l}\t{%b2, %0|%0, %b2}" 12243 [(set_attr "type" "ishift") 12244 (set_attr "mode" "SI")]) 12245 12246(define_insn "*lshrsi3_1_zext" 12247 [(set (match_operand:DI 0 "register_operand" "=r,r") 12248 (zero_extend:DI 12249 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12250 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 12251 (clobber (reg:CC FLAGS_REG))] 12252 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12253 "@ 12254 shr{l}\t{%2, %k0|%k0, %2} 12255 shr{l}\t{%b2, %k0|%k0, %b2}" 12256 [(set_attr "type" "ishift") 12257 (set_attr "mode" "SI")]) 12258 12259;; This pattern can't accept a variable shift count, since shifts by 12260;; zero don't affect the flags. We assume that shifts by constant 12261;; zero are optimized away. 12262(define_insn "*lshrsi3_one_bit_cmp" 12263 [(set (reg FLAGS_REG) 12264 (compare 12265 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12266 (match_operand:QI 2 "const1_operand" "")) 12267 (const_int 0))) 12268 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12269 (lshiftrt:SI (match_dup 1) (match_dup 2)))] 12270 "ix86_match_ccmode (insn, CCGOCmode) 12271 && (TARGET_SHIFT1 || optimize_size) 12272 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12273 "shr{l}\t%0" 12274 [(set_attr "type" "ishift") 12275 (set (attr "length") 12276 (if_then_else (match_operand:SI 0 "register_operand" "") 12277 (const_string "2") 12278 (const_string "*")))]) 12279 12280(define_insn "*lshrsi3_one_bit_cconly" 12281 [(set (reg FLAGS_REG) 12282 (compare 12283 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12284 (match_operand:QI 2 "const1_operand" "")) 12285 (const_int 0))) 12286 (clobber (match_scratch:SI 0 "=r"))] 12287 "ix86_match_ccmode (insn, CCGOCmode) 12288 && (TARGET_SHIFT1 || optimize_size) 12289 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12290 "shr{l}\t%0" 12291 [(set_attr "type" "ishift") 12292 (set_attr "length" "2")]) 12293 12294(define_insn "*lshrsi3_cmp_one_bit_zext" 12295 [(set (reg FLAGS_REG) 12296 (compare 12297 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 12298 (match_operand:QI 2 "const1_operand" "")) 12299 (const_int 0))) 12300 (set (match_operand:DI 0 "register_operand" "=r") 12301 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 12302 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12303 && (TARGET_SHIFT1 || optimize_size) 12304 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12305 "shr{l}\t%k0" 12306 [(set_attr "type" "ishift") 12307 (set_attr "length" "2")]) 12308 12309;; This pattern can't accept a variable shift count, since shifts by 12310;; zero don't affect the flags. We assume that shifts by constant 12311;; zero are optimized away. 12312(define_insn "*lshrsi3_cmp" 12313 [(set (reg FLAGS_REG) 12314 (compare 12315 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12316 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12317 (const_int 0))) 12318 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12319 (lshiftrt:SI (match_dup 1) (match_dup 2)))] 12320 "ix86_match_ccmode (insn, CCGOCmode) 12321 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12322 && (optimize_size 12323 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12324 "shr{l}\t{%2, %0|%0, %2}" 12325 [(set_attr "type" "ishift") 12326 (set_attr "mode" "SI")]) 12327 12328(define_insn "*lshrsi3_cconly" 12329 [(set (reg FLAGS_REG) 12330 (compare 12331 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12332 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12333 (const_int 0))) 12334 (clobber (match_scratch:SI 0 "=r"))] 12335 "ix86_match_ccmode (insn, CCGOCmode) 12336 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12337 && (optimize_size 12338 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12339 "shr{l}\t{%2, %0|%0, %2}" 12340 [(set_attr "type" "ishift") 12341 (set_attr "mode" "SI")]) 12342 12343(define_insn "*lshrsi3_cmp_zext" 12344 [(set (reg FLAGS_REG) 12345 (compare 12346 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 12347 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12348 (const_int 0))) 12349 (set (match_operand:DI 0 "register_operand" "=r") 12350 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 12351 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12352 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12353 && (optimize_size 12354 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12355 "shr{l}\t{%2, %k0|%k0, %2}" 12356 [(set_attr "type" "ishift") 12357 (set_attr "mode" "SI")]) 12358 12359(define_expand "lshrhi3" 12360 [(set (match_operand:HI 0 "nonimmediate_operand" "") 12361 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") 12362 (match_operand:QI 2 "nonmemory_operand" ""))) 12363 (clobber (reg:CC FLAGS_REG))] 12364 "TARGET_HIMODE_MATH" 12365 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;") 12366 12367(define_insn "*lshrhi3_1_one_bit" 12368 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12369 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12370 (match_operand:QI 2 "const1_operand" ""))) 12371 (clobber (reg:CC FLAGS_REG))] 12372 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12373 && (TARGET_SHIFT1 || optimize_size)" 12374 "shr{w}\t%0" 12375 [(set_attr "type" "ishift") 12376 (set (attr "length") 12377 (if_then_else (match_operand 0 "register_operand" "") 12378 (const_string "2") 12379 (const_string "*")))]) 12380 12381(define_insn "*lshrhi3_1" 12382 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 12383 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 12384 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12385 (clobber (reg:CC FLAGS_REG))] 12386 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12387 "@ 12388 shr{w}\t{%2, %0|%0, %2} 12389 shr{w}\t{%b2, %0|%0, %b2}" 12390 [(set_attr "type" "ishift") 12391 (set_attr "mode" "HI")]) 12392 12393;; This pattern can't accept a variable shift count, since shifts by 12394;; zero don't affect the flags. We assume that shifts by constant 12395;; zero are optimized away. 12396(define_insn "*lshrhi3_one_bit_cmp" 12397 [(set (reg FLAGS_REG) 12398 (compare 12399 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12400 (match_operand:QI 2 "const1_operand" "")) 12401 (const_int 0))) 12402 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12403 (lshiftrt:HI (match_dup 1) (match_dup 2)))] 12404 "ix86_match_ccmode (insn, CCGOCmode) 12405 && (TARGET_SHIFT1 || optimize_size) 12406 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12407 "shr{w}\t%0" 12408 [(set_attr "type" "ishift") 12409 (set (attr "length") 12410 (if_then_else (match_operand:SI 0 "register_operand" "") 12411 (const_string "2") 12412 (const_string "*")))]) 12413 12414(define_insn "*lshrhi3_one_bit_cconly" 12415 [(set (reg FLAGS_REG) 12416 (compare 12417 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12418 (match_operand:QI 2 "const1_operand" "")) 12419 (const_int 0))) 12420 (clobber (match_scratch:HI 0 "=r"))] 12421 "ix86_match_ccmode (insn, CCGOCmode) 12422 && (TARGET_SHIFT1 || optimize_size) 12423 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12424 "shr{w}\t%0" 12425 [(set_attr "type" "ishift") 12426 (set_attr "length" "2")]) 12427 12428;; This pattern can't accept a variable shift count, since shifts by 12429;; zero don't affect the flags. We assume that shifts by constant 12430;; zero are optimized away. 12431(define_insn "*lshrhi3_cmp" 12432 [(set (reg FLAGS_REG) 12433 (compare 12434 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12435 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12436 (const_int 0))) 12437 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12438 (lshiftrt:HI (match_dup 1) (match_dup 2)))] 12439 "ix86_match_ccmode (insn, CCGOCmode) 12440 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12441 && (optimize_size 12442 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12443 "shr{w}\t{%2, %0|%0, %2}" 12444 [(set_attr "type" "ishift") 12445 (set_attr "mode" "HI")]) 12446 12447(define_insn "*lshrhi3_cconly" 12448 [(set (reg FLAGS_REG) 12449 (compare 12450 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12451 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12452 (const_int 0))) 12453 (clobber (match_scratch:HI 0 "=r"))] 12454 "ix86_match_ccmode (insn, CCGOCmode) 12455 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12456 && (optimize_size 12457 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12458 "shr{w}\t{%2, %0|%0, %2}" 12459 [(set_attr "type" "ishift") 12460 (set_attr "mode" "HI")]) 12461 12462(define_expand "lshrqi3" 12463 [(set (match_operand:QI 0 "nonimmediate_operand" "") 12464 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "") 12465 (match_operand:QI 2 "nonmemory_operand" ""))) 12466 (clobber (reg:CC FLAGS_REG))] 12467 "TARGET_QIMODE_MATH" 12468 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;") 12469 12470(define_insn "*lshrqi3_1_one_bit" 12471 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12472 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12473 (match_operand:QI 2 "const1_operand" ""))) 12474 (clobber (reg:CC FLAGS_REG))] 12475 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands) 12476 && (TARGET_SHIFT1 || optimize_size)" 12477 "shr{b}\t%0" 12478 [(set_attr "type" "ishift") 12479 (set (attr "length") 12480 (if_then_else (match_operand 0 "register_operand" "") 12481 (const_string "2") 12482 (const_string "*")))]) 12483 12484(define_insn "*lshrqi3_1_one_bit_slp" 12485 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 12486 (lshiftrt:QI (match_dup 0) 12487 (match_operand:QI 1 "const1_operand" ""))) 12488 (clobber (reg:CC FLAGS_REG))] 12489 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12490 && (TARGET_SHIFT1 || optimize_size)" 12491 "shr{b}\t%0" 12492 [(set_attr "type" "ishift1") 12493 (set (attr "length") 12494 (if_then_else (match_operand 0 "register_operand" "") 12495 (const_string "2") 12496 (const_string "*")))]) 12497 12498(define_insn "*lshrqi3_1" 12499 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 12500 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 12501 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12502 (clobber (reg:CC FLAGS_REG))] 12503 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" 12504 "@ 12505 shr{b}\t{%2, %0|%0, %2} 12506 shr{b}\t{%b2, %0|%0, %b2}" 12507 [(set_attr "type" "ishift") 12508 (set_attr "mode" "QI")]) 12509 12510(define_insn "*lshrqi3_1_slp" 12511 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 12512 (lshiftrt:QI (match_dup 0) 12513 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 12514 (clobber (reg:CC FLAGS_REG))] 12515 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12516 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 12517 "@ 12518 shr{b}\t{%1, %0|%0, %1} 12519 shr{b}\t{%b1, %0|%0, %b1}" 12520 [(set_attr "type" "ishift1") 12521 (set_attr "mode" "QI")]) 12522 12523;; This pattern can't accept a variable shift count, since shifts by 12524;; zero don't affect the flags. We assume that shifts by constant 12525;; zero are optimized away. 12526(define_insn "*lshrqi2_one_bit_cmp" 12527 [(set (reg FLAGS_REG) 12528 (compare 12529 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12530 (match_operand:QI 2 "const1_operand" "")) 12531 (const_int 0))) 12532 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12533 (lshiftrt:QI (match_dup 1) (match_dup 2)))] 12534 "ix86_match_ccmode (insn, CCGOCmode) 12535 && (TARGET_SHIFT1 || optimize_size) 12536 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" 12537 "shr{b}\t%0" 12538 [(set_attr "type" "ishift") 12539 (set (attr "length") 12540 (if_then_else (match_operand:SI 0 "register_operand" "") 12541 (const_string "2") 12542 (const_string "*")))]) 12543 12544(define_insn "*lshrqi2_one_bit_cconly" 12545 [(set (reg FLAGS_REG) 12546 (compare 12547 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12548 (match_operand:QI 2 "const1_operand" "")) 12549 (const_int 0))) 12550 (clobber (match_scratch:QI 0 "=q"))] 12551 "ix86_match_ccmode (insn, CCGOCmode) 12552 && (TARGET_SHIFT1 || optimize_size) 12553 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" 12554 "shr{b}\t%0" 12555 [(set_attr "type" "ishift") 12556 (set_attr "length" "2")]) 12557 12558;; This pattern can't accept a variable shift count, since shifts by 12559;; zero don't affect the flags. We assume that shifts by constant 12560;; zero are optimized away. 12561(define_insn "*lshrqi2_cmp" 12562 [(set (reg FLAGS_REG) 12563 (compare 12564 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12565 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12566 (const_int 0))) 12567 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12568 (lshiftrt:QI (match_dup 1) (match_dup 2)))] 12569 "ix86_match_ccmode (insn, CCGOCmode) 12570 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands) 12571 && (optimize_size 12572 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12573 "shr{b}\t{%2, %0|%0, %2}" 12574 [(set_attr "type" "ishift") 12575 (set_attr "mode" "QI")]) 12576 12577(define_insn "*lshrqi2_cconly" 12578 [(set (reg FLAGS_REG) 12579 (compare 12580 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12581 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12582 (const_int 0))) 12583 (clobber (match_scratch:QI 0 "=q"))] 12584 "ix86_match_ccmode (insn, CCGOCmode) 12585 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands) 12586 && (optimize_size 12587 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12588 "shr{b}\t{%2, %0|%0, %2}" 12589 [(set_attr "type" "ishift") 12590 (set_attr "mode" "QI")]) 12591 12592;; Rotate instructions 12593 12594(define_expand "rotldi3" 12595 [(set (match_operand:DI 0 "shiftdi_operand" "") 12596 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "") 12597 (match_operand:QI 2 "nonmemory_operand" ""))) 12598 (clobber (reg:CC FLAGS_REG))] 12599 "" 12600{ 12601 if (TARGET_64BIT) 12602 { 12603 ix86_expand_binary_operator (ROTATE, DImode, operands); 12604 DONE; 12605 } 12606 if (!const_1_to_31_operand (operands[2], VOIDmode)) 12607 FAIL; 12608 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2])); 12609 DONE; 12610}) 12611 12612;; Implement rotation using two double-precision shift instructions 12613;; and a scratch register. 12614(define_insn_and_split "ix86_rotldi3" 12615 [(set (match_operand:DI 0 "register_operand" "=r") 12616 (rotate:DI (match_operand:DI 1 "register_operand" "0") 12617 (match_operand:QI 2 "const_1_to_31_operand" "I"))) 12618 (clobber (reg:CC FLAGS_REG)) 12619 (clobber (match_scratch:SI 3 "=&r"))] 12620 "!TARGET_64BIT" 12621 "" 12622 "&& reload_completed" 12623 [(set (match_dup 3) (match_dup 4)) 12624 (parallel 12625 [(set (match_dup 4) 12626 (ior:SI (ashift:SI (match_dup 4) (match_dup 2)) 12627 (lshiftrt:SI (match_dup 5) 12628 (minus:QI (const_int 32) (match_dup 2))))) 12629 (clobber (reg:CC FLAGS_REG))]) 12630 (parallel 12631 [(set (match_dup 5) 12632 (ior:SI (ashift:SI (match_dup 5) (match_dup 2)) 12633 (lshiftrt:SI (match_dup 3) 12634 (minus:QI (const_int 32) (match_dup 2))))) 12635 (clobber (reg:CC FLAGS_REG))])] 12636 "split_di (operands, 1, operands + 4, operands + 5);") 12637 12638(define_insn "*rotlsi3_1_one_bit_rex64" 12639 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12640 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12641 (match_operand:QI 2 "const1_operand" ""))) 12642 (clobber (reg:CC FLAGS_REG))] 12643 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands) 12644 && (TARGET_SHIFT1 || optimize_size)" 12645 "rol{q}\t%0" 12646 [(set_attr "type" "rotate") 12647 (set (attr "length") 12648 (if_then_else (match_operand:DI 0 "register_operand" "") 12649 (const_string "2") 12650 (const_string "*")))]) 12651 12652(define_insn "*rotldi3_1_rex64" 12653 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 12654 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 12655 (match_operand:QI 2 "nonmemory_operand" "e,c"))) 12656 (clobber (reg:CC FLAGS_REG))] 12657 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)" 12658 "@ 12659 rol{q}\t{%2, %0|%0, %2} 12660 rol{q}\t{%b2, %0|%0, %b2}" 12661 [(set_attr "type" "rotate") 12662 (set_attr "mode" "DI")]) 12663 12664(define_expand "rotlsi3" 12665 [(set (match_operand:SI 0 "nonimmediate_operand" "") 12666 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "") 12667 (match_operand:QI 2 "nonmemory_operand" ""))) 12668 (clobber (reg:CC FLAGS_REG))] 12669 "" 12670 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;") 12671 12672(define_insn "*rotlsi3_1_one_bit" 12673 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12674 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12675 (match_operand:QI 2 "const1_operand" ""))) 12676 (clobber (reg:CC FLAGS_REG))] 12677 "ix86_binary_operator_ok (ROTATE, SImode, operands) 12678 && (TARGET_SHIFT1 || optimize_size)" 12679 "rol{l}\t%0" 12680 [(set_attr "type" "rotate") 12681 (set (attr "length") 12682 (if_then_else (match_operand:SI 0 "register_operand" "") 12683 (const_string "2") 12684 (const_string "*")))]) 12685 12686(define_insn "*rotlsi3_1_one_bit_zext" 12687 [(set (match_operand:DI 0 "register_operand" "=r") 12688 (zero_extend:DI 12689 (rotate:SI (match_operand:SI 1 "register_operand" "0") 12690 (match_operand:QI 2 "const1_operand" "")))) 12691 (clobber (reg:CC FLAGS_REG))] 12692 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands) 12693 && (TARGET_SHIFT1 || optimize_size)" 12694 "rol{l}\t%k0" 12695 [(set_attr "type" "rotate") 12696 (set_attr "length" "2")]) 12697 12698(define_insn "*rotlsi3_1" 12699 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 12700 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12701 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12702 (clobber (reg:CC FLAGS_REG))] 12703 "ix86_binary_operator_ok (ROTATE, SImode, operands)" 12704 "@ 12705 rol{l}\t{%2, %0|%0, %2} 12706 rol{l}\t{%b2, %0|%0, %b2}" 12707 [(set_attr "type" "rotate") 12708 (set_attr "mode" "SI")]) 12709 12710(define_insn "*rotlsi3_1_zext" 12711 [(set (match_operand:DI 0 "register_operand" "=r,r") 12712 (zero_extend:DI 12713 (rotate:SI (match_operand:SI 1 "register_operand" "0,0") 12714 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 12715 (clobber (reg:CC FLAGS_REG))] 12716 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)" 12717 "@ 12718 rol{l}\t{%2, %k0|%k0, %2} 12719 rol{l}\t{%b2, %k0|%k0, %b2}" 12720 [(set_attr "type" "rotate") 12721 (set_attr "mode" "SI")]) 12722 12723(define_expand "rotlhi3" 12724 [(set (match_operand:HI 0 "nonimmediate_operand" "") 12725 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "") 12726 (match_operand:QI 2 "nonmemory_operand" ""))) 12727 (clobber (reg:CC FLAGS_REG))] 12728 "TARGET_HIMODE_MATH" 12729 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;") 12730 12731(define_insn "*rotlhi3_1_one_bit" 12732 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12733 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12734 (match_operand:QI 2 "const1_operand" ""))) 12735 (clobber (reg:CC FLAGS_REG))] 12736 "ix86_binary_operator_ok (ROTATE, HImode, operands) 12737 && (TARGET_SHIFT1 || optimize_size)" 12738 "rol{w}\t%0" 12739 [(set_attr "type" "rotate") 12740 (set (attr "length") 12741 (if_then_else (match_operand 0 "register_operand" "") 12742 (const_string "2") 12743 (const_string "*")))]) 12744 12745(define_insn "*rotlhi3_1" 12746 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 12747 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 12748 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12749 (clobber (reg:CC FLAGS_REG))] 12750 "ix86_binary_operator_ok (ROTATE, HImode, operands)" 12751 "@ 12752 rol{w}\t{%2, %0|%0, %2} 12753 rol{w}\t{%b2, %0|%0, %b2}" 12754 [(set_attr "type" "rotate") 12755 (set_attr "mode" "HI")]) 12756 12757(define_expand "rotlqi3" 12758 [(set (match_operand:QI 0 "nonimmediate_operand" "") 12759 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "") 12760 (match_operand:QI 2 "nonmemory_operand" ""))) 12761 (clobber (reg:CC FLAGS_REG))] 12762 "TARGET_QIMODE_MATH" 12763 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;") 12764 12765(define_insn "*rotlqi3_1_one_bit_slp" 12766 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 12767 (rotate:QI (match_dup 0) 12768 (match_operand:QI 1 "const1_operand" ""))) 12769 (clobber (reg:CC FLAGS_REG))] 12770 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12771 && (TARGET_SHIFT1 || optimize_size)" 12772 "rol{b}\t%0" 12773 [(set_attr "type" "rotate1") 12774 (set (attr "length") 12775 (if_then_else (match_operand 0 "register_operand" "") 12776 (const_string "2") 12777 (const_string "*")))]) 12778 12779(define_insn "*rotlqi3_1_one_bit" 12780 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12781 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12782 (match_operand:QI 2 "const1_operand" ""))) 12783 (clobber (reg:CC FLAGS_REG))] 12784 "ix86_binary_operator_ok (ROTATE, QImode, operands) 12785 && (TARGET_SHIFT1 || optimize_size)" 12786 "rol{b}\t%0" 12787 [(set_attr "type" "rotate") 12788 (set (attr "length") 12789 (if_then_else (match_operand 0 "register_operand" "") 12790 (const_string "2") 12791 (const_string "*")))]) 12792 12793(define_insn "*rotlqi3_1_slp" 12794 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 12795 (rotate:QI (match_dup 0) 12796 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 12797 (clobber (reg:CC FLAGS_REG))] 12798 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12799 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 12800 "@ 12801 rol{b}\t{%1, %0|%0, %1} 12802 rol{b}\t{%b1, %0|%0, %b1}" 12803 [(set_attr "type" "rotate1") 12804 (set_attr "mode" "QI")]) 12805 12806(define_insn "*rotlqi3_1" 12807 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 12808 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 12809 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12810 (clobber (reg:CC FLAGS_REG))] 12811 "ix86_binary_operator_ok (ROTATE, QImode, operands)" 12812 "@ 12813 rol{b}\t{%2, %0|%0, %2} 12814 rol{b}\t{%b2, %0|%0, %b2}" 12815 [(set_attr "type" "rotate") 12816 (set_attr "mode" "QI")]) 12817 12818(define_expand "rotrdi3" 12819 [(set (match_operand:DI 0 "shiftdi_operand" "") 12820 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "") 12821 (match_operand:QI 2 "nonmemory_operand" ""))) 12822 (clobber (reg:CC FLAGS_REG))] 12823 "" 12824{ 12825 if (TARGET_64BIT) 12826 { 12827 ix86_expand_binary_operator (ROTATERT, DImode, operands); 12828 DONE; 12829 } 12830 if (!const_1_to_31_operand (operands[2], VOIDmode)) 12831 FAIL; 12832 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2])); 12833 DONE; 12834}) 12835 12836;; Implement rotation using two double-precision shift instructions 12837;; and a scratch register. 12838(define_insn_and_split "ix86_rotrdi3" 12839 [(set (match_operand:DI 0 "register_operand" "=r") 12840 (rotatert:DI (match_operand:DI 1 "register_operand" "0") 12841 (match_operand:QI 2 "const_1_to_31_operand" "I"))) 12842 (clobber (reg:CC FLAGS_REG)) 12843 (clobber (match_scratch:SI 3 "=&r"))] 12844 "!TARGET_64BIT" 12845 "" 12846 "&& reload_completed" 12847 [(set (match_dup 3) (match_dup 4)) 12848 (parallel 12849 [(set (match_dup 4) 12850 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2)) 12851 (ashift:SI (match_dup 5) 12852 (minus:QI (const_int 32) (match_dup 2))))) 12853 (clobber (reg:CC FLAGS_REG))]) 12854 (parallel 12855 [(set (match_dup 5) 12856 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2)) 12857 (ashift:SI (match_dup 3) 12858 (minus:QI (const_int 32) (match_dup 2))))) 12859 (clobber (reg:CC FLAGS_REG))])] 12860 "split_di (operands, 1, operands + 4, operands + 5);") 12861 12862(define_insn "*rotrdi3_1_one_bit_rex64" 12863 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12864 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12865 (match_operand:QI 2 "const1_operand" ""))) 12866 (clobber (reg:CC FLAGS_REG))] 12867 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands) 12868 && (TARGET_SHIFT1 || optimize_size)" 12869 "ror{q}\t%0" 12870 [(set_attr "type" "rotate") 12871 (set (attr "length") 12872 (if_then_else (match_operand:DI 0 "register_operand" "") 12873 (const_string "2") 12874 (const_string "*")))]) 12875 12876(define_insn "*rotrdi3_1_rex64" 12877 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 12878 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 12879 (match_operand:QI 2 "nonmemory_operand" "J,c"))) 12880 (clobber (reg:CC FLAGS_REG))] 12881 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)" 12882 "@ 12883 ror{q}\t{%2, %0|%0, %2} 12884 ror{q}\t{%b2, %0|%0, %b2}" 12885 [(set_attr "type" "rotate") 12886 (set_attr "mode" "DI")]) 12887 12888(define_expand "rotrsi3" 12889 [(set (match_operand:SI 0 "nonimmediate_operand" "") 12890 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "") 12891 (match_operand:QI 2 "nonmemory_operand" ""))) 12892 (clobber (reg:CC FLAGS_REG))] 12893 "" 12894 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;") 12895 12896(define_insn "*rotrsi3_1_one_bit" 12897 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12898 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12899 (match_operand:QI 2 "const1_operand" ""))) 12900 (clobber (reg:CC FLAGS_REG))] 12901 "ix86_binary_operator_ok (ROTATERT, SImode, operands) 12902 && (TARGET_SHIFT1 || optimize_size)" 12903 "ror{l}\t%0" 12904 [(set_attr "type" "rotate") 12905 (set (attr "length") 12906 (if_then_else (match_operand:SI 0 "register_operand" "") 12907 (const_string "2") 12908 (const_string "*")))]) 12909 12910(define_insn "*rotrsi3_1_one_bit_zext" 12911 [(set (match_operand:DI 0 "register_operand" "=r") 12912 (zero_extend:DI 12913 (rotatert:SI (match_operand:SI 1 "register_operand" "0") 12914 (match_operand:QI 2 "const1_operand" "")))) 12915 (clobber (reg:CC FLAGS_REG))] 12916 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands) 12917 && (TARGET_SHIFT1 || optimize_size)" 12918 "ror{l}\t%k0" 12919 [(set_attr "type" "rotate") 12920 (set (attr "length") 12921 (if_then_else (match_operand:SI 0 "register_operand" "") 12922 (const_string "2") 12923 (const_string "*")))]) 12924 12925(define_insn "*rotrsi3_1" 12926 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 12927 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12928 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12929 (clobber (reg:CC FLAGS_REG))] 12930 "ix86_binary_operator_ok (ROTATERT, SImode, operands)" 12931 "@ 12932 ror{l}\t{%2, %0|%0, %2} 12933 ror{l}\t{%b2, %0|%0, %b2}" 12934 [(set_attr "type" "rotate") 12935 (set_attr "mode" "SI")]) 12936 12937(define_insn "*rotrsi3_1_zext" 12938 [(set (match_operand:DI 0 "register_operand" "=r,r") 12939 (zero_extend:DI 12940 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0") 12941 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 12942 (clobber (reg:CC FLAGS_REG))] 12943 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)" 12944 "@ 12945 ror{l}\t{%2, %k0|%k0, %2} 12946 ror{l}\t{%b2, %k0|%k0, %b2}" 12947 [(set_attr "type" "rotate") 12948 (set_attr "mode" "SI")]) 12949 12950(define_expand "rotrhi3" 12951 [(set (match_operand:HI 0 "nonimmediate_operand" "") 12952 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "") 12953 (match_operand:QI 2 "nonmemory_operand" ""))) 12954 (clobber (reg:CC FLAGS_REG))] 12955 "TARGET_HIMODE_MATH" 12956 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;") 12957 12958(define_insn "*rotrhi3_one_bit" 12959 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12960 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12961 (match_operand:QI 2 "const1_operand" ""))) 12962 (clobber (reg:CC FLAGS_REG))] 12963 "ix86_binary_operator_ok (ROTATERT, HImode, operands) 12964 && (TARGET_SHIFT1 || optimize_size)" 12965 "ror{w}\t%0" 12966 [(set_attr "type" "rotate") 12967 (set (attr "length") 12968 (if_then_else (match_operand 0 "register_operand" "") 12969 (const_string "2") 12970 (const_string "*")))]) 12971 12972(define_insn "*rotrhi3" 12973 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 12974 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 12975 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12976 (clobber (reg:CC FLAGS_REG))] 12977 "ix86_binary_operator_ok (ROTATERT, HImode, operands)" 12978 "@ 12979 ror{w}\t{%2, %0|%0, %2} 12980 ror{w}\t{%b2, %0|%0, %b2}" 12981 [(set_attr "type" "rotate") 12982 (set_attr "mode" "HI")]) 12983 12984(define_expand "rotrqi3" 12985 [(set (match_operand:QI 0 "nonimmediate_operand" "") 12986 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "") 12987 (match_operand:QI 2 "nonmemory_operand" ""))) 12988 (clobber (reg:CC FLAGS_REG))] 12989 "TARGET_QIMODE_MATH" 12990 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;") 12991 12992(define_insn "*rotrqi3_1_one_bit" 12993 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12994 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12995 (match_operand:QI 2 "const1_operand" ""))) 12996 (clobber (reg:CC FLAGS_REG))] 12997 "ix86_binary_operator_ok (ROTATERT, QImode, operands) 12998 && (TARGET_SHIFT1 || optimize_size)" 12999 "ror{b}\t%0" 13000 [(set_attr "type" "rotate") 13001 (set (attr "length") 13002 (if_then_else (match_operand 0 "register_operand" "") 13003 (const_string "2") 13004 (const_string "*")))]) 13005 13006(define_insn "*rotrqi3_1_one_bit_slp" 13007 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 13008 (rotatert:QI (match_dup 0) 13009 (match_operand:QI 1 "const1_operand" ""))) 13010 (clobber (reg:CC FLAGS_REG))] 13011 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 13012 && (TARGET_SHIFT1 || optimize_size)" 13013 "ror{b}\t%0" 13014 [(set_attr "type" "rotate1") 13015 (set (attr "length") 13016 (if_then_else (match_operand 0 "register_operand" "") 13017 (const_string "2") 13018 (const_string "*")))]) 13019 13020(define_insn "*rotrqi3_1" 13021 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 13022 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 13023 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 13024 (clobber (reg:CC FLAGS_REG))] 13025 "ix86_binary_operator_ok (ROTATERT, QImode, operands)" 13026 "@ 13027 ror{b}\t{%2, %0|%0, %2} 13028 ror{b}\t{%b2, %0|%0, %b2}" 13029 [(set_attr "type" "rotate") 13030 (set_attr "mode" "QI")]) 13031 13032(define_insn "*rotrqi3_1_slp" 13033 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 13034 (rotatert:QI (match_dup 0) 13035 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 13036 (clobber (reg:CC FLAGS_REG))] 13037 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 13038 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 13039 "@ 13040 ror{b}\t{%1, %0|%0, %1} 13041 ror{b}\t{%b1, %0|%0, %b1}" 13042 [(set_attr "type" "rotate1") 13043 (set_attr "mode" "QI")]) 13044 13045;; Bit set / bit test instructions 13046 13047(define_expand "extv" 13048 [(set (match_operand:SI 0 "register_operand" "") 13049 (sign_extract:SI (match_operand:SI 1 "register_operand" "") 13050 (match_operand:SI 2 "const8_operand" "") 13051 (match_operand:SI 3 "const8_operand" "")))] 13052 "" 13053{ 13054 /* Handle extractions from %ah et al. */ 13055 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 13056 FAIL; 13057 13058 /* From mips.md: extract_bit_field doesn't verify that our source 13059 matches the predicate, so check it again here. */ 13060 if (! ext_register_operand (operands[1], VOIDmode)) 13061 FAIL; 13062}) 13063 13064(define_expand "extzv" 13065 [(set (match_operand:SI 0 "register_operand" "") 13066 (zero_extract:SI (match_operand 1 "ext_register_operand" "") 13067 (match_operand:SI 2 "const8_operand" "") 13068 (match_operand:SI 3 "const8_operand" "")))] 13069 "" 13070{ 13071 /* Handle extractions from %ah et al. */ 13072 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 13073 FAIL; 13074 13075 /* From mips.md: extract_bit_field doesn't verify that our source 13076 matches the predicate, so check it again here. */ 13077 if (! ext_register_operand (operands[1], VOIDmode)) 13078 FAIL; 13079}) 13080 13081(define_expand "insv" 13082 [(set (zero_extract (match_operand 0 "ext_register_operand" "") 13083 (match_operand 1 "const8_operand" "") 13084 (match_operand 2 "const8_operand" "")) 13085 (match_operand 3 "register_operand" ""))] 13086 "" 13087{ 13088 /* Handle insertions to %ah et al. */ 13089 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8) 13090 FAIL; 13091 13092 /* From mips.md: insert_bit_field doesn't verify that our source 13093 matches the predicate, so check it again here. */ 13094 if (! ext_register_operand (operands[0], VOIDmode)) 13095 FAIL; 13096 13097 if (TARGET_64BIT) 13098 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3])); 13099 else 13100 emit_insn (gen_movsi_insv_1 (operands[0], operands[3])); 13101 13102 DONE; 13103}) 13104 13105;; %%% bts, btr, btc, bt. 13106;; In general these instructions are *slow* when applied to memory, 13107;; since they enforce atomic operation. When applied to registers, 13108;; it depends on the cpu implementation. They're never faster than 13109;; the corresponding and/ior/xor operations, so with 32-bit there's 13110;; no point. But in 64-bit, we can't hold the relevant immediates 13111;; within the instruction itself, so operating on bits in the high 13112;; 32-bits of a register becomes easier. 13113;; 13114;; These are slow on Nocona, but fast on Athlon64. We do require the use 13115;; of btrq and btcq for corner cases of post-reload expansion of absdf and 13116;; negdf respectively, so they can never be disabled entirely. 13117 13118(define_insn "*btsq" 13119 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 13120 (const_int 1) 13121 (match_operand:DI 1 "const_0_to_63_operand" "")) 13122 (const_int 1)) 13123 (clobber (reg:CC FLAGS_REG))] 13124 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 13125 "bts{q} %1,%0" 13126 [(set_attr "type" "alu1")]) 13127 13128(define_insn "*btrq" 13129 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 13130 (const_int 1) 13131 (match_operand:DI 1 "const_0_to_63_operand" "")) 13132 (const_int 0)) 13133 (clobber (reg:CC FLAGS_REG))] 13134 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 13135 "btr{q} %1,%0" 13136 [(set_attr "type" "alu1")]) 13137 13138(define_insn "*btcq" 13139 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 13140 (const_int 1) 13141 (match_operand:DI 1 "const_0_to_63_operand" "")) 13142 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) 13143 (clobber (reg:CC FLAGS_REG))] 13144 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 13145 "btc{q} %1,%0" 13146 [(set_attr "type" "alu1")]) 13147 13148;; Allow Nocona to avoid these instructions if a register is available. 13149 13150(define_peephole2 13151 [(match_scratch:DI 2 "r") 13152 (parallel [(set (zero_extract:DI 13153 (match_operand:DI 0 "register_operand" "") 13154 (const_int 1) 13155 (match_operand:DI 1 "const_0_to_63_operand" "")) 13156 (const_int 1)) 13157 (clobber (reg:CC FLAGS_REG))])] 13158 "TARGET_64BIT && !TARGET_USE_BT" 13159 [(const_int 0)] 13160{ 13161 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 13162 rtx op1; 13163 13164 if (HOST_BITS_PER_WIDE_INT >= 64) 13165 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13166 else if (i < HOST_BITS_PER_WIDE_INT) 13167 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13168 else 13169 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 13170 13171 op1 = immed_double_const (lo, hi, DImode); 13172 if (i >= 31) 13173 { 13174 emit_move_insn (operands[2], op1); 13175 op1 = operands[2]; 13176 } 13177 13178 emit_insn (gen_iordi3 (operands[0], operands[0], op1)); 13179 DONE; 13180}) 13181 13182(define_peephole2 13183 [(match_scratch:DI 2 "r") 13184 (parallel [(set (zero_extract:DI 13185 (match_operand:DI 0 "register_operand" "") 13186 (const_int 1) 13187 (match_operand:DI 1 "const_0_to_63_operand" "")) 13188 (const_int 0)) 13189 (clobber (reg:CC FLAGS_REG))])] 13190 "TARGET_64BIT && !TARGET_USE_BT" 13191 [(const_int 0)] 13192{ 13193 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 13194 rtx op1; 13195 13196 if (HOST_BITS_PER_WIDE_INT >= 64) 13197 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13198 else if (i < HOST_BITS_PER_WIDE_INT) 13199 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13200 else 13201 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 13202 13203 op1 = immed_double_const (~lo, ~hi, DImode); 13204 if (i >= 32) 13205 { 13206 emit_move_insn (operands[2], op1); 13207 op1 = operands[2]; 13208 } 13209 13210 emit_insn (gen_anddi3 (operands[0], operands[0], op1)); 13211 DONE; 13212}) 13213 13214(define_peephole2 13215 [(match_scratch:DI 2 "r") 13216 (parallel [(set (zero_extract:DI 13217 (match_operand:DI 0 "register_operand" "") 13218 (const_int 1) 13219 (match_operand:DI 1 "const_0_to_63_operand" "")) 13220 (not:DI (zero_extract:DI 13221 (match_dup 0) (const_int 1) (match_dup 1)))) 13222 (clobber (reg:CC FLAGS_REG))])] 13223 "TARGET_64BIT && !TARGET_USE_BT" 13224 [(const_int 0)] 13225{ 13226 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 13227 rtx op1; 13228 13229 if (HOST_BITS_PER_WIDE_INT >= 64) 13230 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13231 else if (i < HOST_BITS_PER_WIDE_INT) 13232 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13233 else 13234 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 13235 13236 op1 = immed_double_const (lo, hi, DImode); 13237 if (i >= 31) 13238 { 13239 emit_move_insn (operands[2], op1); 13240 op1 = operands[2]; 13241 } 13242 13243 emit_insn (gen_xordi3 (operands[0], operands[0], op1)); 13244 DONE; 13245}) 13246 13247;; Store-flag instructions. 13248 13249;; For all sCOND expanders, also expand the compare or test insn that 13250;; generates cc0. Generate an equality comparison if `seq' or `sne'. 13251 13252;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way 13253;; to avoid partial register stalls. Otherwise do things the setcc+movzx 13254;; way, which can later delete the movzx if only QImode is needed. 13255 13256(define_expand "seq" 13257 [(set (match_operand:QI 0 "register_operand" "") 13258 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))] 13259 "" 13260 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;") 13261 13262(define_expand "sne" 13263 [(set (match_operand:QI 0 "register_operand" "") 13264 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))] 13265 "" 13266 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;") 13267 13268(define_expand "sgt" 13269 [(set (match_operand:QI 0 "register_operand" "") 13270 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13271 "" 13272 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;") 13273 13274(define_expand "sgtu" 13275 [(set (match_operand:QI 0 "register_operand" "") 13276 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13277 "" 13278 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;") 13279 13280(define_expand "slt" 13281 [(set (match_operand:QI 0 "register_operand" "") 13282 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13283 "" 13284 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;") 13285 13286(define_expand "sltu" 13287 [(set (match_operand:QI 0 "register_operand" "") 13288 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13289 "" 13290 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;") 13291 13292(define_expand "sge" 13293 [(set (match_operand:QI 0 "register_operand" "") 13294 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))] 13295 "" 13296 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;") 13297 13298(define_expand "sgeu" 13299 [(set (match_operand:QI 0 "register_operand" "") 13300 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13301 "" 13302 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;") 13303 13304(define_expand "sle" 13305 [(set (match_operand:QI 0 "register_operand" "") 13306 (le:QI (reg:CC FLAGS_REG) (const_int 0)))] 13307 "" 13308 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;") 13309 13310(define_expand "sleu" 13311 [(set (match_operand:QI 0 "register_operand" "") 13312 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13313 "" 13314 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;") 13315 13316(define_expand "sunordered" 13317 [(set (match_operand:QI 0 "register_operand" "") 13318 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))] 13319 "TARGET_80387 || TARGET_SSE" 13320 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;") 13321 13322(define_expand "sordered" 13323 [(set (match_operand:QI 0 "register_operand" "") 13324 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))] 13325 "TARGET_80387" 13326 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;") 13327 13328(define_expand "suneq" 13329 [(set (match_operand:QI 0 "register_operand" "") 13330 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))] 13331 "TARGET_80387 || TARGET_SSE" 13332 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;") 13333 13334(define_expand "sunge" 13335 [(set (match_operand:QI 0 "register_operand" "") 13336 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))] 13337 "TARGET_80387 || TARGET_SSE" 13338 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;") 13339 13340(define_expand "sungt" 13341 [(set (match_operand:QI 0 "register_operand" "") 13342 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13343 "TARGET_80387 || TARGET_SSE" 13344 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;") 13345 13346(define_expand "sunle" 13347 [(set (match_operand:QI 0 "register_operand" "") 13348 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))] 13349 "TARGET_80387 || TARGET_SSE" 13350 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;") 13351 13352(define_expand "sunlt" 13353 [(set (match_operand:QI 0 "register_operand" "") 13354 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13355 "TARGET_80387 || TARGET_SSE" 13356 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;") 13357 13358(define_expand "sltgt" 13359 [(set (match_operand:QI 0 "register_operand" "") 13360 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13361 "TARGET_80387 || TARGET_SSE" 13362 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;") 13363 13364(define_insn "*setcc_1" 13365 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 13366 (match_operator:QI 1 "ix86_comparison_operator" 13367 [(reg FLAGS_REG) (const_int 0)]))] 13368 "" 13369 "set%C1\t%0" 13370 [(set_attr "type" "setcc") 13371 (set_attr "mode" "QI")]) 13372 13373(define_insn "*setcc_2" 13374 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 13375 (match_operator:QI 1 "ix86_comparison_operator" 13376 [(reg FLAGS_REG) (const_int 0)]))] 13377 "" 13378 "set%C1\t%0" 13379 [(set_attr "type" "setcc") 13380 (set_attr "mode" "QI")]) 13381 13382;; In general it is not safe to assume too much about CCmode registers, 13383;; so simplify-rtx stops when it sees a second one. Under certain 13384;; conditions this is safe on x86, so help combine not create 13385;; 13386;; seta %al 13387;; testb %al, %al 13388;; sete %al 13389 13390(define_split 13391 [(set (match_operand:QI 0 "nonimmediate_operand" "") 13392 (ne:QI (match_operator 1 "ix86_comparison_operator" 13393 [(reg FLAGS_REG) (const_int 0)]) 13394 (const_int 0)))] 13395 "" 13396 [(set (match_dup 0) (match_dup 1))] 13397{ 13398 PUT_MODE (operands[1], QImode); 13399}) 13400 13401(define_split 13402 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 13403 (ne:QI (match_operator 1 "ix86_comparison_operator" 13404 [(reg FLAGS_REG) (const_int 0)]) 13405 (const_int 0)))] 13406 "" 13407 [(set (match_dup 0) (match_dup 1))] 13408{ 13409 PUT_MODE (operands[1], QImode); 13410}) 13411 13412(define_split 13413 [(set (match_operand:QI 0 "nonimmediate_operand" "") 13414 (eq:QI (match_operator 1 "ix86_comparison_operator" 13415 [(reg FLAGS_REG) (const_int 0)]) 13416 (const_int 0)))] 13417 "" 13418 [(set (match_dup 0) (match_dup 1))] 13419{ 13420 rtx new_op1 = copy_rtx (operands[1]); 13421 operands[1] = new_op1; 13422 PUT_MODE (new_op1, QImode); 13423 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), 13424 GET_MODE (XEXP (new_op1, 0)))); 13425 13426 /* Make sure that (a) the CCmode we have for the flags is strong 13427 enough for the reversed compare or (b) we have a valid FP compare. */ 13428 if (! ix86_comparison_operator (new_op1, VOIDmode)) 13429 FAIL; 13430}) 13431 13432(define_split 13433 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 13434 (eq:QI (match_operator 1 "ix86_comparison_operator" 13435 [(reg FLAGS_REG) (const_int 0)]) 13436 (const_int 0)))] 13437 "" 13438 [(set (match_dup 0) (match_dup 1))] 13439{ 13440 rtx new_op1 = copy_rtx (operands[1]); 13441 operands[1] = new_op1; 13442 PUT_MODE (new_op1, QImode); 13443 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), 13444 GET_MODE (XEXP (new_op1, 0)))); 13445 13446 /* Make sure that (a) the CCmode we have for the flags is strong 13447 enough for the reversed compare or (b) we have a valid FP compare. */ 13448 if (! ix86_comparison_operator (new_op1, VOIDmode)) 13449 FAIL; 13450}) 13451 13452;; The SSE store flag instructions saves 0 or 0xffffffff to the result. 13453;; subsequent logical operations are used to imitate conditional moves. 13454;; 0xffffffff is NaN, but not in normalized form, so we can't represent 13455;; it directly. 13456 13457(define_insn "*sse_setccsf" 13458 [(set (match_operand:SF 0 "register_operand" "=x") 13459 (match_operator:SF 1 "sse_comparison_operator" 13460 [(match_operand:SF 2 "register_operand" "0") 13461 (match_operand:SF 3 "nonimmediate_operand" "xm")]))] 13462 "TARGET_SSE" 13463 "cmp%D1ss\t{%3, %0|%0, %3}" 13464 [(set_attr "type" "ssecmp") 13465 (set_attr "mode" "SF")]) 13466 13467(define_insn "*sse_setccdf" 13468 [(set (match_operand:DF 0 "register_operand" "=Y") 13469 (match_operator:DF 1 "sse_comparison_operator" 13470 [(match_operand:DF 2 "register_operand" "0") 13471 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))] 13472 "TARGET_SSE2" 13473 "cmp%D1sd\t{%3, %0|%0, %3}" 13474 [(set_attr "type" "ssecmp") 13475 (set_attr "mode" "DF")]) 13476 13477;; Basic conditional jump instructions. 13478;; We ignore the overflow flag for signed branch instructions. 13479 13480;; For all bCOND expanders, also expand the compare or test insn that 13481;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'. 13482 13483(define_expand "beq" 13484 [(set (pc) 13485 (if_then_else (match_dup 1) 13486 (label_ref (match_operand 0 "" "")) 13487 (pc)))] 13488 "" 13489 "ix86_expand_branch (EQ, operands[0]); DONE;") 13490 13491(define_expand "bne" 13492 [(set (pc) 13493 (if_then_else (match_dup 1) 13494 (label_ref (match_operand 0 "" "")) 13495 (pc)))] 13496 "" 13497 "ix86_expand_branch (NE, operands[0]); DONE;") 13498 13499(define_expand "bgt" 13500 [(set (pc) 13501 (if_then_else (match_dup 1) 13502 (label_ref (match_operand 0 "" "")) 13503 (pc)))] 13504 "" 13505 "ix86_expand_branch (GT, operands[0]); DONE;") 13506 13507(define_expand "bgtu" 13508 [(set (pc) 13509 (if_then_else (match_dup 1) 13510 (label_ref (match_operand 0 "" "")) 13511 (pc)))] 13512 "" 13513 "ix86_expand_branch (GTU, operands[0]); DONE;") 13514 13515(define_expand "blt" 13516 [(set (pc) 13517 (if_then_else (match_dup 1) 13518 (label_ref (match_operand 0 "" "")) 13519 (pc)))] 13520 "" 13521 "ix86_expand_branch (LT, operands[0]); DONE;") 13522 13523(define_expand "bltu" 13524 [(set (pc) 13525 (if_then_else (match_dup 1) 13526 (label_ref (match_operand 0 "" "")) 13527 (pc)))] 13528 "" 13529 "ix86_expand_branch (LTU, operands[0]); DONE;") 13530 13531(define_expand "bge" 13532 [(set (pc) 13533 (if_then_else (match_dup 1) 13534 (label_ref (match_operand 0 "" "")) 13535 (pc)))] 13536 "" 13537 "ix86_expand_branch (GE, operands[0]); DONE;") 13538 13539(define_expand "bgeu" 13540 [(set (pc) 13541 (if_then_else (match_dup 1) 13542 (label_ref (match_operand 0 "" "")) 13543 (pc)))] 13544 "" 13545 "ix86_expand_branch (GEU, operands[0]); DONE;") 13546 13547(define_expand "ble" 13548 [(set (pc) 13549 (if_then_else (match_dup 1) 13550 (label_ref (match_operand 0 "" "")) 13551 (pc)))] 13552 "" 13553 "ix86_expand_branch (LE, operands[0]); DONE;") 13554 13555(define_expand "bleu" 13556 [(set (pc) 13557 (if_then_else (match_dup 1) 13558 (label_ref (match_operand 0 "" "")) 13559 (pc)))] 13560 "" 13561 "ix86_expand_branch (LEU, operands[0]); DONE;") 13562 13563(define_expand "bunordered" 13564 [(set (pc) 13565 (if_then_else (match_dup 1) 13566 (label_ref (match_operand 0 "" "")) 13567 (pc)))] 13568 "TARGET_80387 || TARGET_SSE_MATH" 13569 "ix86_expand_branch (UNORDERED, operands[0]); DONE;") 13570 13571(define_expand "bordered" 13572 [(set (pc) 13573 (if_then_else (match_dup 1) 13574 (label_ref (match_operand 0 "" "")) 13575 (pc)))] 13576 "TARGET_80387 || TARGET_SSE_MATH" 13577 "ix86_expand_branch (ORDERED, operands[0]); DONE;") 13578 13579(define_expand "buneq" 13580 [(set (pc) 13581 (if_then_else (match_dup 1) 13582 (label_ref (match_operand 0 "" "")) 13583 (pc)))] 13584 "TARGET_80387 || TARGET_SSE_MATH" 13585 "ix86_expand_branch (UNEQ, operands[0]); DONE;") 13586 13587(define_expand "bunge" 13588 [(set (pc) 13589 (if_then_else (match_dup 1) 13590 (label_ref (match_operand 0 "" "")) 13591 (pc)))] 13592 "TARGET_80387 || TARGET_SSE_MATH" 13593 "ix86_expand_branch (UNGE, operands[0]); DONE;") 13594 13595(define_expand "bungt" 13596 [(set (pc) 13597 (if_then_else (match_dup 1) 13598 (label_ref (match_operand 0 "" "")) 13599 (pc)))] 13600 "TARGET_80387 || TARGET_SSE_MATH" 13601 "ix86_expand_branch (UNGT, operands[0]); DONE;") 13602 13603(define_expand "bunle" 13604 [(set (pc) 13605 (if_then_else (match_dup 1) 13606 (label_ref (match_operand 0 "" "")) 13607 (pc)))] 13608 "TARGET_80387 || TARGET_SSE_MATH" 13609 "ix86_expand_branch (UNLE, operands[0]); DONE;") 13610 13611(define_expand "bunlt" 13612 [(set (pc) 13613 (if_then_else (match_dup 1) 13614 (label_ref (match_operand 0 "" "")) 13615 (pc)))] 13616 "TARGET_80387 || TARGET_SSE_MATH" 13617 "ix86_expand_branch (UNLT, operands[0]); DONE;") 13618 13619(define_expand "bltgt" 13620 [(set (pc) 13621 (if_then_else (match_dup 1) 13622 (label_ref (match_operand 0 "" "")) 13623 (pc)))] 13624 "TARGET_80387 || TARGET_SSE_MATH" 13625 "ix86_expand_branch (LTGT, operands[0]); DONE;") 13626 13627(define_insn "*jcc_1" 13628 [(set (pc) 13629 (if_then_else (match_operator 1 "ix86_comparison_operator" 13630 [(reg FLAGS_REG) (const_int 0)]) 13631 (label_ref (match_operand 0 "" "")) 13632 (pc)))] 13633 "" 13634 "%+j%C1\t%l0" 13635 [(set_attr "type" "ibr") 13636 (set_attr "modrm" "0") 13637 (set (attr "length") 13638 (if_then_else (and (ge (minus (match_dup 0) (pc)) 13639 (const_int -126)) 13640 (lt (minus (match_dup 0) (pc)) 13641 (const_int 128))) 13642 (const_int 2) 13643 (const_int 6)))]) 13644 13645(define_insn "*jcc_2" 13646 [(set (pc) 13647 (if_then_else (match_operator 1 "ix86_comparison_operator" 13648 [(reg FLAGS_REG) (const_int 0)]) 13649 (pc) 13650 (label_ref (match_operand 0 "" ""))))] 13651 "" 13652 "%+j%c1\t%l0" 13653 [(set_attr "type" "ibr") 13654 (set_attr "modrm" "0") 13655 (set (attr "length") 13656 (if_then_else (and (ge (minus (match_dup 0) (pc)) 13657 (const_int -126)) 13658 (lt (minus (match_dup 0) (pc)) 13659 (const_int 128))) 13660 (const_int 2) 13661 (const_int 6)))]) 13662 13663;; In general it is not safe to assume too much about CCmode registers, 13664;; so simplify-rtx stops when it sees a second one. Under certain 13665;; conditions this is safe on x86, so help combine not create 13666;; 13667;; seta %al 13668;; testb %al, %al 13669;; je Lfoo 13670 13671(define_split 13672 [(set (pc) 13673 (if_then_else (ne (match_operator 0 "ix86_comparison_operator" 13674 [(reg FLAGS_REG) (const_int 0)]) 13675 (const_int 0)) 13676 (label_ref (match_operand 1 "" "")) 13677 (pc)))] 13678 "" 13679 [(set (pc) 13680 (if_then_else (match_dup 0) 13681 (label_ref (match_dup 1)) 13682 (pc)))] 13683{ 13684 PUT_MODE (operands[0], VOIDmode); 13685}) 13686 13687(define_split 13688 [(set (pc) 13689 (if_then_else (eq (match_operator 0 "ix86_comparison_operator" 13690 [(reg FLAGS_REG) (const_int 0)]) 13691 (const_int 0)) 13692 (label_ref (match_operand 1 "" "")) 13693 (pc)))] 13694 "" 13695 [(set (pc) 13696 (if_then_else (match_dup 0) 13697 (label_ref (match_dup 1)) 13698 (pc)))] 13699{ 13700 rtx new_op0 = copy_rtx (operands[0]); 13701 operands[0] = new_op0; 13702 PUT_MODE (new_op0, VOIDmode); 13703 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0), 13704 GET_MODE (XEXP (new_op0, 0)))); 13705 13706 /* Make sure that (a) the CCmode we have for the flags is strong 13707 enough for the reversed compare or (b) we have a valid FP compare. */ 13708 if (! ix86_comparison_operator (new_op0, VOIDmode)) 13709 FAIL; 13710}) 13711 13712;; Define combination compare-and-branch fp compare instructions to use 13713;; during early optimization. Splitting the operation apart early makes 13714;; for bad code when we want to reverse the operation. 13715 13716(define_insn "*fp_jcc_1_mixed" 13717 [(set (pc) 13718 (if_then_else (match_operator 0 "comparison_operator" 13719 [(match_operand 1 "register_operand" "f,x") 13720 (match_operand 2 "nonimmediate_operand" "f,xm")]) 13721 (label_ref (match_operand 3 "" "")) 13722 (pc))) 13723 (clobber (reg:CCFP FPSR_REG)) 13724 (clobber (reg:CCFP FLAGS_REG))] 13725 "TARGET_MIX_SSE_I387 13726 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13727 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13728 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13729 "#") 13730 13731(define_insn "*fp_jcc_1_sse" 13732 [(set (pc) 13733 (if_then_else (match_operator 0 "comparison_operator" 13734 [(match_operand 1 "register_operand" "x") 13735 (match_operand 2 "nonimmediate_operand" "xm")]) 13736 (label_ref (match_operand 3 "" "")) 13737 (pc))) 13738 (clobber (reg:CCFP FPSR_REG)) 13739 (clobber (reg:CCFP FLAGS_REG))] 13740 "TARGET_SSE_MATH 13741 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13742 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13743 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13744 "#") 13745 13746(define_insn "*fp_jcc_1_387" 13747 [(set (pc) 13748 (if_then_else (match_operator 0 "comparison_operator" 13749 [(match_operand 1 "register_operand" "f") 13750 (match_operand 2 "register_operand" "f")]) 13751 (label_ref (match_operand 3 "" "")) 13752 (pc))) 13753 (clobber (reg:CCFP FPSR_REG)) 13754 (clobber (reg:CCFP FLAGS_REG))] 13755 "TARGET_CMOVE && TARGET_80387 13756 && FLOAT_MODE_P (GET_MODE (operands[1])) 13757 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13758 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13759 "#") 13760 13761(define_insn "*fp_jcc_2_mixed" 13762 [(set (pc) 13763 (if_then_else (match_operator 0 "comparison_operator" 13764 [(match_operand 1 "register_operand" "f,x") 13765 (match_operand 2 "nonimmediate_operand" "f,xm")]) 13766 (pc) 13767 (label_ref (match_operand 3 "" "")))) 13768 (clobber (reg:CCFP FPSR_REG)) 13769 (clobber (reg:CCFP FLAGS_REG))] 13770 "TARGET_MIX_SSE_I387 13771 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13772 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13773 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13774 "#") 13775 13776(define_insn "*fp_jcc_2_sse" 13777 [(set (pc) 13778 (if_then_else (match_operator 0 "comparison_operator" 13779 [(match_operand 1 "register_operand" "x") 13780 (match_operand 2 "nonimmediate_operand" "xm")]) 13781 (pc) 13782 (label_ref (match_operand 3 "" "")))) 13783 (clobber (reg:CCFP FPSR_REG)) 13784 (clobber (reg:CCFP FLAGS_REG))] 13785 "TARGET_SSE_MATH 13786 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13787 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13788 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13789 "#") 13790 13791(define_insn "*fp_jcc_2_387" 13792 [(set (pc) 13793 (if_then_else (match_operator 0 "comparison_operator" 13794 [(match_operand 1 "register_operand" "f") 13795 (match_operand 2 "register_operand" "f")]) 13796 (pc) 13797 (label_ref (match_operand 3 "" "")))) 13798 (clobber (reg:CCFP FPSR_REG)) 13799 (clobber (reg:CCFP FLAGS_REG))] 13800 "TARGET_CMOVE && TARGET_80387 13801 && FLOAT_MODE_P (GET_MODE (operands[1])) 13802 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13803 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13804 "#") 13805 13806(define_insn "*fp_jcc_3_387" 13807 [(set (pc) 13808 (if_then_else (match_operator 0 "comparison_operator" 13809 [(match_operand 1 "register_operand" "f") 13810 (match_operand 2 "nonimmediate_operand" "fm")]) 13811 (label_ref (match_operand 3 "" "")) 13812 (pc))) 13813 (clobber (reg:CCFP FPSR_REG)) 13814 (clobber (reg:CCFP FLAGS_REG)) 13815 (clobber (match_scratch:HI 4 "=a"))] 13816 "TARGET_80387 13817 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) 13818 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13819 && !ix86_use_fcomi_compare (GET_CODE (operands[0])) 13820 && SELECT_CC_MODE (GET_CODE (operands[0]), 13821 operands[1], operands[2]) == CCFPmode 13822 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13823 "#") 13824 13825(define_insn "*fp_jcc_4_387" 13826 [(set (pc) 13827 (if_then_else (match_operator 0 "comparison_operator" 13828 [(match_operand 1 "register_operand" "f") 13829 (match_operand 2 "nonimmediate_operand" "fm")]) 13830 (pc) 13831 (label_ref (match_operand 3 "" "")))) 13832 (clobber (reg:CCFP FPSR_REG)) 13833 (clobber (reg:CCFP FLAGS_REG)) 13834 (clobber (match_scratch:HI 4 "=a"))] 13835 "TARGET_80387 13836 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) 13837 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13838 && !ix86_use_fcomi_compare (GET_CODE (operands[0])) 13839 && SELECT_CC_MODE (GET_CODE (operands[0]), 13840 operands[1], operands[2]) == CCFPmode 13841 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13842 "#") 13843 13844(define_insn "*fp_jcc_5_387" 13845 [(set (pc) 13846 (if_then_else (match_operator 0 "comparison_operator" 13847 [(match_operand 1 "register_operand" "f") 13848 (match_operand 2 "register_operand" "f")]) 13849 (label_ref (match_operand 3 "" "")) 13850 (pc))) 13851 (clobber (reg:CCFP FPSR_REG)) 13852 (clobber (reg:CCFP FLAGS_REG)) 13853 (clobber (match_scratch:HI 4 "=a"))] 13854 "TARGET_80387 13855 && FLOAT_MODE_P (GET_MODE (operands[1])) 13856 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13857 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13858 "#") 13859 13860(define_insn "*fp_jcc_6_387" 13861 [(set (pc) 13862 (if_then_else (match_operator 0 "comparison_operator" 13863 [(match_operand 1 "register_operand" "f") 13864 (match_operand 2 "register_operand" "f")]) 13865 (pc) 13866 (label_ref (match_operand 3 "" "")))) 13867 (clobber (reg:CCFP FPSR_REG)) 13868 (clobber (reg:CCFP FLAGS_REG)) 13869 (clobber (match_scratch:HI 4 "=a"))] 13870 "TARGET_80387 13871 && FLOAT_MODE_P (GET_MODE (operands[1])) 13872 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13873 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13874 "#") 13875 13876(define_insn "*fp_jcc_7_387" 13877 [(set (pc) 13878 (if_then_else (match_operator 0 "comparison_operator" 13879 [(match_operand 1 "register_operand" "f") 13880 (match_operand 2 "const0_operand" "X")]) 13881 (label_ref (match_operand 3 "" "")) 13882 (pc))) 13883 (clobber (reg:CCFP FPSR_REG)) 13884 (clobber (reg:CCFP FLAGS_REG)) 13885 (clobber (match_scratch:HI 4 "=a"))] 13886 "TARGET_80387 13887 && FLOAT_MODE_P (GET_MODE (operands[1])) 13888 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13889 && !ix86_use_fcomi_compare (GET_CODE (operands[0])) 13890 && SELECT_CC_MODE (GET_CODE (operands[0]), 13891 operands[1], operands[2]) == CCFPmode 13892 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13893 "#") 13894 13895;; The order of operands in *fp_jcc_8_387 is forced by combine in 13896;; simplify_comparison () function. Float operator is treated as RTX_OBJ 13897;; with a precedence over other operators and is always put in the first 13898;; place. Swap condition and operands to match ficom instruction. 13899 13900(define_insn "*fp_jcc_8<mode>_387" 13901 [(set (pc) 13902 (if_then_else (match_operator 0 "comparison_operator" 13903 [(match_operator 1 "float_operator" 13904 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")]) 13905 (match_operand 3 "register_operand" "f,f")]) 13906 (label_ref (match_operand 4 "" "")) 13907 (pc))) 13908 (clobber (reg:CCFP FPSR_REG)) 13909 (clobber (reg:CCFP FLAGS_REG)) 13910 (clobber (match_scratch:HI 5 "=a,a"))] 13911 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 13912 && FLOAT_MODE_P (GET_MODE (operands[3])) 13913 && GET_MODE (operands[1]) == GET_MODE (operands[3]) 13914 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0]))) 13915 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode 13916 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))" 13917 "#") 13918 13919(define_split 13920 [(set (pc) 13921 (if_then_else (match_operator 0 "comparison_operator" 13922 [(match_operand 1 "register_operand" "") 13923 (match_operand 2 "nonimmediate_operand" "")]) 13924 (match_operand 3 "" "") 13925 (match_operand 4 "" ""))) 13926 (clobber (reg:CCFP FPSR_REG)) 13927 (clobber (reg:CCFP FLAGS_REG))] 13928 "reload_completed" 13929 [(const_int 0)] 13930{ 13931 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 13932 operands[3], operands[4], NULL_RTX, NULL_RTX); 13933 DONE; 13934}) 13935 13936(define_split 13937 [(set (pc) 13938 (if_then_else (match_operator 0 "comparison_operator" 13939 [(match_operand 1 "register_operand" "") 13940 (match_operand 2 "general_operand" "")]) 13941 (match_operand 3 "" "") 13942 (match_operand 4 "" ""))) 13943 (clobber (reg:CCFP FPSR_REG)) 13944 (clobber (reg:CCFP FLAGS_REG)) 13945 (clobber (match_scratch:HI 5 "=a"))] 13946 "reload_completed" 13947 [(const_int 0)] 13948{ 13949 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 13950 operands[3], operands[4], operands[5], NULL_RTX); 13951 DONE; 13952}) 13953 13954(define_split 13955 [(set (pc) 13956 (if_then_else (match_operator 0 "comparison_operator" 13957 [(match_operator 1 "float_operator" 13958 [(match_operand:X87MODEI12 2 "memory_operand" "")]) 13959 (match_operand 3 "register_operand" "")]) 13960 (match_operand 4 "" "") 13961 (match_operand 5 "" ""))) 13962 (clobber (reg:CCFP FPSR_REG)) 13963 (clobber (reg:CCFP FLAGS_REG)) 13964 (clobber (match_scratch:HI 6 "=a"))] 13965 "reload_completed" 13966 [(const_int 0)] 13967{ 13968 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]); 13969 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), 13970 operands[3], operands[7], 13971 operands[4], operands[5], operands[6], NULL_RTX); 13972 DONE; 13973}) 13974 13975;; %%% Kill this when reload knows how to do it. 13976(define_split 13977 [(set (pc) 13978 (if_then_else (match_operator 0 "comparison_operator" 13979 [(match_operator 1 "float_operator" 13980 [(match_operand:X87MODEI12 2 "register_operand" "")]) 13981 (match_operand 3 "register_operand" "")]) 13982 (match_operand 4 "" "") 13983 (match_operand 5 "" ""))) 13984 (clobber (reg:CCFP FPSR_REG)) 13985 (clobber (reg:CCFP FLAGS_REG)) 13986 (clobber (match_scratch:HI 6 "=a"))] 13987 "reload_completed" 13988 [(const_int 0)] 13989{ 13990 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); 13991 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]); 13992 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), 13993 operands[3], operands[7], 13994 operands[4], operands[5], operands[6], operands[2]); 13995 DONE; 13996}) 13997 13998;; Unconditional and other jump instructions 13999 14000(define_insn "jump" 14001 [(set (pc) 14002 (label_ref (match_operand 0 "" "")))] 14003 "" 14004 "jmp\t%l0" 14005 [(set_attr "type" "ibr") 14006 (set (attr "length") 14007 (if_then_else (and (ge (minus (match_dup 0) (pc)) 14008 (const_int -126)) 14009 (lt (minus (match_dup 0) (pc)) 14010 (const_int 128))) 14011 (const_int 2) 14012 (const_int 5))) 14013 (set_attr "modrm" "0")]) 14014 14015(define_expand "indirect_jump" 14016 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))] 14017 "" 14018 "") 14019 14020(define_insn "*indirect_jump" 14021 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))] 14022 "!TARGET_64BIT" 14023 "jmp\t%A0" 14024 [(set_attr "type" "ibr") 14025 (set_attr "length_immediate" "0")]) 14026 14027(define_insn "*indirect_jump_rtx64" 14028 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))] 14029 "TARGET_64BIT" 14030 "jmp\t%A0" 14031 [(set_attr "type" "ibr") 14032 (set_attr "length_immediate" "0")]) 14033 14034(define_expand "tablejump" 14035 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm")) 14036 (use (label_ref (match_operand 1 "" "")))])] 14037 "" 14038{ 14039 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit) 14040 relative. Convert the relative address to an absolute address. */ 14041 if (flag_pic) 14042 { 14043 rtx op0, op1; 14044 enum rtx_code code; 14045 14046 if (TARGET_64BIT) 14047 { 14048 code = PLUS; 14049 op0 = operands[0]; 14050 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]); 14051 } 14052 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA) 14053 { 14054 code = PLUS; 14055 op0 = operands[0]; 14056 op1 = pic_offset_table_rtx; 14057 } 14058 else 14059 { 14060 code = MINUS; 14061 op0 = pic_offset_table_rtx; 14062 op1 = operands[0]; 14063 } 14064 14065 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0, 14066 OPTAB_DIRECT); 14067 } 14068}) 14069 14070(define_insn "*tablejump_1" 14071 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm")) 14072 (use (label_ref (match_operand 1 "" "")))] 14073 "!TARGET_64BIT" 14074 "jmp\t%A0" 14075 [(set_attr "type" "ibr") 14076 (set_attr "length_immediate" "0")]) 14077 14078(define_insn "*tablejump_1_rtx64" 14079 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm")) 14080 (use (label_ref (match_operand 1 "" "")))] 14081 "TARGET_64BIT" 14082 "jmp\t%A0" 14083 [(set_attr "type" "ibr") 14084 (set_attr "length_immediate" "0")]) 14085 14086;; Convert setcc + movzbl to xor + setcc if operands don't overlap. 14087 14088(define_peephole2 14089 [(set (reg FLAGS_REG) (match_operand 0 "" "")) 14090 (set (match_operand:QI 1 "register_operand" "") 14091 (match_operator:QI 2 "ix86_comparison_operator" 14092 [(reg FLAGS_REG) (const_int 0)])) 14093 (set (match_operand 3 "q_regs_operand" "") 14094 (zero_extend (match_dup 1)))] 14095 "(peep2_reg_dead_p (3, operands[1]) 14096 || operands_match_p (operands[1], operands[3])) 14097 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 14098 [(set (match_dup 4) (match_dup 0)) 14099 (set (strict_low_part (match_dup 5)) 14100 (match_dup 2))] 14101{ 14102 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 14103 operands[5] = gen_lowpart (QImode, operands[3]); 14104 ix86_expand_clear (operands[3]); 14105}) 14106 14107;; Similar, but match zero_extendhisi2_and, which adds a clobber. 14108 14109(define_peephole2 14110 [(set (reg FLAGS_REG) (match_operand 0 "" "")) 14111 (set (match_operand:QI 1 "register_operand" "") 14112 (match_operator:QI 2 "ix86_comparison_operator" 14113 [(reg FLAGS_REG) (const_int 0)])) 14114 (parallel [(set (match_operand 3 "q_regs_operand" "") 14115 (zero_extend (match_dup 1))) 14116 (clobber (reg:CC FLAGS_REG))])] 14117 "(peep2_reg_dead_p (3, operands[1]) 14118 || operands_match_p (operands[1], operands[3])) 14119 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 14120 [(set (match_dup 4) (match_dup 0)) 14121 (set (strict_low_part (match_dup 5)) 14122 (match_dup 2))] 14123{ 14124 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 14125 operands[5] = gen_lowpart (QImode, operands[3]); 14126 ix86_expand_clear (operands[3]); 14127}) 14128 14129;; Call instructions. 14130 14131;; The predicates normally associated with named expanders are not properly 14132;; checked for calls. This is a bug in the generic code, but it isn't that 14133;; easy to fix. Ignore it for now and be prepared to fix things up. 14134 14135;; Call subroutine returning no value. 14136 14137(define_expand "call_pop" 14138 [(parallel [(call (match_operand:QI 0 "" "") 14139 (match_operand:SI 1 "" "")) 14140 (set (reg:SI SP_REG) 14141 (plus:SI (reg:SI SP_REG) 14142 (match_operand:SI 3 "" "")))])] 14143 "!TARGET_64BIT" 14144{ 14145 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0); 14146 DONE; 14147}) 14148 14149(define_insn "*call_pop_0" 14150 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" "")) 14151 (match_operand:SI 1 "" "")) 14152 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 14153 (match_operand:SI 2 "immediate_operand" "")))] 14154 "!TARGET_64BIT" 14155{ 14156 if (SIBLING_CALL_P (insn)) 14157 return "jmp\t%P0"; 14158 else 14159 return "call\t%P0"; 14160} 14161 [(set_attr "type" "call")]) 14162 14163(define_insn "*call_pop_1" 14164 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm")) 14165 (match_operand:SI 1 "" "")) 14166 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 14167 (match_operand:SI 2 "immediate_operand" "i")))] 14168 "!TARGET_64BIT" 14169{ 14170 if (constant_call_address_operand (operands[0], Pmode)) 14171 { 14172 if (SIBLING_CALL_P (insn)) 14173 return "jmp\t%P0"; 14174 else 14175 return "call\t%P0"; 14176 } 14177 if (SIBLING_CALL_P (insn)) 14178 return "jmp\t%A0"; 14179 else 14180 return "call\t%A0"; 14181} 14182 [(set_attr "type" "call")]) 14183 14184(define_expand "call" 14185 [(call (match_operand:QI 0 "" "") 14186 (match_operand 1 "" "")) 14187 (use (match_operand 2 "" ""))] 14188 "" 14189{ 14190 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0); 14191 DONE; 14192}) 14193 14194(define_expand "sibcall" 14195 [(call (match_operand:QI 0 "" "") 14196 (match_operand 1 "" "")) 14197 (use (match_operand 2 "" ""))] 14198 "" 14199{ 14200 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1); 14201 DONE; 14202}) 14203 14204(define_insn "*call_0" 14205 [(call (mem:QI (match_operand 0 "constant_call_address_operand" "")) 14206 (match_operand 1 "" ""))] 14207 "" 14208{ 14209 if (SIBLING_CALL_P (insn)) 14210 return "jmp\t%P0"; 14211 else 14212 return "call\t%P0"; 14213} 14214 [(set_attr "type" "call")]) 14215 14216(define_insn "*call_1" 14217 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm")) 14218 (match_operand 1 "" ""))] 14219 "!SIBLING_CALL_P (insn) && !TARGET_64BIT" 14220{ 14221 if (constant_call_address_operand (operands[0], Pmode)) 14222 return "call\t%P0"; 14223 return "call\t%A0"; 14224} 14225 [(set_attr "type" "call")]) 14226 14227(define_insn "*sibcall_1" 14228 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a")) 14229 (match_operand 1 "" ""))] 14230 "SIBLING_CALL_P (insn) && !TARGET_64BIT" 14231{ 14232 if (constant_call_address_operand (operands[0], Pmode)) 14233 return "jmp\t%P0"; 14234 return "jmp\t%A0"; 14235} 14236 [(set_attr "type" "call")]) 14237 14238(define_insn "*call_1_rex64" 14239 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm")) 14240 (match_operand 1 "" ""))] 14241 "!SIBLING_CALL_P (insn) && TARGET_64BIT" 14242{ 14243 if (constant_call_address_operand (operands[0], Pmode)) 14244 return "call\t%P0"; 14245 return "call\t%A0"; 14246} 14247 [(set_attr "type" "call")]) 14248 14249(define_insn "*sibcall_1_rex64" 14250 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" "")) 14251 (match_operand 1 "" ""))] 14252 "SIBLING_CALL_P (insn) && TARGET_64BIT" 14253 "jmp\t%P0" 14254 [(set_attr "type" "call")]) 14255 14256(define_insn "*sibcall_1_rex64_v" 14257 [(call (mem:QI (reg:DI R11_REG)) 14258 (match_operand 0 "" ""))] 14259 "SIBLING_CALL_P (insn) && TARGET_64BIT" 14260 "jmp\t*%%r11" 14261 [(set_attr "type" "call")]) 14262 14263 14264;; Call subroutine, returning value in operand 0 14265 14266(define_expand "call_value_pop" 14267 [(parallel [(set (match_operand 0 "" "") 14268 (call (match_operand:QI 1 "" "") 14269 (match_operand:SI 2 "" ""))) 14270 (set (reg:SI SP_REG) 14271 (plus:SI (reg:SI SP_REG) 14272 (match_operand:SI 4 "" "")))])] 14273 "!TARGET_64BIT" 14274{ 14275 ix86_expand_call (operands[0], operands[1], operands[2], 14276 operands[3], operands[4], 0); 14277 DONE; 14278}) 14279 14280(define_expand "call_value" 14281 [(set (match_operand 0 "" "") 14282 (call (match_operand:QI 1 "" "") 14283 (match_operand:SI 2 "" ""))) 14284 (use (match_operand:SI 3 "" ""))] 14285 ;; Operand 2 not used on the i386. 14286 "" 14287{ 14288 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0); 14289 DONE; 14290}) 14291 14292(define_expand "sibcall_value" 14293 [(set (match_operand 0 "" "") 14294 (call (match_operand:QI 1 "" "") 14295 (match_operand:SI 2 "" ""))) 14296 (use (match_operand:SI 3 "" ""))] 14297 ;; Operand 2 not used on the i386. 14298 "" 14299{ 14300 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1); 14301 DONE; 14302}) 14303 14304;; Call subroutine returning any type. 14305 14306(define_expand "untyped_call" 14307 [(parallel [(call (match_operand 0 "" "") 14308 (const_int 0)) 14309 (match_operand 1 "" "") 14310 (match_operand 2 "" "")])] 14311 "" 14312{ 14313 int i; 14314 14315 /* In order to give reg-stack an easier job in validating two 14316 coprocessor registers as containing a possible return value, 14317 simply pretend the untyped call returns a complex long double 14318 value. */ 14319 14320 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387 14321 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL), 14322 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1), 14323 NULL, 0); 14324 14325 for (i = 0; i < XVECLEN (operands[2], 0); i++) 14326 { 14327 rtx set = XVECEXP (operands[2], 0, i); 14328 emit_move_insn (SET_DEST (set), SET_SRC (set)); 14329 } 14330 14331 /* The optimizer does not know that the call sets the function value 14332 registers we stored in the result block. We avoid problems by 14333 claiming that all hard registers are used and clobbered at this 14334 point. */ 14335 emit_insn (gen_blockage (const0_rtx)); 14336 14337 DONE; 14338}) 14339 14340;; Prologue and epilogue instructions 14341 14342;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 14343;; all of memory. This blocks insns from being moved across this point. 14344 14345(define_insn "blockage" 14346 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)] 14347 "" 14348 "" 14349 [(set_attr "length" "0")]) 14350 14351;; Insn emitted into the body of a function to return from a function. 14352;; This is only done if the function's epilogue is known to be simple. 14353;; See comments for ix86_can_use_return_insn_p in i386.c. 14354 14355(define_expand "return" 14356 [(return)] 14357 "ix86_can_use_return_insn_p ()" 14358{ 14359 if (current_function_pops_args) 14360 { 14361 rtx popc = GEN_INT (current_function_pops_args); 14362 emit_jump_insn (gen_return_pop_internal (popc)); 14363 DONE; 14364 } 14365}) 14366 14367(define_insn "return_internal" 14368 [(return)] 14369 "reload_completed" 14370 "ret" 14371 [(set_attr "length" "1") 14372 (set_attr "length_immediate" "0") 14373 (set_attr "modrm" "0")]) 14374 14375;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET 14376;; instruction Athlon and K8 have. 14377 14378(define_insn "return_internal_long" 14379 [(return) 14380 (unspec [(const_int 0)] UNSPEC_REP)] 14381 "reload_completed" 14382 "rep {;} ret" 14383 [(set_attr "length" "1") 14384 (set_attr "length_immediate" "0") 14385 (set_attr "prefix_rep" "1") 14386 (set_attr "modrm" "0")]) 14387 14388(define_insn "return_pop_internal" 14389 [(return) 14390 (use (match_operand:SI 0 "const_int_operand" ""))] 14391 "reload_completed" 14392 "ret\t%0" 14393 [(set_attr "length" "3") 14394 (set_attr "length_immediate" "2") 14395 (set_attr "modrm" "0")]) 14396 14397(define_insn "return_indirect_internal" 14398 [(return) 14399 (use (match_operand:SI 0 "register_operand" "r"))] 14400 "reload_completed" 14401 "jmp\t%A0" 14402 [(set_attr "type" "ibr") 14403 (set_attr "length_immediate" "0")]) 14404 14405(define_insn "nop" 14406 [(const_int 0)] 14407 "" 14408 "nop" 14409 [(set_attr "length" "1") 14410 (set_attr "length_immediate" "0") 14411 (set_attr "modrm" "0")]) 14412 14413;; Align to 16-byte boundary, max skip in op0. Used to avoid 14414;; branch prediction penalty for the third jump in a 16-byte 14415;; block on K8. 14416 14417(define_insn "align" 14418 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)] 14419 "" 14420{ 14421#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN 14422 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0])); 14423#else 14424 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that. 14425 The align insn is used to avoid 3 jump instructions in the row to improve 14426 branch prediction and the benefits hardly outweigh the cost of extra 8 14427 nops on the average inserted by full alignment pseudo operation. */ 14428#endif 14429 return ""; 14430} 14431 [(set_attr "length" "16")]) 14432 14433(define_expand "prologue" 14434 [(const_int 1)] 14435 "" 14436 "ix86_expand_prologue (); DONE;") 14437 14438(define_insn "set_got" 14439 [(set (match_operand:SI 0 "register_operand" "=r") 14440 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 14441 (clobber (reg:CC FLAGS_REG))] 14442 "!TARGET_64BIT" 14443 { return output_set_got (operands[0], NULL_RTX); } 14444 [(set_attr "type" "multi") 14445 (set_attr "length" "12")]) 14446 14447(define_insn "set_got_labelled" 14448 [(set (match_operand:SI 0 "register_operand" "=r") 14449 (unspec:SI [(label_ref (match_operand 1 "" ""))] 14450 UNSPEC_SET_GOT)) 14451 (clobber (reg:CC FLAGS_REG))] 14452 "!TARGET_64BIT" 14453 { return output_set_got (operands[0], operands[1]); } 14454 [(set_attr "type" "multi") 14455 (set_attr "length" "12")]) 14456 14457(define_insn "set_got_rex64" 14458 [(set (match_operand:DI 0 "register_operand" "=r") 14459 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))] 14460 "TARGET_64BIT" 14461 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0" 14462 [(set_attr "type" "lea") 14463 (set_attr "length" "6")]) 14464 14465(define_expand "epilogue" 14466 [(const_int 1)] 14467 "" 14468 "ix86_expand_epilogue (1); DONE;") 14469 14470(define_expand "sibcall_epilogue" 14471 [(const_int 1)] 14472 "" 14473 "ix86_expand_epilogue (0); DONE;") 14474 14475(define_expand "eh_return" 14476 [(use (match_operand 0 "register_operand" ""))] 14477 "" 14478{ 14479 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0]; 14480 14481 /* Tricky bit: we write the address of the handler to which we will 14482 be returning into someone else's stack frame, one word below the 14483 stack address we wish to restore. */ 14484 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa); 14485 tmp = plus_constant (tmp, -UNITS_PER_WORD); 14486 tmp = gen_rtx_MEM (Pmode, tmp); 14487 emit_move_insn (tmp, ra); 14488 14489 if (Pmode == SImode) 14490 emit_jump_insn (gen_eh_return_si (sa)); 14491 else 14492 emit_jump_insn (gen_eh_return_di (sa)); 14493 emit_barrier (); 14494 DONE; 14495}) 14496 14497(define_insn_and_split "eh_return_si" 14498 [(set (pc) 14499 (unspec [(match_operand:SI 0 "register_operand" "c")] 14500 UNSPEC_EH_RETURN))] 14501 "!TARGET_64BIT" 14502 "#" 14503 "reload_completed" 14504 [(const_int 1)] 14505 "ix86_expand_epilogue (2); DONE;") 14506 14507(define_insn_and_split "eh_return_di" 14508 [(set (pc) 14509 (unspec [(match_operand:DI 0 "register_operand" "c")] 14510 UNSPEC_EH_RETURN))] 14511 "TARGET_64BIT" 14512 "#" 14513 "reload_completed" 14514 [(const_int 1)] 14515 "ix86_expand_epilogue (2); DONE;") 14516 14517(define_insn "leave" 14518 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4))) 14519 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG))) 14520 (clobber (mem:BLK (scratch)))] 14521 "!TARGET_64BIT" 14522 "leave" 14523 [(set_attr "type" "leave")]) 14524 14525(define_insn "leave_rex64" 14526 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8))) 14527 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG))) 14528 (clobber (mem:BLK (scratch)))] 14529 "TARGET_64BIT" 14530 "leave" 14531 [(set_attr "type" "leave")]) 14532 14533(define_expand "ffssi2" 14534 [(parallel 14535 [(set (match_operand:SI 0 "register_operand" "") 14536 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" ""))) 14537 (clobber (match_scratch:SI 2 "")) 14538 (clobber (reg:CC FLAGS_REG))])] 14539 "" 14540 "") 14541 14542(define_insn_and_split "*ffs_cmove" 14543 [(set (match_operand:SI 0 "register_operand" "=r") 14544 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 14545 (clobber (match_scratch:SI 2 "=&r")) 14546 (clobber (reg:CC FLAGS_REG))] 14547 "TARGET_CMOVE" 14548 "#" 14549 "&& reload_completed" 14550 [(set (match_dup 2) (const_int -1)) 14551 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0))) 14552 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 14553 (set (match_dup 0) (if_then_else:SI 14554 (eq (reg:CCZ FLAGS_REG) (const_int 0)) 14555 (match_dup 2) 14556 (match_dup 0))) 14557 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 14558 (clobber (reg:CC FLAGS_REG))])] 14559 "") 14560 14561(define_insn_and_split "*ffs_no_cmove" 14562 [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 14563 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 14564 (clobber (match_scratch:SI 2 "=&q")) 14565 (clobber (reg:CC FLAGS_REG))] 14566 "" 14567 "#" 14568 "reload_completed" 14569 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0))) 14570 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 14571 (set (strict_low_part (match_dup 3)) 14572 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0))) 14573 (parallel [(set (match_dup 2) (neg:SI (match_dup 2))) 14574 (clobber (reg:CC FLAGS_REG))]) 14575 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2))) 14576 (clobber (reg:CC FLAGS_REG))]) 14577 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 14578 (clobber (reg:CC FLAGS_REG))])] 14579{ 14580 operands[3] = gen_lowpart (QImode, operands[2]); 14581 ix86_expand_clear (operands[2]); 14582}) 14583 14584(define_insn "*ffssi_1" 14585 [(set (reg:CCZ FLAGS_REG) 14586 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm") 14587 (const_int 0))) 14588 (set (match_operand:SI 0 "register_operand" "=r") 14589 (ctz:SI (match_dup 1)))] 14590 "" 14591 "bsf{l}\t{%1, %0|%0, %1}" 14592 [(set_attr "prefix_0f" "1")]) 14593 14594(define_expand "ffsdi2" 14595 [(parallel 14596 [(set (match_operand:DI 0 "register_operand" "") 14597 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" ""))) 14598 (clobber (match_scratch:DI 2 "")) 14599 (clobber (reg:CC FLAGS_REG))])] 14600 "TARGET_64BIT && TARGET_CMOVE" 14601 "") 14602 14603(define_insn_and_split "*ffs_rex64" 14604 [(set (match_operand:DI 0 "register_operand" "=r") 14605 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))) 14606 (clobber (match_scratch:DI 2 "=&r")) 14607 (clobber (reg:CC FLAGS_REG))] 14608 "TARGET_64BIT && TARGET_CMOVE" 14609 "#" 14610 "&& reload_completed" 14611 [(set (match_dup 2) (const_int -1)) 14612 (parallel [(set (reg:CCZ FLAGS_REG) 14613 (compare:CCZ (match_dup 1) (const_int 0))) 14614 (set (match_dup 0) (ctz:DI (match_dup 1)))]) 14615 (set (match_dup 0) (if_then_else:DI 14616 (eq (reg:CCZ FLAGS_REG) (const_int 0)) 14617 (match_dup 2) 14618 (match_dup 0))) 14619 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1))) 14620 (clobber (reg:CC FLAGS_REG))])] 14621 "") 14622 14623(define_insn "*ffsdi_1" 14624 [(set (reg:CCZ FLAGS_REG) 14625 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm") 14626 (const_int 0))) 14627 (set (match_operand:DI 0 "register_operand" "=r") 14628 (ctz:DI (match_dup 1)))] 14629 "TARGET_64BIT" 14630 "bsf{q}\t{%1, %0|%0, %1}" 14631 [(set_attr "prefix_0f" "1")]) 14632 14633(define_insn "ctzsi2" 14634 [(set (match_operand:SI 0 "register_operand" "=r") 14635 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 14636 (clobber (reg:CC FLAGS_REG))] 14637 "" 14638 "bsf{l}\t{%1, %0|%0, %1}" 14639 [(set_attr "prefix_0f" "1")]) 14640 14641(define_insn "ctzdi2" 14642 [(set (match_operand:DI 0 "register_operand" "=r") 14643 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))) 14644 (clobber (reg:CC FLAGS_REG))] 14645 "TARGET_64BIT" 14646 "bsf{q}\t{%1, %0|%0, %1}" 14647 [(set_attr "prefix_0f" "1")]) 14648 14649(define_expand "clzsi2" 14650 [(parallel 14651 [(set (match_operand:SI 0 "register_operand" "") 14652 (minus:SI (const_int 31) 14653 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))) 14654 (clobber (reg:CC FLAGS_REG))]) 14655 (parallel 14656 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31))) 14657 (clobber (reg:CC FLAGS_REG))])] 14658 "" 14659{ 14660 if (TARGET_ABM) 14661 { 14662 emit_insn (gen_clzsi2_abm (operands[0], operands[1])); 14663 DONE; 14664 } 14665}) 14666 14667(define_insn "clzsi2_abm" 14668 [(set (match_operand:SI 0 "register_operand" "=r") 14669 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))) 14670 (clobber (reg:CC FLAGS_REG))] 14671 "TARGET_ABM" 14672 "lzcnt{l}\t{%1, %0|%0, %1}" 14673 [(set_attr "prefix_rep" "1") 14674 (set_attr "type" "bitmanip") 14675 (set_attr "mode" "SI")]) 14676 14677(define_insn "*bsr" 14678 [(set (match_operand:SI 0 "register_operand" "=r") 14679 (minus:SI (const_int 31) 14680 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))) 14681 (clobber (reg:CC FLAGS_REG))] 14682 "" 14683 "bsr{l}\t{%1, %0|%0, %1}" 14684 [(set_attr "prefix_0f" "1") 14685 (set_attr "mode" "SI")]) 14686 14687(define_insn "popcountsi2" 14688 [(set (match_operand:SI 0 "register_operand" "=r") 14689 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" ""))) 14690 (clobber (reg:CC FLAGS_REG))] 14691 "TARGET_POPCNT" 14692 "popcnt{l}\t{%1, %0|%0, %1}" 14693 [(set_attr "prefix_rep" "1") 14694 (set_attr "type" "bitmanip") 14695 (set_attr "mode" "SI")]) 14696 14697(define_insn "*popcountsi2_cmp" 14698 [(set (reg FLAGS_REG) 14699 (compare 14700 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm")) 14701 (const_int 0))) 14702 (set (match_operand:SI 0 "register_operand" "=r") 14703 (popcount:SI (match_dup 1)))] 14704 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" 14705 "popcnt{l}\t{%1, %0|%0, %1}" 14706 [(set_attr "prefix_rep" "1") 14707 (set_attr "type" "bitmanip") 14708 (set_attr "mode" "SI")]) 14709 14710(define_insn "*popcountsi2_cmp_zext" 14711 [(set (reg FLAGS_REG) 14712 (compare 14713 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm")) 14714 (const_int 0))) 14715 (set (match_operand:DI 0 "register_operand" "=r") 14716 (zero_extend:DI(popcount:SI (match_dup 1))))] 14717 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" 14718 "popcnt{l}\t{%1, %0|%0, %1}" 14719 [(set_attr "prefix_rep" "1") 14720 (set_attr "type" "bitmanip") 14721 (set_attr "mode" "SI")]) 14722 14723(define_expand "clzdi2" 14724 [(parallel 14725 [(set (match_operand:DI 0 "register_operand" "") 14726 (minus:DI (const_int 63) 14727 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))) 14728 (clobber (reg:CC FLAGS_REG))]) 14729 (parallel 14730 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63))) 14731 (clobber (reg:CC FLAGS_REG))])] 14732 "TARGET_64BIT" 14733{ 14734 if (TARGET_ABM) 14735 { 14736 emit_insn (gen_clzdi2_abm (operands[0], operands[1])); 14737 DONE; 14738 } 14739}) 14740 14741(define_insn "clzdi2_abm" 14742 [(set (match_operand:DI 0 "register_operand" "=r") 14743 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))) 14744 (clobber (reg:CC FLAGS_REG))] 14745 "TARGET_64BIT && TARGET_ABM" 14746 "lzcnt{q}\t{%1, %0|%0, %1}" 14747 [(set_attr "prefix_rep" "1") 14748 (set_attr "type" "bitmanip") 14749 (set_attr "mode" "DI")]) 14750 14751(define_insn "*bsr_rex64" 14752 [(set (match_operand:DI 0 "register_operand" "=r") 14753 (minus:DI (const_int 63) 14754 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) 14755 (clobber (reg:CC FLAGS_REG))] 14756 "TARGET_64BIT" 14757 "bsr{q}\t{%1, %0|%0, %1}" 14758 [(set_attr "prefix_0f" "1") 14759 (set_attr "mode" "DI")]) 14760 14761(define_insn "popcountdi2" 14762 [(set (match_operand:DI 0 "register_operand" "=r") 14763 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" ""))) 14764 (clobber (reg:CC FLAGS_REG))] 14765 "TARGET_64BIT && TARGET_POPCNT" 14766 "popcnt{q}\t{%1, %0|%0, %1}" 14767 [(set_attr "prefix_rep" "1") 14768 (set_attr "type" "bitmanip") 14769 (set_attr "mode" "DI")]) 14770 14771(define_insn "*popcountdi2_cmp" 14772 [(set (reg FLAGS_REG) 14773 (compare 14774 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm")) 14775 (const_int 0))) 14776 (set (match_operand:DI 0 "register_operand" "=r") 14777 (popcount:DI (match_dup 1)))] 14778 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" 14779 "popcnt{q}\t{%1, %0|%0, %1}" 14780 [(set_attr "prefix_rep" "1") 14781 (set_attr "type" "bitmanip") 14782 (set_attr "mode" "DI")]) 14783 14784(define_expand "clzhi2" 14785 [(parallel 14786 [(set (match_operand:HI 0 "register_operand" "") 14787 (minus:HI (const_int 15) 14788 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))) 14789 (clobber (reg:CC FLAGS_REG))]) 14790 (parallel 14791 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15))) 14792 (clobber (reg:CC FLAGS_REG))])] 14793 "" 14794{ 14795 if (TARGET_ABM) 14796 { 14797 emit_insn (gen_clzhi2_abm (operands[0], operands[1])); 14798 DONE; 14799 } 14800}) 14801 14802(define_insn "clzhi2_abm" 14803 [(set (match_operand:HI 0 "register_operand" "=r") 14804 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))) 14805 (clobber (reg:CC FLAGS_REG))] 14806 "TARGET_ABM" 14807 "lzcnt{w}\t{%1, %0|%0, %1}" 14808 [(set_attr "prefix_rep" "1") 14809 (set_attr "type" "bitmanip") 14810 (set_attr "mode" "HI")]) 14811 14812(define_insn "*bsrhi" 14813 [(set (match_operand:HI 0 "register_operand" "=r") 14814 (minus:HI (const_int 15) 14815 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))) 14816 (clobber (reg:CC FLAGS_REG))] 14817 "" 14818 "bsr{w}\t{%1, %0|%0, %1}" 14819 [(set_attr "prefix_0f" "1") 14820 (set_attr "mode" "HI")]) 14821 14822(define_insn "popcounthi2" 14823 [(set (match_operand:HI 0 "register_operand" "=r") 14824 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" ""))) 14825 (clobber (reg:CC FLAGS_REG))] 14826 "TARGET_POPCNT" 14827 "popcnt{w}\t{%1, %0|%0, %1}" 14828 [(set_attr "prefix_rep" "1") 14829 (set_attr "type" "bitmanip") 14830 (set_attr "mode" "HI")]) 14831 14832(define_insn "*popcounthi2_cmp" 14833 [(set (reg FLAGS_REG) 14834 (compare 14835 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm")) 14836 (const_int 0))) 14837 (set (match_operand:HI 0 "register_operand" "=r") 14838 (popcount:HI (match_dup 1)))] 14839 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" 14840 "popcnt{w}\t{%1, %0|%0, %1}" 14841 [(set_attr "prefix_rep" "1") 14842 (set_attr "type" "bitmanip") 14843 (set_attr "mode" "HI")]) 14844 14845;; Thread-local storage patterns for ELF. 14846;; 14847;; Note that these code sequences must appear exactly as shown 14848;; in order to allow linker relaxation. 14849 14850(define_insn "*tls_global_dynamic_32_gnu" 14851 [(set (match_operand:SI 0 "register_operand" "=a") 14852 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14853 (match_operand:SI 2 "tls_symbolic_operand" "") 14854 (match_operand:SI 3 "call_insn_operand" "")] 14855 UNSPEC_TLS_GD)) 14856 (clobber (match_scratch:SI 4 "=d")) 14857 (clobber (match_scratch:SI 5 "=c")) 14858 (clobber (reg:CC FLAGS_REG))] 14859 "!TARGET_64BIT && TARGET_GNU_TLS" 14860 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3" 14861 [(set_attr "type" "multi") 14862 (set_attr "length" "12")]) 14863 14864(define_insn "*tls_global_dynamic_32_sun" 14865 [(set (match_operand:SI 0 "register_operand" "=a") 14866 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14867 (match_operand:SI 2 "tls_symbolic_operand" "") 14868 (match_operand:SI 3 "call_insn_operand" "")] 14869 UNSPEC_TLS_GD)) 14870 (clobber (match_scratch:SI 4 "=d")) 14871 (clobber (match_scratch:SI 5 "=c")) 14872 (clobber (reg:CC FLAGS_REG))] 14873 "!TARGET_64BIT && TARGET_SUN_TLS" 14874 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]} 14875 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop" 14876 [(set_attr "type" "multi") 14877 (set_attr "length" "14")]) 14878 14879(define_expand "tls_global_dynamic_32" 14880 [(parallel [(set (match_operand:SI 0 "register_operand" "") 14881 (unspec:SI 14882 [(match_dup 2) 14883 (match_operand:SI 1 "tls_symbolic_operand" "") 14884 (match_dup 3)] 14885 UNSPEC_TLS_GD)) 14886 (clobber (match_scratch:SI 4 "")) 14887 (clobber (match_scratch:SI 5 "")) 14888 (clobber (reg:CC FLAGS_REG))])] 14889 "" 14890{ 14891 if (flag_pic) 14892 operands[2] = pic_offset_table_rtx; 14893 else 14894 { 14895 operands[2] = gen_reg_rtx (Pmode); 14896 emit_insn (gen_set_got (operands[2])); 14897 } 14898 if (TARGET_GNU2_TLS) 14899 { 14900 emit_insn (gen_tls_dynamic_gnu2_32 14901 (operands[0], operands[1], operands[2])); 14902 DONE; 14903 } 14904 operands[3] = ix86_tls_get_addr (); 14905}) 14906 14907(define_insn "*tls_global_dynamic_64" 14908 [(set (match_operand:DI 0 "register_operand" "=a") 14909 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" "")) 14910 (match_operand:DI 3 "" ""))) 14911 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 14912 UNSPEC_TLS_GD)] 14913 "TARGET_64BIT" 14914 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2" 14915 [(set_attr "type" "multi") 14916 (set_attr "length" "16")]) 14917 14918(define_expand "tls_global_dynamic_64" 14919 [(parallel [(set (match_operand:DI 0 "register_operand" "") 14920 (call:DI (mem:QI (match_dup 2)) (const_int 0))) 14921 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 14922 UNSPEC_TLS_GD)])] 14923 "" 14924{ 14925 if (TARGET_GNU2_TLS) 14926 { 14927 emit_insn (gen_tls_dynamic_gnu2_64 14928 (operands[0], operands[1])); 14929 DONE; 14930 } 14931 operands[2] = ix86_tls_get_addr (); 14932}) 14933 14934(define_insn "*tls_local_dynamic_base_32_gnu" 14935 [(set (match_operand:SI 0 "register_operand" "=a") 14936 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14937 (match_operand:SI 2 "call_insn_operand" "")] 14938 UNSPEC_TLS_LD_BASE)) 14939 (clobber (match_scratch:SI 3 "=d")) 14940 (clobber (match_scratch:SI 4 "=c")) 14941 (clobber (reg:CC FLAGS_REG))] 14942 "!TARGET_64BIT && TARGET_GNU_TLS" 14943 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2" 14944 [(set_attr "type" "multi") 14945 (set_attr "length" "11")]) 14946 14947(define_insn "*tls_local_dynamic_base_32_sun" 14948 [(set (match_operand:SI 0 "register_operand" "=a") 14949 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14950 (match_operand:SI 2 "call_insn_operand" "")] 14951 UNSPEC_TLS_LD_BASE)) 14952 (clobber (match_scratch:SI 3 "=d")) 14953 (clobber (match_scratch:SI 4 "=c")) 14954 (clobber (reg:CC FLAGS_REG))] 14955 "!TARGET_64BIT && TARGET_SUN_TLS" 14956 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]} 14957 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3" 14958 [(set_attr "type" "multi") 14959 (set_attr "length" "13")]) 14960 14961(define_expand "tls_local_dynamic_base_32" 14962 [(parallel [(set (match_operand:SI 0 "register_operand" "") 14963 (unspec:SI [(match_dup 1) (match_dup 2)] 14964 UNSPEC_TLS_LD_BASE)) 14965 (clobber (match_scratch:SI 3 "")) 14966 (clobber (match_scratch:SI 4 "")) 14967 (clobber (reg:CC FLAGS_REG))])] 14968 "" 14969{ 14970 if (flag_pic) 14971 operands[1] = pic_offset_table_rtx; 14972 else 14973 { 14974 operands[1] = gen_reg_rtx (Pmode); 14975 emit_insn (gen_set_got (operands[1])); 14976 } 14977 if (TARGET_GNU2_TLS) 14978 { 14979 emit_insn (gen_tls_dynamic_gnu2_32 14980 (operands[0], ix86_tls_module_base (), operands[1])); 14981 DONE; 14982 } 14983 operands[2] = ix86_tls_get_addr (); 14984}) 14985 14986(define_insn "*tls_local_dynamic_base_64" 14987 [(set (match_operand:DI 0 "register_operand" "=a") 14988 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" "")) 14989 (match_operand:DI 2 "" ""))) 14990 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)] 14991 "TARGET_64BIT" 14992 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1" 14993 [(set_attr "type" "multi") 14994 (set_attr "length" "12")]) 14995 14996(define_expand "tls_local_dynamic_base_64" 14997 [(parallel [(set (match_operand:DI 0 "register_operand" "") 14998 (call:DI (mem:QI (match_dup 1)) (const_int 0))) 14999 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])] 15000 "" 15001{ 15002 if (TARGET_GNU2_TLS) 15003 { 15004 emit_insn (gen_tls_dynamic_gnu2_64 15005 (operands[0], ix86_tls_module_base ())); 15006 DONE; 15007 } 15008 operands[1] = ix86_tls_get_addr (); 15009}) 15010 15011;; Local dynamic of a single variable is a lose. Show combine how 15012;; to convert that back to global dynamic. 15013 15014(define_insn_and_split "*tls_local_dynamic_32_once" 15015 [(set (match_operand:SI 0 "register_operand" "=a") 15016 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b") 15017 (match_operand:SI 2 "call_insn_operand" "")] 15018 UNSPEC_TLS_LD_BASE) 15019 (const:SI (unspec:SI 15020 [(match_operand:SI 3 "tls_symbolic_operand" "")] 15021 UNSPEC_DTPOFF)))) 15022 (clobber (match_scratch:SI 4 "=d")) 15023 (clobber (match_scratch:SI 5 "=c")) 15024 (clobber (reg:CC FLAGS_REG))] 15025 "" 15026 "#" 15027 "" 15028 [(parallel [(set (match_dup 0) 15029 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)] 15030 UNSPEC_TLS_GD)) 15031 (clobber (match_dup 4)) 15032 (clobber (match_dup 5)) 15033 (clobber (reg:CC FLAGS_REG))])] 15034 "") 15035 15036;; Load and add the thread base pointer from %gs:0. 15037 15038(define_insn "*load_tp_si" 15039 [(set (match_operand:SI 0 "register_operand" "=r") 15040 (unspec:SI [(const_int 0)] UNSPEC_TP))] 15041 "!TARGET_64BIT" 15042 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}" 15043 [(set_attr "type" "imov") 15044 (set_attr "modrm" "0") 15045 (set_attr "length" "7") 15046 (set_attr "memory" "load") 15047 (set_attr "imm_disp" "false")]) 15048 15049(define_insn "*add_tp_si" 15050 [(set (match_operand:SI 0 "register_operand" "=r") 15051 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) 15052 (match_operand:SI 1 "register_operand" "0"))) 15053 (clobber (reg:CC FLAGS_REG))] 15054 "!TARGET_64BIT" 15055 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}" 15056 [(set_attr "type" "alu") 15057 (set_attr "modrm" "0") 15058 (set_attr "length" "7") 15059 (set_attr "memory" "load") 15060 (set_attr "imm_disp" "false")]) 15061 15062(define_insn "*load_tp_di" 15063 [(set (match_operand:DI 0 "register_operand" "=r") 15064 (unspec:DI [(const_int 0)] UNSPEC_TP))] 15065 "TARGET_64BIT" 15066 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}" 15067 [(set_attr "type" "imov") 15068 (set_attr "modrm" "0") 15069 (set_attr "length" "7") 15070 (set_attr "memory" "load") 15071 (set_attr "imm_disp" "false")]) 15072 15073(define_insn "*add_tp_di" 15074 [(set (match_operand:DI 0 "register_operand" "=r") 15075 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP) 15076 (match_operand:DI 1 "register_operand" "0"))) 15077 (clobber (reg:CC FLAGS_REG))] 15078 "TARGET_64BIT" 15079 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}" 15080 [(set_attr "type" "alu") 15081 (set_attr "modrm" "0") 15082 (set_attr "length" "7") 15083 (set_attr "memory" "load") 15084 (set_attr "imm_disp" "false")]) 15085 15086;; GNU2 TLS patterns can be split. 15087 15088(define_expand "tls_dynamic_gnu2_32" 15089 [(set (match_dup 3) 15090 (plus:SI (match_operand:SI 2 "register_operand" "") 15091 (const:SI 15092 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")] 15093 UNSPEC_TLSDESC)))) 15094 (parallel 15095 [(set (match_operand:SI 0 "register_operand" "") 15096 (unspec:SI [(match_dup 1) (match_dup 3) 15097 (match_dup 2) (reg:SI SP_REG)] 15098 UNSPEC_TLSDESC)) 15099 (clobber (reg:CC FLAGS_REG))])] 15100 "!TARGET_64BIT && TARGET_GNU2_TLS" 15101{ 15102 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); 15103 ix86_tls_descriptor_calls_expanded_in_cfun = true; 15104}) 15105 15106(define_insn "*tls_dynamic_lea_32" 15107 [(set (match_operand:SI 0 "register_operand" "=r") 15108 (plus:SI (match_operand:SI 1 "register_operand" "b") 15109 (const:SI 15110 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")] 15111 UNSPEC_TLSDESC))))] 15112 "!TARGET_64BIT && TARGET_GNU2_TLS" 15113 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}" 15114 [(set_attr "type" "lea") 15115 (set_attr "mode" "SI") 15116 (set_attr "length" "6") 15117 (set_attr "length_address" "4")]) 15118 15119(define_insn "*tls_dynamic_call_32" 15120 [(set (match_operand:SI 0 "register_operand" "=a") 15121 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "") 15122 (match_operand:SI 2 "register_operand" "0") 15123 ;; we have to make sure %ebx still points to the GOT 15124 (match_operand:SI 3 "register_operand" "b") 15125 (reg:SI SP_REG)] 15126 UNSPEC_TLSDESC)) 15127 (clobber (reg:CC FLAGS_REG))] 15128 "!TARGET_64BIT && TARGET_GNU2_TLS" 15129 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}" 15130 [(set_attr "type" "call") 15131 (set_attr "length" "2") 15132 (set_attr "length_address" "0")]) 15133 15134(define_insn_and_split "*tls_dynamic_gnu2_combine_32" 15135 [(set (match_operand:SI 0 "register_operand" "=&a") 15136 (plus:SI 15137 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "") 15138 (match_operand:SI 4 "" "") 15139 (match_operand:SI 2 "register_operand" "b") 15140 (reg:SI SP_REG)] 15141 UNSPEC_TLSDESC) 15142 (const:SI (unspec:SI 15143 [(match_operand:SI 1 "tls_symbolic_operand" "")] 15144 UNSPEC_DTPOFF)))) 15145 (clobber (reg:CC FLAGS_REG))] 15146 "!TARGET_64BIT && TARGET_GNU2_TLS" 15147 "#" 15148 "" 15149 [(set (match_dup 0) (match_dup 5))] 15150{ 15151 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); 15152 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2])); 15153}) 15154 15155(define_expand "tls_dynamic_gnu2_64" 15156 [(set (match_dup 2) 15157 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 15158 UNSPEC_TLSDESC)) 15159 (parallel 15160 [(set (match_operand:DI 0 "register_operand" "") 15161 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)] 15162 UNSPEC_TLSDESC)) 15163 (clobber (reg:CC FLAGS_REG))])] 15164 "TARGET_64BIT && TARGET_GNU2_TLS" 15165{ 15166 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); 15167 ix86_tls_descriptor_calls_expanded_in_cfun = true; 15168}) 15169 15170(define_insn "*tls_dynamic_lea_64" 15171 [(set (match_operand:DI 0 "register_operand" "=r") 15172 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 15173 UNSPEC_TLSDESC))] 15174 "TARGET_64BIT && TARGET_GNU2_TLS" 15175 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}" 15176 [(set_attr "type" "lea") 15177 (set_attr "mode" "DI") 15178 (set_attr "length" "7") 15179 (set_attr "length_address" "4")]) 15180 15181(define_insn "*tls_dynamic_call_64" 15182 [(set (match_operand:DI 0 "register_operand" "=a") 15183 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "") 15184 (match_operand:DI 2 "register_operand" "0") 15185 (reg:DI SP_REG)] 15186 UNSPEC_TLSDESC)) 15187 (clobber (reg:CC FLAGS_REG))] 15188 "TARGET_64BIT && TARGET_GNU2_TLS" 15189 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}" 15190 [(set_attr "type" "call") 15191 (set_attr "length" "2") 15192 (set_attr "length_address" "0")]) 15193 15194(define_insn_and_split "*tls_dynamic_gnu2_combine_64" 15195 [(set (match_operand:DI 0 "register_operand" "=&a") 15196 (plus:DI 15197 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "") 15198 (match_operand:DI 3 "" "") 15199 (reg:DI SP_REG)] 15200 UNSPEC_TLSDESC) 15201 (const:DI (unspec:DI 15202 [(match_operand:DI 1 "tls_symbolic_operand" "")] 15203 UNSPEC_DTPOFF)))) 15204 (clobber (reg:CC FLAGS_REG))] 15205 "TARGET_64BIT && TARGET_GNU2_TLS" 15206 "#" 15207 "" 15208 [(set (match_dup 0) (match_dup 4))] 15209{ 15210 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); 15211 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1])); 15212}) 15213 15214;; 15215 15216;; These patterns match the binary 387 instructions for addM3, subM3, 15217;; mulM3 and divM3. There are three patterns for each of DFmode and 15218;; SFmode. The first is the normal insn, the second the same insn but 15219;; with one operand a conversion, and the third the same insn but with 15220;; the other operand a conversion. The conversion may be SFmode or 15221;; SImode if the target mode DFmode, but only SImode if the target mode 15222;; is SFmode. 15223 15224;; Gcc is slightly more smart about handling normal two address instructions 15225;; so use special patterns for add and mull. 15226 15227(define_insn "*fop_sf_comm_mixed" 15228 [(set (match_operand:SF 0 "register_operand" "=f,x") 15229 (match_operator:SF 3 "binary_fp_operator" 15230 [(match_operand:SF 1 "nonimmediate_operand" "%0,0") 15231 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))] 15232 "TARGET_MIX_SSE_I387 15233 && COMMUTATIVE_ARITH_P (operands[3]) 15234 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15235 "* return output_387_binary_op (insn, operands);" 15236 [(set (attr "type") 15237 (if_then_else (eq_attr "alternative" "1") 15238 (if_then_else (match_operand:SF 3 "mult_operator" "") 15239 (const_string "ssemul") 15240 (const_string "sseadd")) 15241 (if_then_else (match_operand:SF 3 "mult_operator" "") 15242 (const_string "fmul") 15243 (const_string "fop")))) 15244 (set_attr "mode" "SF")]) 15245 15246(define_insn "*fop_sf_comm_sse" 15247 [(set (match_operand:SF 0 "register_operand" "=x") 15248 (match_operator:SF 3 "binary_fp_operator" 15249 [(match_operand:SF 1 "nonimmediate_operand" "%0") 15250 (match_operand:SF 2 "nonimmediate_operand" "xm")]))] 15251 "TARGET_SSE_MATH 15252 && COMMUTATIVE_ARITH_P (operands[3]) 15253 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15254 "* return output_387_binary_op (insn, operands);" 15255 [(set (attr "type") 15256 (if_then_else (match_operand:SF 3 "mult_operator" "") 15257 (const_string "ssemul") 15258 (const_string "sseadd"))) 15259 (set_attr "mode" "SF")]) 15260 15261(define_insn "*fop_sf_comm_i387" 15262 [(set (match_operand:SF 0 "register_operand" "=f") 15263 (match_operator:SF 3 "binary_fp_operator" 15264 [(match_operand:SF 1 "nonimmediate_operand" "%0") 15265 (match_operand:SF 2 "nonimmediate_operand" "fm")]))] 15266 "TARGET_80387 15267 && COMMUTATIVE_ARITH_P (operands[3]) 15268 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15269 "* return output_387_binary_op (insn, operands);" 15270 [(set (attr "type") 15271 (if_then_else (match_operand:SF 3 "mult_operator" "") 15272 (const_string "fmul") 15273 (const_string "fop"))) 15274 (set_attr "mode" "SF")]) 15275 15276(define_insn "*fop_sf_1_mixed" 15277 [(set (match_operand:SF 0 "register_operand" "=f,f,x") 15278 (match_operator:SF 3 "binary_fp_operator" 15279 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0") 15280 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))] 15281 "TARGET_MIX_SSE_I387 15282 && !COMMUTATIVE_ARITH_P (operands[3]) 15283 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15284 "* return output_387_binary_op (insn, operands);" 15285 [(set (attr "type") 15286 (cond [(and (eq_attr "alternative" "2") 15287 (match_operand:SF 3 "mult_operator" "")) 15288 (const_string "ssemul") 15289 (and (eq_attr "alternative" "2") 15290 (match_operand:SF 3 "div_operator" "")) 15291 (const_string "ssediv") 15292 (eq_attr "alternative" "2") 15293 (const_string "sseadd") 15294 (match_operand:SF 3 "mult_operator" "") 15295 (const_string "fmul") 15296 (match_operand:SF 3 "div_operator" "") 15297 (const_string "fdiv") 15298 ] 15299 (const_string "fop"))) 15300 (set_attr "mode" "SF")]) 15301 15302(define_insn "*fop_sf_1_sse" 15303 [(set (match_operand:SF 0 "register_operand" "=x") 15304 (match_operator:SF 3 "binary_fp_operator" 15305 [(match_operand:SF 1 "register_operand" "0") 15306 (match_operand:SF 2 "nonimmediate_operand" "xm")]))] 15307 "TARGET_SSE_MATH 15308 && !COMMUTATIVE_ARITH_P (operands[3])" 15309 "* return output_387_binary_op (insn, operands);" 15310 [(set (attr "type") 15311 (cond [(match_operand:SF 3 "mult_operator" "") 15312 (const_string "ssemul") 15313 (match_operand:SF 3 "div_operator" "") 15314 (const_string "ssediv") 15315 ] 15316 (const_string "sseadd"))) 15317 (set_attr "mode" "SF")]) 15318 15319;; This pattern is not fully shadowed by the pattern above. 15320(define_insn "*fop_sf_1_i387" 15321 [(set (match_operand:SF 0 "register_operand" "=f,f") 15322 (match_operator:SF 3 "binary_fp_operator" 15323 [(match_operand:SF 1 "nonimmediate_operand" "0,fm") 15324 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))] 15325 "TARGET_80387 && !TARGET_SSE_MATH 15326 && !COMMUTATIVE_ARITH_P (operands[3]) 15327 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15328 "* return output_387_binary_op (insn, operands);" 15329 [(set (attr "type") 15330 (cond [(match_operand:SF 3 "mult_operator" "") 15331 (const_string "fmul") 15332 (match_operand:SF 3 "div_operator" "") 15333 (const_string "fdiv") 15334 ] 15335 (const_string "fop"))) 15336 (set_attr "mode" "SF")]) 15337 15338;; ??? Add SSE splitters for these! 15339(define_insn "*fop_sf_2<mode>_i387" 15340 [(set (match_operand:SF 0 "register_operand" "=f,f") 15341 (match_operator:SF 3 "binary_fp_operator" 15342 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r")) 15343 (match_operand:SF 2 "register_operand" "0,0")]))] 15344 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH" 15345 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15346 [(set (attr "type") 15347 (cond [(match_operand:SF 3 "mult_operator" "") 15348 (const_string "fmul") 15349 (match_operand:SF 3 "div_operator" "") 15350 (const_string "fdiv") 15351 ] 15352 (const_string "fop"))) 15353 (set_attr "fp_int_src" "true") 15354 (set_attr "mode" "<MODE>")]) 15355 15356(define_insn "*fop_sf_3<mode>_i387" 15357 [(set (match_operand:SF 0 "register_operand" "=f,f") 15358 (match_operator:SF 3 "binary_fp_operator" 15359 [(match_operand:SF 1 "register_operand" "0,0") 15360 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))] 15361 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH" 15362 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15363 [(set (attr "type") 15364 (cond [(match_operand:SF 3 "mult_operator" "") 15365 (const_string "fmul") 15366 (match_operand:SF 3 "div_operator" "") 15367 (const_string "fdiv") 15368 ] 15369 (const_string "fop"))) 15370 (set_attr "fp_int_src" "true") 15371 (set_attr "mode" "<MODE>")]) 15372 15373(define_insn "*fop_df_comm_mixed" 15374 [(set (match_operand:DF 0 "register_operand" "=f,Y") 15375 (match_operator:DF 3 "binary_fp_operator" 15376 [(match_operand:DF 1 "nonimmediate_operand" "%0,0") 15377 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))] 15378 "TARGET_SSE2 && TARGET_MIX_SSE_I387 15379 && COMMUTATIVE_ARITH_P (operands[3]) 15380 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15381 "* return output_387_binary_op (insn, operands);" 15382 [(set (attr "type") 15383 (if_then_else (eq_attr "alternative" "1") 15384 (if_then_else (match_operand:DF 3 "mult_operator" "") 15385 (const_string "ssemul") 15386 (const_string "sseadd")) 15387 (if_then_else (match_operand:DF 3 "mult_operator" "") 15388 (const_string "fmul") 15389 (const_string "fop")))) 15390 (set_attr "mode" "DF")]) 15391 15392(define_insn "*fop_df_comm_sse" 15393 [(set (match_operand:DF 0 "register_operand" "=Y") 15394 (match_operator:DF 3 "binary_fp_operator" 15395 [(match_operand:DF 1 "nonimmediate_operand" "%0") 15396 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))] 15397 "TARGET_SSE2 && TARGET_SSE_MATH 15398 && COMMUTATIVE_ARITH_P (operands[3]) 15399 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15400 "* return output_387_binary_op (insn, operands);" 15401 [(set (attr "type") 15402 (if_then_else (match_operand:DF 3 "mult_operator" "") 15403 (const_string "ssemul") 15404 (const_string "sseadd"))) 15405 (set_attr "mode" "DF")]) 15406 15407(define_insn "*fop_df_comm_i387" 15408 [(set (match_operand:DF 0 "register_operand" "=f") 15409 (match_operator:DF 3 "binary_fp_operator" 15410 [(match_operand:DF 1 "nonimmediate_operand" "%0") 15411 (match_operand:DF 2 "nonimmediate_operand" "fm")]))] 15412 "TARGET_80387 15413 && COMMUTATIVE_ARITH_P (operands[3]) 15414 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15415 "* return output_387_binary_op (insn, operands);" 15416 [(set (attr "type") 15417 (if_then_else (match_operand:DF 3 "mult_operator" "") 15418 (const_string "fmul") 15419 (const_string "fop"))) 15420 (set_attr "mode" "DF")]) 15421 15422(define_insn "*fop_df_1_mixed" 15423 [(set (match_operand:DF 0 "register_operand" "=f,f,Y") 15424 (match_operator:DF 3 "binary_fp_operator" 15425 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0") 15426 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))] 15427 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387 15428 && !COMMUTATIVE_ARITH_P (operands[3]) 15429 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15430 "* return output_387_binary_op (insn, operands);" 15431 [(set (attr "type") 15432 (cond [(and (eq_attr "alternative" "2") 15433 (match_operand:DF 3 "mult_operator" "")) 15434 (const_string "ssemul") 15435 (and (eq_attr "alternative" "2") 15436 (match_operand:DF 3 "div_operator" "")) 15437 (const_string "ssediv") 15438 (eq_attr "alternative" "2") 15439 (const_string "sseadd") 15440 (match_operand:DF 3 "mult_operator" "") 15441 (const_string "fmul") 15442 (match_operand:DF 3 "div_operator" "") 15443 (const_string "fdiv") 15444 ] 15445 (const_string "fop"))) 15446 (set_attr "mode" "DF")]) 15447 15448(define_insn "*fop_df_1_sse" 15449 [(set (match_operand:DF 0 "register_operand" "=Y") 15450 (match_operator:DF 3 "binary_fp_operator" 15451 [(match_operand:DF 1 "register_operand" "0") 15452 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))] 15453 "TARGET_SSE2 && TARGET_SSE_MATH 15454 && !COMMUTATIVE_ARITH_P (operands[3])" 15455 "* return output_387_binary_op (insn, operands);" 15456 [(set_attr "mode" "DF") 15457 (set (attr "type") 15458 (cond [(match_operand:DF 3 "mult_operator" "") 15459 (const_string "ssemul") 15460 (match_operand:DF 3 "div_operator" "") 15461 (const_string "ssediv") 15462 ] 15463 (const_string "sseadd")))]) 15464 15465;; This pattern is not fully shadowed by the pattern above. 15466(define_insn "*fop_df_1_i387" 15467 [(set (match_operand:DF 0 "register_operand" "=f,f") 15468 (match_operator:DF 3 "binary_fp_operator" 15469 [(match_operand:DF 1 "nonimmediate_operand" "0,fm") 15470 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))] 15471 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH) 15472 && !COMMUTATIVE_ARITH_P (operands[3]) 15473 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15474 "* return output_387_binary_op (insn, operands);" 15475 [(set (attr "type") 15476 (cond [(match_operand:DF 3 "mult_operator" "") 15477 (const_string "fmul") 15478 (match_operand:DF 3 "div_operator" "") 15479 (const_string "fdiv") 15480 ] 15481 (const_string "fop"))) 15482 (set_attr "mode" "DF")]) 15483 15484;; ??? Add SSE splitters for these! 15485(define_insn "*fop_df_2<mode>_i387" 15486 [(set (match_operand:DF 0 "register_operand" "=f,f") 15487 (match_operator:DF 3 "binary_fp_operator" 15488 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r")) 15489 (match_operand:DF 2 "register_operand" "0,0")]))] 15490 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 15491 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15492 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15493 [(set (attr "type") 15494 (cond [(match_operand:DF 3 "mult_operator" "") 15495 (const_string "fmul") 15496 (match_operand:DF 3 "div_operator" "") 15497 (const_string "fdiv") 15498 ] 15499 (const_string "fop"))) 15500 (set_attr "fp_int_src" "true") 15501 (set_attr "mode" "<MODE>")]) 15502 15503(define_insn "*fop_df_3<mode>_i387" 15504 [(set (match_operand:DF 0 "register_operand" "=f,f") 15505 (match_operator:DF 3 "binary_fp_operator" 15506 [(match_operand:DF 1 "register_operand" "0,0") 15507 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))] 15508 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 15509 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15510 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15511 [(set (attr "type") 15512 (cond [(match_operand:DF 3 "mult_operator" "") 15513 (const_string "fmul") 15514 (match_operand:DF 3 "div_operator" "") 15515 (const_string "fdiv") 15516 ] 15517 (const_string "fop"))) 15518 (set_attr "fp_int_src" "true") 15519 (set_attr "mode" "<MODE>")]) 15520 15521(define_insn "*fop_df_4_i387" 15522 [(set (match_operand:DF 0 "register_operand" "=f,f") 15523 (match_operator:DF 3 "binary_fp_operator" 15524 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0")) 15525 (match_operand:DF 2 "register_operand" "0,f")]))] 15526 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH) 15527 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15528 "* return output_387_binary_op (insn, operands);" 15529 [(set (attr "type") 15530 (cond [(match_operand:DF 3 "mult_operator" "") 15531 (const_string "fmul") 15532 (match_operand:DF 3 "div_operator" "") 15533 (const_string "fdiv") 15534 ] 15535 (const_string "fop"))) 15536 (set_attr "mode" "SF")]) 15537 15538(define_insn "*fop_df_5_i387" 15539 [(set (match_operand:DF 0 "register_operand" "=f,f") 15540 (match_operator:DF 3 "binary_fp_operator" 15541 [(match_operand:DF 1 "register_operand" "0,f") 15542 (float_extend:DF 15543 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15544 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15545 "* return output_387_binary_op (insn, operands);" 15546 [(set (attr "type") 15547 (cond [(match_operand:DF 3 "mult_operator" "") 15548 (const_string "fmul") 15549 (match_operand:DF 3 "div_operator" "") 15550 (const_string "fdiv") 15551 ] 15552 (const_string "fop"))) 15553 (set_attr "mode" "SF")]) 15554 15555(define_insn "*fop_df_6_i387" 15556 [(set (match_operand:DF 0 "register_operand" "=f,f") 15557 (match_operator:DF 3 "binary_fp_operator" 15558 [(float_extend:DF 15559 (match_operand:SF 1 "register_operand" "0,f")) 15560 (float_extend:DF 15561 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15562 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15563 "* return output_387_binary_op (insn, operands);" 15564 [(set (attr "type") 15565 (cond [(match_operand:DF 3 "mult_operator" "") 15566 (const_string "fmul") 15567 (match_operand:DF 3 "div_operator" "") 15568 (const_string "fdiv") 15569 ] 15570 (const_string "fop"))) 15571 (set_attr "mode" "SF")]) 15572 15573(define_insn "*fop_xf_comm_i387" 15574 [(set (match_operand:XF 0 "register_operand" "=f") 15575 (match_operator:XF 3 "binary_fp_operator" 15576 [(match_operand:XF 1 "register_operand" "%0") 15577 (match_operand:XF 2 "register_operand" "f")]))] 15578 "TARGET_80387 15579 && COMMUTATIVE_ARITH_P (operands[3])" 15580 "* return output_387_binary_op (insn, operands);" 15581 [(set (attr "type") 15582 (if_then_else (match_operand:XF 3 "mult_operator" "") 15583 (const_string "fmul") 15584 (const_string "fop"))) 15585 (set_attr "mode" "XF")]) 15586 15587(define_insn "*fop_xf_1_i387" 15588 [(set (match_operand:XF 0 "register_operand" "=f,f") 15589 (match_operator:XF 3 "binary_fp_operator" 15590 [(match_operand:XF 1 "register_operand" "0,f") 15591 (match_operand:XF 2 "register_operand" "f,0")]))] 15592 "TARGET_80387 15593 && !COMMUTATIVE_ARITH_P (operands[3])" 15594 "* return output_387_binary_op (insn, operands);" 15595 [(set (attr "type") 15596 (cond [(match_operand:XF 3 "mult_operator" "") 15597 (const_string "fmul") 15598 (match_operand:XF 3 "div_operator" "") 15599 (const_string "fdiv") 15600 ] 15601 (const_string "fop"))) 15602 (set_attr "mode" "XF")]) 15603 15604(define_insn "*fop_xf_2<mode>_i387" 15605 [(set (match_operand:XF 0 "register_operand" "=f,f") 15606 (match_operator:XF 3 "binary_fp_operator" 15607 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r")) 15608 (match_operand:XF 2 "register_operand" "0,0")]))] 15609 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP" 15610 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15611 [(set (attr "type") 15612 (cond [(match_operand:XF 3 "mult_operator" "") 15613 (const_string "fmul") 15614 (match_operand:XF 3 "div_operator" "") 15615 (const_string "fdiv") 15616 ] 15617 (const_string "fop"))) 15618 (set_attr "fp_int_src" "true") 15619 (set_attr "mode" "<MODE>")]) 15620 15621(define_insn "*fop_xf_3<mode>_i387" 15622 [(set (match_operand:XF 0 "register_operand" "=f,f") 15623 (match_operator:XF 3 "binary_fp_operator" 15624 [(match_operand:XF 1 "register_operand" "0,0") 15625 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))] 15626 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP" 15627 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15628 [(set (attr "type") 15629 (cond [(match_operand:XF 3 "mult_operator" "") 15630 (const_string "fmul") 15631 (match_operand:XF 3 "div_operator" "") 15632 (const_string "fdiv") 15633 ] 15634 (const_string "fop"))) 15635 (set_attr "fp_int_src" "true") 15636 (set_attr "mode" "<MODE>")]) 15637 15638(define_insn "*fop_xf_4_i387" 15639 [(set (match_operand:XF 0 "register_operand" "=f,f") 15640 (match_operator:XF 3 "binary_fp_operator" 15641 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0")) 15642 (match_operand:XF 2 "register_operand" "0,f")]))] 15643 "TARGET_80387" 15644 "* return output_387_binary_op (insn, operands);" 15645 [(set (attr "type") 15646 (cond [(match_operand:XF 3 "mult_operator" "") 15647 (const_string "fmul") 15648 (match_operand:XF 3 "div_operator" "") 15649 (const_string "fdiv") 15650 ] 15651 (const_string "fop"))) 15652 (set_attr "mode" "SF")]) 15653 15654(define_insn "*fop_xf_5_i387" 15655 [(set (match_operand:XF 0 "register_operand" "=f,f") 15656 (match_operator:XF 3 "binary_fp_operator" 15657 [(match_operand:XF 1 "register_operand" "0,f") 15658 (float_extend:XF 15659 (match_operand 2 "nonimmediate_operand" "fm,0"))]))] 15660 "TARGET_80387" 15661 "* return output_387_binary_op (insn, operands);" 15662 [(set (attr "type") 15663 (cond [(match_operand:XF 3 "mult_operator" "") 15664 (const_string "fmul") 15665 (match_operand:XF 3 "div_operator" "") 15666 (const_string "fdiv") 15667 ] 15668 (const_string "fop"))) 15669 (set_attr "mode" "SF")]) 15670 15671(define_insn "*fop_xf_6_i387" 15672 [(set (match_operand:XF 0 "register_operand" "=f,f") 15673 (match_operator:XF 3 "binary_fp_operator" 15674 [(float_extend:XF 15675 (match_operand 1 "register_operand" "0,f")) 15676 (float_extend:XF 15677 (match_operand 2 "nonimmediate_operand" "fm,0"))]))] 15678 "TARGET_80387" 15679 "* return output_387_binary_op (insn, operands);" 15680 [(set (attr "type") 15681 (cond [(match_operand:XF 3 "mult_operator" "") 15682 (const_string "fmul") 15683 (match_operand:XF 3 "div_operator" "") 15684 (const_string "fdiv") 15685 ] 15686 (const_string "fop"))) 15687 (set_attr "mode" "SF")]) 15688 15689(define_split 15690 [(set (match_operand 0 "register_operand" "") 15691 (match_operator 3 "binary_fp_operator" 15692 [(float (match_operand:X87MODEI12 1 "register_operand" "")) 15693 (match_operand 2 "register_operand" "")]))] 15694 "TARGET_80387 && reload_completed 15695 && FLOAT_MODE_P (GET_MODE (operands[0]))" 15696 [(const_int 0)] 15697{ 15698 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]); 15699 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); 15700 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 15701 gen_rtx_fmt_ee (GET_CODE (operands[3]), 15702 GET_MODE (operands[3]), 15703 operands[4], 15704 operands[2]))); 15705 ix86_free_from_memory (GET_MODE (operands[1])); 15706 DONE; 15707}) 15708 15709(define_split 15710 [(set (match_operand 0 "register_operand" "") 15711 (match_operator 3 "binary_fp_operator" 15712 [(match_operand 1 "register_operand" "") 15713 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))] 15714 "TARGET_80387 && reload_completed 15715 && FLOAT_MODE_P (GET_MODE (operands[0]))" 15716 [(const_int 0)] 15717{ 15718 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); 15719 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); 15720 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 15721 gen_rtx_fmt_ee (GET_CODE (operands[3]), 15722 GET_MODE (operands[3]), 15723 operands[1], 15724 operands[4]))); 15725 ix86_free_from_memory (GET_MODE (operands[2])); 15726 DONE; 15727}) 15728 15729;; FPU special functions. 15730 15731(define_expand "sqrtsf2" 15732 [(set (match_operand:SF 0 "register_operand" "") 15733 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))] 15734 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH" 15735{ 15736 if (!TARGET_SSE_MATH) 15737 operands[1] = force_reg (SFmode, operands[1]); 15738}) 15739 15740(define_insn "*sqrtsf2_mixed" 15741 [(set (match_operand:SF 0 "register_operand" "=f,x") 15742 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))] 15743 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387" 15744 "@ 15745 fsqrt 15746 sqrtss\t{%1, %0|%0, %1}" 15747 [(set_attr "type" "fpspc,sse") 15748 (set_attr "mode" "SF,SF") 15749 (set_attr "athlon_decode" "direct,*")]) 15750 15751(define_insn "*sqrtsf2_sse" 15752 [(set (match_operand:SF 0 "register_operand" "=x") 15753 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))] 15754 "TARGET_SSE_MATH" 15755 "sqrtss\t{%1, %0|%0, %1}" 15756 [(set_attr "type" "sse") 15757 (set_attr "mode" "SF") 15758 (set_attr "athlon_decode" "*") 15759 (set_attr "amdfam10_decode" "*")]) 15760 15761(define_insn "*sqrtsf2_i387" 15762 [(set (match_operand:SF 0 "register_operand" "=f") 15763 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))] 15764 "TARGET_USE_FANCY_MATH_387" 15765 "fsqrt" 15766 [(set_attr "type" "fpspc") 15767 (set_attr "mode" "SF") 15768 (set_attr "athlon_decode" "direct")]) 15769 15770(define_expand "sqrtdf2" 15771 [(set (match_operand:DF 0 "register_operand" "") 15772 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))] 15773 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 15774{ 15775 if (!(TARGET_SSE2 && TARGET_SSE_MATH)) 15776 operands[1] = force_reg (DFmode, operands[1]); 15777}) 15778 15779(define_insn "*sqrtdf2_mixed" 15780 [(set (match_operand:DF 0 "register_operand" "=f,Y") 15781 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))] 15782 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387" 15783 "@ 15784 fsqrt 15785 sqrtsd\t{%1, %0|%0, %1}" 15786 [(set_attr "type" "fpspc,sse") 15787 (set_attr "mode" "DF,DF") 15788 (set_attr "athlon_decode" "direct,*")]) 15789 15790(define_insn "*sqrtdf2_sse" 15791 [(set (match_operand:DF 0 "register_operand" "=Y") 15792 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))] 15793 "TARGET_SSE2 && TARGET_SSE_MATH" 15794 "sqrtsd\t{%1, %0|%0, %1}" 15795 [(set_attr "type" "sse") 15796 (set_attr "mode" "DF") 15797 (set_attr "athlon_decode" "*") 15798 (set_attr "amdfam10_decode" "*")]) 15799 15800(define_insn "*sqrtdf2_i387" 15801 [(set (match_operand:DF 0 "register_operand" "=f") 15802 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))] 15803 "TARGET_USE_FANCY_MATH_387" 15804 "fsqrt" 15805 [(set_attr "type" "fpspc") 15806 (set_attr "mode" "DF") 15807 (set_attr "athlon_decode" "direct")]) 15808 15809(define_insn "*sqrtextendsfdf2_i387" 15810 [(set (match_operand:DF 0 "register_operand" "=f") 15811 (sqrt:DF (float_extend:DF 15812 (match_operand:SF 1 "register_operand" "0"))))] 15813 "TARGET_USE_FANCY_MATH_387 15814 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)" 15815 "fsqrt" 15816 [(set_attr "type" "fpspc") 15817 (set_attr "mode" "DF") 15818 (set_attr "athlon_decode" "direct")]) 15819 15820(define_insn "sqrtxf2" 15821 [(set (match_operand:XF 0 "register_operand" "=f") 15822 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] 15823 "TARGET_USE_FANCY_MATH_387" 15824 "fsqrt" 15825 [(set_attr "type" "fpspc") 15826 (set_attr "mode" "XF") 15827 (set_attr "athlon_decode" "direct") 15828 (set_attr "amdfam10_decode" "direct")]) 15829 15830(define_insn "*sqrtextendsfxf2_i387" 15831 [(set (match_operand:XF 0 "register_operand" "=f") 15832 (sqrt:XF (float_extend:XF 15833 (match_operand:SF 1 "register_operand" "0"))))] 15834 "TARGET_USE_FANCY_MATH_387" 15835 "fsqrt" 15836 [(set_attr "type" "fpspc") 15837 (set_attr "mode" "XF") 15838 (set_attr "athlon_decode" "direct")]) 15839 15840(define_insn "*sqrtextenddfxf2_i387" 15841 [(set (match_operand:XF 0 "register_operand" "=f") 15842 (sqrt:XF (float_extend:XF 15843 (match_operand:DF 1 "register_operand" "0"))))] 15844 "TARGET_USE_FANCY_MATH_387" 15845 "fsqrt" 15846 [(set_attr "type" "fpspc") 15847 (set_attr "mode" "XF") 15848 (set_attr "athlon_decode" "direct") 15849 (set_attr "amdfam10_decode" "direct")]) 15850 15851(define_insn "fpremxf4" 15852 [(set (match_operand:XF 0 "register_operand" "=f") 15853 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15854 (match_operand:XF 3 "register_operand" "1")] 15855 UNSPEC_FPREM_F)) 15856 (set (match_operand:XF 1 "register_operand" "=u") 15857 (unspec:XF [(match_dup 2) (match_dup 3)] 15858 UNSPEC_FPREM_U)) 15859 (set (reg:CCFP FPSR_REG) 15860 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))] 15861 "TARGET_USE_FANCY_MATH_387 15862 && flag_unsafe_math_optimizations" 15863 "fprem" 15864 [(set_attr "type" "fpspc") 15865 (set_attr "mode" "XF")]) 15866 15867(define_expand "fmodsf3" 15868 [(use (match_operand:SF 0 "register_operand" "")) 15869 (use (match_operand:SF 1 "register_operand" "")) 15870 (use (match_operand:SF 2 "register_operand" ""))] 15871 "TARGET_USE_FANCY_MATH_387 15872 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15873 && flag_unsafe_math_optimizations" 15874{ 15875 rtx label = gen_label_rtx (); 15876 15877 rtx op1 = gen_reg_rtx (XFmode); 15878 rtx op2 = gen_reg_rtx (XFmode); 15879 15880 emit_insn(gen_extendsfxf2 (op1, operands[1])); 15881 emit_insn(gen_extendsfxf2 (op2, operands[2])); 15882 15883 emit_label (label); 15884 15885 emit_insn (gen_fpremxf4 (op1, op2, op1, op2)); 15886 ix86_emit_fp_unordered_jump (label); 15887 15888 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1)); 15889 DONE; 15890}) 15891 15892(define_expand "fmoddf3" 15893 [(use (match_operand:DF 0 "register_operand" "")) 15894 (use (match_operand:DF 1 "register_operand" "")) 15895 (use (match_operand:DF 2 "register_operand" ""))] 15896 "TARGET_USE_FANCY_MATH_387 15897 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15898 && flag_unsafe_math_optimizations" 15899{ 15900 rtx label = gen_label_rtx (); 15901 15902 rtx op1 = gen_reg_rtx (XFmode); 15903 rtx op2 = gen_reg_rtx (XFmode); 15904 15905 emit_insn (gen_extenddfxf2 (op1, operands[1])); 15906 emit_insn (gen_extenddfxf2 (op2, operands[2])); 15907 15908 emit_label (label); 15909 15910 emit_insn (gen_fpremxf4 (op1, op2, op1, op2)); 15911 ix86_emit_fp_unordered_jump (label); 15912 15913 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1)); 15914 DONE; 15915}) 15916 15917(define_expand "fmodxf3" 15918 [(use (match_operand:XF 0 "register_operand" "")) 15919 (use (match_operand:XF 1 "register_operand" "")) 15920 (use (match_operand:XF 2 "register_operand" ""))] 15921 "TARGET_USE_FANCY_MATH_387 15922 && flag_unsafe_math_optimizations" 15923{ 15924 rtx label = gen_label_rtx (); 15925 15926 emit_label (label); 15927 15928 emit_insn (gen_fpremxf4 (operands[1], operands[2], 15929 operands[1], operands[2])); 15930 ix86_emit_fp_unordered_jump (label); 15931 15932 emit_move_insn (operands[0], operands[1]); 15933 DONE; 15934}) 15935 15936(define_insn "fprem1xf4" 15937 [(set (match_operand:XF 0 "register_operand" "=f") 15938 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15939 (match_operand:XF 3 "register_operand" "1")] 15940 UNSPEC_FPREM1_F)) 15941 (set (match_operand:XF 1 "register_operand" "=u") 15942 (unspec:XF [(match_dup 2) (match_dup 3)] 15943 UNSPEC_FPREM1_U)) 15944 (set (reg:CCFP FPSR_REG) 15945 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))] 15946 "TARGET_USE_FANCY_MATH_387 15947 && flag_unsafe_math_optimizations" 15948 "fprem1" 15949 [(set_attr "type" "fpspc") 15950 (set_attr "mode" "XF")]) 15951 15952(define_expand "dremsf3" 15953 [(use (match_operand:SF 0 "register_operand" "")) 15954 (use (match_operand:SF 1 "register_operand" "")) 15955 (use (match_operand:SF 2 "register_operand" ""))] 15956 "TARGET_USE_FANCY_MATH_387 15957 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15958 && flag_unsafe_math_optimizations" 15959{ 15960 rtx label = gen_label_rtx (); 15961 15962 rtx op1 = gen_reg_rtx (XFmode); 15963 rtx op2 = gen_reg_rtx (XFmode); 15964 15965 emit_insn(gen_extendsfxf2 (op1, operands[1])); 15966 emit_insn(gen_extendsfxf2 (op2, operands[2])); 15967 15968 emit_label (label); 15969 15970 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2)); 15971 ix86_emit_fp_unordered_jump (label); 15972 15973 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1)); 15974 DONE; 15975}) 15976 15977(define_expand "dremdf3" 15978 [(use (match_operand:DF 0 "register_operand" "")) 15979 (use (match_operand:DF 1 "register_operand" "")) 15980 (use (match_operand:DF 2 "register_operand" ""))] 15981 "TARGET_USE_FANCY_MATH_387 15982 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15983 && flag_unsafe_math_optimizations" 15984{ 15985 rtx label = gen_label_rtx (); 15986 15987 rtx op1 = gen_reg_rtx (XFmode); 15988 rtx op2 = gen_reg_rtx (XFmode); 15989 15990 emit_insn (gen_extenddfxf2 (op1, operands[1])); 15991 emit_insn (gen_extenddfxf2 (op2, operands[2])); 15992 15993 emit_label (label); 15994 15995 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2)); 15996 ix86_emit_fp_unordered_jump (label); 15997 15998 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1)); 15999 DONE; 16000}) 16001 16002(define_expand "dremxf3" 16003 [(use (match_operand:XF 0 "register_operand" "")) 16004 (use (match_operand:XF 1 "register_operand" "")) 16005 (use (match_operand:XF 2 "register_operand" ""))] 16006 "TARGET_USE_FANCY_MATH_387 16007 && flag_unsafe_math_optimizations" 16008{ 16009 rtx label = gen_label_rtx (); 16010 16011 emit_label (label); 16012 16013 emit_insn (gen_fprem1xf4 (operands[1], operands[2], 16014 operands[1], operands[2])); 16015 ix86_emit_fp_unordered_jump (label); 16016 16017 emit_move_insn (operands[0], operands[1]); 16018 DONE; 16019}) 16020 16021(define_insn "*sindf2" 16022 [(set (match_operand:DF 0 "register_operand" "=f") 16023 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))] 16024 "TARGET_USE_FANCY_MATH_387 16025 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16026 && flag_unsafe_math_optimizations" 16027 "fsin" 16028 [(set_attr "type" "fpspc") 16029 (set_attr "mode" "DF")]) 16030 16031(define_insn "*sinsf2" 16032 [(set (match_operand:SF 0 "register_operand" "=f") 16033 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))] 16034 "TARGET_USE_FANCY_MATH_387 16035 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16036 && flag_unsafe_math_optimizations" 16037 "fsin" 16038 [(set_attr "type" "fpspc") 16039 (set_attr "mode" "SF")]) 16040 16041(define_insn "*sinextendsfdf2" 16042 [(set (match_operand:DF 0 "register_operand" "=f") 16043 (unspec:DF [(float_extend:DF 16044 (match_operand:SF 1 "register_operand" "0"))] 16045 UNSPEC_SIN))] 16046 "TARGET_USE_FANCY_MATH_387 16047 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16048 && flag_unsafe_math_optimizations" 16049 "fsin" 16050 [(set_attr "type" "fpspc") 16051 (set_attr "mode" "DF")]) 16052 16053(define_insn "*sinxf2" 16054 [(set (match_operand:XF 0 "register_operand" "=f") 16055 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))] 16056 "TARGET_USE_FANCY_MATH_387 16057 && flag_unsafe_math_optimizations" 16058 "fsin" 16059 [(set_attr "type" "fpspc") 16060 (set_attr "mode" "XF")]) 16061 16062(define_insn "*cosdf2" 16063 [(set (match_operand:DF 0 "register_operand" "=f") 16064 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))] 16065 "TARGET_USE_FANCY_MATH_387 16066 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16067 && flag_unsafe_math_optimizations" 16068 "fcos" 16069 [(set_attr "type" "fpspc") 16070 (set_attr "mode" "DF")]) 16071 16072(define_insn "*cossf2" 16073 [(set (match_operand:SF 0 "register_operand" "=f") 16074 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))] 16075 "TARGET_USE_FANCY_MATH_387 16076 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16077 && flag_unsafe_math_optimizations" 16078 "fcos" 16079 [(set_attr "type" "fpspc") 16080 (set_attr "mode" "SF")]) 16081 16082(define_insn "*cosextendsfdf2" 16083 [(set (match_operand:DF 0 "register_operand" "=f") 16084 (unspec:DF [(float_extend:DF 16085 (match_operand:SF 1 "register_operand" "0"))] 16086 UNSPEC_COS))] 16087 "TARGET_USE_FANCY_MATH_387 16088 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16089 && flag_unsafe_math_optimizations" 16090 "fcos" 16091 [(set_attr "type" "fpspc") 16092 (set_attr "mode" "DF")]) 16093 16094(define_insn "*cosxf2" 16095 [(set (match_operand:XF 0 "register_operand" "=f") 16096 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))] 16097 "TARGET_USE_FANCY_MATH_387 16098 && flag_unsafe_math_optimizations" 16099 "fcos" 16100 [(set_attr "type" "fpspc") 16101 (set_attr "mode" "XF")]) 16102 16103;; With sincos pattern defined, sin and cos builtin function will be 16104;; expanded to sincos pattern with one of its outputs left unused. 16105;; Cse pass will detected, if two sincos patterns can be combined, 16106;; otherwise sincos pattern will be split back to sin or cos pattern, 16107;; depending on the unused output. 16108 16109(define_insn "sincosdf3" 16110 [(set (match_operand:DF 0 "register_operand" "=f") 16111 (unspec:DF [(match_operand:DF 2 "register_operand" "0")] 16112 UNSPEC_SINCOS_COS)) 16113 (set (match_operand:DF 1 "register_operand" "=u") 16114 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16115 "TARGET_USE_FANCY_MATH_387 16116 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16117 && flag_unsafe_math_optimizations" 16118 "fsincos" 16119 [(set_attr "type" "fpspc") 16120 (set_attr "mode" "DF")]) 16121 16122(define_split 16123 [(set (match_operand:DF 0 "register_operand" "") 16124 (unspec:DF [(match_operand:DF 2 "register_operand" "")] 16125 UNSPEC_SINCOS_COS)) 16126 (set (match_operand:DF 1 "register_operand" "") 16127 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16128 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 16129 && !reload_completed && !reload_in_progress" 16130 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))] 16131 "") 16132 16133(define_split 16134 [(set (match_operand:DF 0 "register_operand" "") 16135 (unspec:DF [(match_operand:DF 2 "register_operand" "")] 16136 UNSPEC_SINCOS_COS)) 16137 (set (match_operand:DF 1 "register_operand" "") 16138 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16139 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 16140 && !reload_completed && !reload_in_progress" 16141 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))] 16142 "") 16143 16144(define_insn "sincossf3" 16145 [(set (match_operand:SF 0 "register_operand" "=f") 16146 (unspec:SF [(match_operand:SF 2 "register_operand" "0")] 16147 UNSPEC_SINCOS_COS)) 16148 (set (match_operand:SF 1 "register_operand" "=u") 16149 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16150 "TARGET_USE_FANCY_MATH_387 16151 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16152 && flag_unsafe_math_optimizations" 16153 "fsincos" 16154 [(set_attr "type" "fpspc") 16155 (set_attr "mode" "SF")]) 16156 16157(define_split 16158 [(set (match_operand:SF 0 "register_operand" "") 16159 (unspec:SF [(match_operand:SF 2 "register_operand" "")] 16160 UNSPEC_SINCOS_COS)) 16161 (set (match_operand:SF 1 "register_operand" "") 16162 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16163 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 16164 && !reload_completed && !reload_in_progress" 16165 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))] 16166 "") 16167 16168(define_split 16169 [(set (match_operand:SF 0 "register_operand" "") 16170 (unspec:SF [(match_operand:SF 2 "register_operand" "")] 16171 UNSPEC_SINCOS_COS)) 16172 (set (match_operand:SF 1 "register_operand" "") 16173 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16174 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 16175 && !reload_completed && !reload_in_progress" 16176 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))] 16177 "") 16178 16179(define_insn "*sincosextendsfdf3" 16180 [(set (match_operand:DF 0 "register_operand" "=f") 16181 (unspec:DF [(float_extend:DF 16182 (match_operand:SF 2 "register_operand" "0"))] 16183 UNSPEC_SINCOS_COS)) 16184 (set (match_operand:DF 1 "register_operand" "=u") 16185 (unspec:DF [(float_extend:DF 16186 (match_dup 2))] UNSPEC_SINCOS_SIN))] 16187 "TARGET_USE_FANCY_MATH_387 16188 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16189 && flag_unsafe_math_optimizations" 16190 "fsincos" 16191 [(set_attr "type" "fpspc") 16192 (set_attr "mode" "DF")]) 16193 16194(define_split 16195 [(set (match_operand:DF 0 "register_operand" "") 16196 (unspec:DF [(float_extend:DF 16197 (match_operand:SF 2 "register_operand" ""))] 16198 UNSPEC_SINCOS_COS)) 16199 (set (match_operand:DF 1 "register_operand" "") 16200 (unspec:DF [(float_extend:DF 16201 (match_dup 2))] UNSPEC_SINCOS_SIN))] 16202 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 16203 && !reload_completed && !reload_in_progress" 16204 [(set (match_dup 1) (unspec:DF [(float_extend:DF 16205 (match_dup 2))] UNSPEC_SIN))] 16206 "") 16207 16208(define_split 16209 [(set (match_operand:DF 0 "register_operand" "") 16210 (unspec:DF [(float_extend:DF 16211 (match_operand:SF 2 "register_operand" ""))] 16212 UNSPEC_SINCOS_COS)) 16213 (set (match_operand:DF 1 "register_operand" "") 16214 (unspec:DF [(float_extend:DF 16215 (match_dup 2))] UNSPEC_SINCOS_SIN))] 16216 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 16217 && !reload_completed && !reload_in_progress" 16218 [(set (match_dup 0) (unspec:DF [(float_extend:DF 16219 (match_dup 2))] UNSPEC_COS))] 16220 "") 16221 16222(define_insn "sincosxf3" 16223 [(set (match_operand:XF 0 "register_operand" "=f") 16224 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 16225 UNSPEC_SINCOS_COS)) 16226 (set (match_operand:XF 1 "register_operand" "=u") 16227 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16228 "TARGET_USE_FANCY_MATH_387 16229 && flag_unsafe_math_optimizations" 16230 "fsincos" 16231 [(set_attr "type" "fpspc") 16232 (set_attr "mode" "XF")]) 16233 16234(define_split 16235 [(set (match_operand:XF 0 "register_operand" "") 16236 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 16237 UNSPEC_SINCOS_COS)) 16238 (set (match_operand:XF 1 "register_operand" "") 16239 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16240 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 16241 && !reload_completed && !reload_in_progress" 16242 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))] 16243 "") 16244 16245(define_split 16246 [(set (match_operand:XF 0 "register_operand" "") 16247 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 16248 UNSPEC_SINCOS_COS)) 16249 (set (match_operand:XF 1 "register_operand" "") 16250 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16251 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 16252 && !reload_completed && !reload_in_progress" 16253 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))] 16254 "") 16255 16256(define_insn "*tandf3_1" 16257 [(set (match_operand:DF 0 "register_operand" "=f") 16258 (unspec:DF [(match_operand:DF 2 "register_operand" "0")] 16259 UNSPEC_TAN_ONE)) 16260 (set (match_operand:DF 1 "register_operand" "=u") 16261 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))] 16262 "TARGET_USE_FANCY_MATH_387 16263 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16264 && flag_unsafe_math_optimizations" 16265 "fptan" 16266 [(set_attr "type" "fpspc") 16267 (set_attr "mode" "DF")]) 16268 16269;; optimize sequence: fptan 16270;; fstp %st(0) 16271;; fld1 16272;; into fptan insn. 16273 16274(define_peephole2 16275 [(parallel[(set (match_operand:DF 0 "register_operand" "") 16276 (unspec:DF [(match_operand:DF 2 "register_operand" "")] 16277 UNSPEC_TAN_ONE)) 16278 (set (match_operand:DF 1 "register_operand" "") 16279 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]) 16280 (set (match_dup 0) 16281 (match_operand:DF 3 "immediate_operand" ""))] 16282 "standard_80387_constant_p (operands[3]) == 2" 16283 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE)) 16284 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])] 16285 "") 16286 16287(define_expand "tandf2" 16288 [(parallel [(set (match_dup 2) 16289 (unspec:DF [(match_operand:DF 1 "register_operand" "")] 16290 UNSPEC_TAN_ONE)) 16291 (set (match_operand:DF 0 "register_operand" "") 16292 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])] 16293 "TARGET_USE_FANCY_MATH_387 16294 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16295 && flag_unsafe_math_optimizations" 16296{ 16297 operands[2] = gen_reg_rtx (DFmode); 16298}) 16299 16300(define_insn "*tansf3_1" 16301 [(set (match_operand:SF 0 "register_operand" "=f") 16302 (unspec:SF [(match_operand:SF 2 "register_operand" "0")] 16303 UNSPEC_TAN_ONE)) 16304 (set (match_operand:SF 1 "register_operand" "=u") 16305 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))] 16306 "TARGET_USE_FANCY_MATH_387 16307 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16308 && flag_unsafe_math_optimizations" 16309 "fptan" 16310 [(set_attr "type" "fpspc") 16311 (set_attr "mode" "SF")]) 16312 16313;; optimize sequence: fptan 16314;; fstp %st(0) 16315;; fld1 16316;; into fptan insn. 16317 16318(define_peephole2 16319 [(parallel[(set (match_operand:SF 0 "register_operand" "") 16320 (unspec:SF [(match_operand:SF 2 "register_operand" "")] 16321 UNSPEC_TAN_ONE)) 16322 (set (match_operand:SF 1 "register_operand" "") 16323 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]) 16324 (set (match_dup 0) 16325 (match_operand:SF 3 "immediate_operand" ""))] 16326 "standard_80387_constant_p (operands[3]) == 2" 16327 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE)) 16328 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])] 16329 "") 16330 16331(define_expand "tansf2" 16332 [(parallel [(set (match_dup 2) 16333 (unspec:SF [(match_operand:SF 1 "register_operand" "")] 16334 UNSPEC_TAN_ONE)) 16335 (set (match_operand:SF 0 "register_operand" "") 16336 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])] 16337 "TARGET_USE_FANCY_MATH_387 16338 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16339 && flag_unsafe_math_optimizations" 16340{ 16341 operands[2] = gen_reg_rtx (SFmode); 16342}) 16343 16344(define_insn "*tanxf3_1" 16345 [(set (match_operand:XF 0 "register_operand" "=f") 16346 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 16347 UNSPEC_TAN_ONE)) 16348 (set (match_operand:XF 1 "register_operand" "=u") 16349 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))] 16350 "TARGET_USE_FANCY_MATH_387 16351 && flag_unsafe_math_optimizations" 16352 "fptan" 16353 [(set_attr "type" "fpspc") 16354 (set_attr "mode" "XF")]) 16355 16356;; optimize sequence: fptan 16357;; fstp %st(0) 16358;; fld1 16359;; into fptan insn. 16360 16361(define_peephole2 16362 [(parallel[(set (match_operand:XF 0 "register_operand" "") 16363 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 16364 UNSPEC_TAN_ONE)) 16365 (set (match_operand:XF 1 "register_operand" "") 16366 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]) 16367 (set (match_dup 0) 16368 (match_operand:XF 3 "immediate_operand" ""))] 16369 "standard_80387_constant_p (operands[3]) == 2" 16370 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE)) 16371 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])] 16372 "") 16373 16374(define_expand "tanxf2" 16375 [(parallel [(set (match_dup 2) 16376 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 16377 UNSPEC_TAN_ONE)) 16378 (set (match_operand:XF 0 "register_operand" "") 16379 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])] 16380 "TARGET_USE_FANCY_MATH_387 16381 && flag_unsafe_math_optimizations" 16382{ 16383 operands[2] = gen_reg_rtx (XFmode); 16384}) 16385 16386(define_insn "atan2df3_1" 16387 [(set (match_operand:DF 0 "register_operand" "=f") 16388 (unspec:DF [(match_operand:DF 2 "register_operand" "0") 16389 (match_operand:DF 1 "register_operand" "u")] 16390 UNSPEC_FPATAN)) 16391 (clobber (match_scratch:DF 3 "=1"))] 16392 "TARGET_USE_FANCY_MATH_387 16393 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16394 && flag_unsafe_math_optimizations" 16395 "fpatan" 16396 [(set_attr "type" "fpspc") 16397 (set_attr "mode" "DF")]) 16398 16399(define_expand "atan2df3" 16400 [(use (match_operand:DF 0 "register_operand" "")) 16401 (use (match_operand:DF 2 "register_operand" "")) 16402 (use (match_operand:DF 1 "register_operand" ""))] 16403 "TARGET_USE_FANCY_MATH_387 16404 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16405 && flag_unsafe_math_optimizations" 16406{ 16407 rtx copy = gen_reg_rtx (DFmode); 16408 emit_move_insn (copy, operands[1]); 16409 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2])); 16410 DONE; 16411}) 16412 16413(define_expand "atandf2" 16414 [(parallel [(set (match_operand:DF 0 "register_operand" "") 16415 (unspec:DF [(match_dup 2) 16416 (match_operand:DF 1 "register_operand" "")] 16417 UNSPEC_FPATAN)) 16418 (clobber (match_scratch:DF 3 ""))])] 16419 "TARGET_USE_FANCY_MATH_387 16420 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16421 && flag_unsafe_math_optimizations" 16422{ 16423 operands[2] = gen_reg_rtx (DFmode); 16424 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */ 16425}) 16426 16427(define_insn "atan2sf3_1" 16428 [(set (match_operand:SF 0 "register_operand" "=f") 16429 (unspec:SF [(match_operand:SF 2 "register_operand" "0") 16430 (match_operand:SF 1 "register_operand" "u")] 16431 UNSPEC_FPATAN)) 16432 (clobber (match_scratch:SF 3 "=1"))] 16433 "TARGET_USE_FANCY_MATH_387 16434 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16435 && flag_unsafe_math_optimizations" 16436 "fpatan" 16437 [(set_attr "type" "fpspc") 16438 (set_attr "mode" "SF")]) 16439 16440(define_expand "atan2sf3" 16441 [(use (match_operand:SF 0 "register_operand" "")) 16442 (use (match_operand:SF 2 "register_operand" "")) 16443 (use (match_operand:SF 1 "register_operand" ""))] 16444 "TARGET_USE_FANCY_MATH_387 16445 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16446 && flag_unsafe_math_optimizations" 16447{ 16448 rtx copy = gen_reg_rtx (SFmode); 16449 emit_move_insn (copy, operands[1]); 16450 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2])); 16451 DONE; 16452}) 16453 16454(define_expand "atansf2" 16455 [(parallel [(set (match_operand:SF 0 "register_operand" "") 16456 (unspec:SF [(match_dup 2) 16457 (match_operand:SF 1 "register_operand" "")] 16458 UNSPEC_FPATAN)) 16459 (clobber (match_scratch:SF 3 ""))])] 16460 "TARGET_USE_FANCY_MATH_387 16461 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16462 && flag_unsafe_math_optimizations" 16463{ 16464 operands[2] = gen_reg_rtx (SFmode); 16465 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */ 16466}) 16467 16468(define_insn "atan2xf3_1" 16469 [(set (match_operand:XF 0 "register_operand" "=f") 16470 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16471 (match_operand:XF 1 "register_operand" "u")] 16472 UNSPEC_FPATAN)) 16473 (clobber (match_scratch:XF 3 "=1"))] 16474 "TARGET_USE_FANCY_MATH_387 16475 && flag_unsafe_math_optimizations" 16476 "fpatan" 16477 [(set_attr "type" "fpspc") 16478 (set_attr "mode" "XF")]) 16479 16480(define_expand "atan2xf3" 16481 [(use (match_operand:XF 0 "register_operand" "")) 16482 (use (match_operand:XF 2 "register_operand" "")) 16483 (use (match_operand:XF 1 "register_operand" ""))] 16484 "TARGET_USE_FANCY_MATH_387 16485 && flag_unsafe_math_optimizations" 16486{ 16487 rtx copy = gen_reg_rtx (XFmode); 16488 emit_move_insn (copy, operands[1]); 16489 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2])); 16490 DONE; 16491}) 16492 16493(define_expand "atanxf2" 16494 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16495 (unspec:XF [(match_dup 2) 16496 (match_operand:XF 1 "register_operand" "")] 16497 UNSPEC_FPATAN)) 16498 (clobber (match_scratch:XF 3 ""))])] 16499 "TARGET_USE_FANCY_MATH_387 16500 && flag_unsafe_math_optimizations" 16501{ 16502 operands[2] = gen_reg_rtx (XFmode); 16503 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 16504}) 16505 16506(define_expand "asindf2" 16507 [(set (match_dup 2) 16508 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16509 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16510 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16511 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16512 (parallel [(set (match_dup 7) 16513 (unspec:XF [(match_dup 6) (match_dup 2)] 16514 UNSPEC_FPATAN)) 16515 (clobber (match_scratch:XF 8 ""))]) 16516 (set (match_operand:DF 0 "register_operand" "") 16517 (float_truncate:DF (match_dup 7)))] 16518 "TARGET_USE_FANCY_MATH_387 16519 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16520 && flag_unsafe_math_optimizations" 16521{ 16522 int i; 16523 16524 for (i=2; i<8; i++) 16525 operands[i] = gen_reg_rtx (XFmode); 16526 16527 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16528}) 16529 16530(define_expand "asinsf2" 16531 [(set (match_dup 2) 16532 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16533 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16534 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16535 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16536 (parallel [(set (match_dup 7) 16537 (unspec:XF [(match_dup 6) (match_dup 2)] 16538 UNSPEC_FPATAN)) 16539 (clobber (match_scratch:XF 8 ""))]) 16540 (set (match_operand:SF 0 "register_operand" "") 16541 (float_truncate:SF (match_dup 7)))] 16542 "TARGET_USE_FANCY_MATH_387 16543 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16544 && flag_unsafe_math_optimizations" 16545{ 16546 int i; 16547 16548 for (i=2; i<8; i++) 16549 operands[i] = gen_reg_rtx (XFmode); 16550 16551 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16552}) 16553 16554(define_expand "asinxf2" 16555 [(set (match_dup 2) 16556 (mult:XF (match_operand:XF 1 "register_operand" "") 16557 (match_dup 1))) 16558 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 16559 (set (match_dup 5) (sqrt:XF (match_dup 4))) 16560 (parallel [(set (match_operand:XF 0 "register_operand" "") 16561 (unspec:XF [(match_dup 5) (match_dup 1)] 16562 UNSPEC_FPATAN)) 16563 (clobber (match_scratch:XF 6 ""))])] 16564 "TARGET_USE_FANCY_MATH_387 16565 && flag_unsafe_math_optimizations" 16566{ 16567 int i; 16568 16569 for (i=2; i<6; i++) 16570 operands[i] = gen_reg_rtx (XFmode); 16571 16572 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16573}) 16574 16575(define_expand "acosdf2" 16576 [(set (match_dup 2) 16577 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16578 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16579 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16580 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16581 (parallel [(set (match_dup 7) 16582 (unspec:XF [(match_dup 2) (match_dup 6)] 16583 UNSPEC_FPATAN)) 16584 (clobber (match_scratch:XF 8 ""))]) 16585 (set (match_operand:DF 0 "register_operand" "") 16586 (float_truncate:DF (match_dup 7)))] 16587 "TARGET_USE_FANCY_MATH_387 16588 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16589 && flag_unsafe_math_optimizations" 16590{ 16591 int i; 16592 16593 for (i=2; i<8; i++) 16594 operands[i] = gen_reg_rtx (XFmode); 16595 16596 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16597}) 16598 16599(define_expand "acossf2" 16600 [(set (match_dup 2) 16601 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16602 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16603 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16604 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16605 (parallel [(set (match_dup 7) 16606 (unspec:XF [(match_dup 2) (match_dup 6)] 16607 UNSPEC_FPATAN)) 16608 (clobber (match_scratch:XF 8 ""))]) 16609 (set (match_operand:SF 0 "register_operand" "") 16610 (float_truncate:SF (match_dup 7)))] 16611 "TARGET_USE_FANCY_MATH_387 16612 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16613 && flag_unsafe_math_optimizations" 16614{ 16615 int i; 16616 16617 for (i=2; i<8; i++) 16618 operands[i] = gen_reg_rtx (XFmode); 16619 16620 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16621}) 16622 16623(define_expand "acosxf2" 16624 [(set (match_dup 2) 16625 (mult:XF (match_operand:XF 1 "register_operand" "") 16626 (match_dup 1))) 16627 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 16628 (set (match_dup 5) (sqrt:XF (match_dup 4))) 16629 (parallel [(set (match_operand:XF 0 "register_operand" "") 16630 (unspec:XF [(match_dup 1) (match_dup 5)] 16631 UNSPEC_FPATAN)) 16632 (clobber (match_scratch:XF 6 ""))])] 16633 "TARGET_USE_FANCY_MATH_387 16634 && flag_unsafe_math_optimizations" 16635{ 16636 int i; 16637 16638 for (i=2; i<6; i++) 16639 operands[i] = gen_reg_rtx (XFmode); 16640 16641 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16642}) 16643 16644(define_insn "fyl2x_xf3" 16645 [(set (match_operand:XF 0 "register_operand" "=f") 16646 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16647 (match_operand:XF 1 "register_operand" "u")] 16648 UNSPEC_FYL2X)) 16649 (clobber (match_scratch:XF 3 "=1"))] 16650 "TARGET_USE_FANCY_MATH_387 16651 && flag_unsafe_math_optimizations" 16652 "fyl2x" 16653 [(set_attr "type" "fpspc") 16654 (set_attr "mode" "XF")]) 16655 16656(define_expand "logsf2" 16657 [(set (match_dup 2) 16658 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16659 (parallel [(set (match_dup 4) 16660 (unspec:XF [(match_dup 2) 16661 (match_dup 3)] UNSPEC_FYL2X)) 16662 (clobber (match_scratch:XF 5 ""))]) 16663 (set (match_operand:SF 0 "register_operand" "") 16664 (float_truncate:SF (match_dup 4)))] 16665 "TARGET_USE_FANCY_MATH_387 16666 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16667 && flag_unsafe_math_optimizations" 16668{ 16669 rtx temp; 16670 16671 operands[2] = gen_reg_rtx (XFmode); 16672 operands[3] = gen_reg_rtx (XFmode); 16673 operands[4] = gen_reg_rtx (XFmode); 16674 16675 temp = standard_80387_constant_rtx (4); /* fldln2 */ 16676 emit_move_insn (operands[3], temp); 16677}) 16678 16679(define_expand "logdf2" 16680 [(set (match_dup 2) 16681 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16682 (parallel [(set (match_dup 4) 16683 (unspec:XF [(match_dup 2) 16684 (match_dup 3)] UNSPEC_FYL2X)) 16685 (clobber (match_scratch:XF 5 ""))]) 16686 (set (match_operand:DF 0 "register_operand" "") 16687 (float_truncate:DF (match_dup 4)))] 16688 "TARGET_USE_FANCY_MATH_387 16689 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16690 && flag_unsafe_math_optimizations" 16691{ 16692 rtx temp; 16693 16694 operands[2] = gen_reg_rtx (XFmode); 16695 operands[3] = gen_reg_rtx (XFmode); 16696 operands[4] = gen_reg_rtx (XFmode); 16697 16698 temp = standard_80387_constant_rtx (4); /* fldln2 */ 16699 emit_move_insn (operands[3], temp); 16700}) 16701 16702(define_expand "logxf2" 16703 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16704 (unspec:XF [(match_operand:XF 1 "register_operand" "") 16705 (match_dup 2)] UNSPEC_FYL2X)) 16706 (clobber (match_scratch:XF 3 ""))])] 16707 "TARGET_USE_FANCY_MATH_387 16708 && flag_unsafe_math_optimizations" 16709{ 16710 rtx temp; 16711 16712 operands[2] = gen_reg_rtx (XFmode); 16713 temp = standard_80387_constant_rtx (4); /* fldln2 */ 16714 emit_move_insn (operands[2], temp); 16715}) 16716 16717(define_expand "log10sf2" 16718 [(set (match_dup 2) 16719 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16720 (parallel [(set (match_dup 4) 16721 (unspec:XF [(match_dup 2) 16722 (match_dup 3)] UNSPEC_FYL2X)) 16723 (clobber (match_scratch:XF 5 ""))]) 16724 (set (match_operand:SF 0 "register_operand" "") 16725 (float_truncate:SF (match_dup 4)))] 16726 "TARGET_USE_FANCY_MATH_387 16727 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16728 && flag_unsafe_math_optimizations" 16729{ 16730 rtx temp; 16731 16732 operands[2] = gen_reg_rtx (XFmode); 16733 operands[3] = gen_reg_rtx (XFmode); 16734 operands[4] = gen_reg_rtx (XFmode); 16735 16736 temp = standard_80387_constant_rtx (3); /* fldlg2 */ 16737 emit_move_insn (operands[3], temp); 16738}) 16739 16740(define_expand "log10df2" 16741 [(set (match_dup 2) 16742 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16743 (parallel [(set (match_dup 4) 16744 (unspec:XF [(match_dup 2) 16745 (match_dup 3)] UNSPEC_FYL2X)) 16746 (clobber (match_scratch:XF 5 ""))]) 16747 (set (match_operand:DF 0 "register_operand" "") 16748 (float_truncate:DF (match_dup 4)))] 16749 "TARGET_USE_FANCY_MATH_387 16750 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16751 && flag_unsafe_math_optimizations" 16752{ 16753 rtx temp; 16754 16755 operands[2] = gen_reg_rtx (XFmode); 16756 operands[3] = gen_reg_rtx (XFmode); 16757 operands[4] = gen_reg_rtx (XFmode); 16758 16759 temp = standard_80387_constant_rtx (3); /* fldlg2 */ 16760 emit_move_insn (operands[3], temp); 16761}) 16762 16763(define_expand "log10xf2" 16764 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16765 (unspec:XF [(match_operand:XF 1 "register_operand" "") 16766 (match_dup 2)] UNSPEC_FYL2X)) 16767 (clobber (match_scratch:XF 3 ""))])] 16768 "TARGET_USE_FANCY_MATH_387 16769 && flag_unsafe_math_optimizations" 16770{ 16771 rtx temp; 16772 16773 operands[2] = gen_reg_rtx (XFmode); 16774 temp = standard_80387_constant_rtx (3); /* fldlg2 */ 16775 emit_move_insn (operands[2], temp); 16776}) 16777 16778(define_expand "log2sf2" 16779 [(set (match_dup 2) 16780 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16781 (parallel [(set (match_dup 4) 16782 (unspec:XF [(match_dup 2) 16783 (match_dup 3)] UNSPEC_FYL2X)) 16784 (clobber (match_scratch:XF 5 ""))]) 16785 (set (match_operand:SF 0 "register_operand" "") 16786 (float_truncate:SF (match_dup 4)))] 16787 "TARGET_USE_FANCY_MATH_387 16788 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16789 && flag_unsafe_math_optimizations" 16790{ 16791 operands[2] = gen_reg_rtx (XFmode); 16792 operands[3] = gen_reg_rtx (XFmode); 16793 operands[4] = gen_reg_rtx (XFmode); 16794 16795 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16796}) 16797 16798(define_expand "log2df2" 16799 [(set (match_dup 2) 16800 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16801 (parallel [(set (match_dup 4) 16802 (unspec:XF [(match_dup 2) 16803 (match_dup 3)] UNSPEC_FYL2X)) 16804 (clobber (match_scratch:XF 5 ""))]) 16805 (set (match_operand:DF 0 "register_operand" "") 16806 (float_truncate:DF (match_dup 4)))] 16807 "TARGET_USE_FANCY_MATH_387 16808 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16809 && flag_unsafe_math_optimizations" 16810{ 16811 operands[2] = gen_reg_rtx (XFmode); 16812 operands[3] = gen_reg_rtx (XFmode); 16813 operands[4] = gen_reg_rtx (XFmode); 16814 16815 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16816}) 16817 16818(define_expand "log2xf2" 16819 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16820 (unspec:XF [(match_operand:XF 1 "register_operand" "") 16821 (match_dup 2)] UNSPEC_FYL2X)) 16822 (clobber (match_scratch:XF 3 ""))])] 16823 "TARGET_USE_FANCY_MATH_387 16824 && flag_unsafe_math_optimizations" 16825{ 16826 operands[2] = gen_reg_rtx (XFmode); 16827 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 16828}) 16829 16830(define_insn "fyl2xp1_xf3" 16831 [(set (match_operand:XF 0 "register_operand" "=f") 16832 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16833 (match_operand:XF 1 "register_operand" "u")] 16834 UNSPEC_FYL2XP1)) 16835 (clobber (match_scratch:XF 3 "=1"))] 16836 "TARGET_USE_FANCY_MATH_387 16837 && flag_unsafe_math_optimizations" 16838 "fyl2xp1" 16839 [(set_attr "type" "fpspc") 16840 (set_attr "mode" "XF")]) 16841 16842(define_expand "log1psf2" 16843 [(use (match_operand:SF 0 "register_operand" "")) 16844 (use (match_operand:SF 1 "register_operand" ""))] 16845 "TARGET_USE_FANCY_MATH_387 16846 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16847 && flag_unsafe_math_optimizations" 16848{ 16849 rtx op0 = gen_reg_rtx (XFmode); 16850 rtx op1 = gen_reg_rtx (XFmode); 16851 16852 emit_insn (gen_extendsfxf2 (op1, operands[1])); 16853 ix86_emit_i387_log1p (op0, op1); 16854 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 16855 DONE; 16856}) 16857 16858(define_expand "log1pdf2" 16859 [(use (match_operand:DF 0 "register_operand" "")) 16860 (use (match_operand:DF 1 "register_operand" ""))] 16861 "TARGET_USE_FANCY_MATH_387 16862 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16863 && flag_unsafe_math_optimizations" 16864{ 16865 rtx op0 = gen_reg_rtx (XFmode); 16866 rtx op1 = gen_reg_rtx (XFmode); 16867 16868 emit_insn (gen_extenddfxf2 (op1, operands[1])); 16869 ix86_emit_i387_log1p (op0, op1); 16870 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 16871 DONE; 16872}) 16873 16874(define_expand "log1pxf2" 16875 [(use (match_operand:XF 0 "register_operand" "")) 16876 (use (match_operand:XF 1 "register_operand" ""))] 16877 "TARGET_USE_FANCY_MATH_387 16878 && flag_unsafe_math_optimizations" 16879{ 16880 ix86_emit_i387_log1p (operands[0], operands[1]); 16881 DONE; 16882}) 16883 16884(define_insn "*fxtractxf3" 16885 [(set (match_operand:XF 0 "register_operand" "=f") 16886 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 16887 UNSPEC_XTRACT_FRACT)) 16888 (set (match_operand:XF 1 "register_operand" "=u") 16889 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))] 16890 "TARGET_USE_FANCY_MATH_387 16891 && flag_unsafe_math_optimizations" 16892 "fxtract" 16893 [(set_attr "type" "fpspc") 16894 (set_attr "mode" "XF")]) 16895 16896(define_expand "logbsf2" 16897 [(set (match_dup 2) 16898 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16899 (parallel [(set (match_dup 3) 16900 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT)) 16901 (set (match_dup 4) 16902 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]) 16903 (set (match_operand:SF 0 "register_operand" "") 16904 (float_truncate:SF (match_dup 4)))] 16905 "TARGET_USE_FANCY_MATH_387 16906 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16907 && flag_unsafe_math_optimizations" 16908{ 16909 operands[2] = gen_reg_rtx (XFmode); 16910 operands[3] = gen_reg_rtx (XFmode); 16911 operands[4] = gen_reg_rtx (XFmode); 16912}) 16913 16914(define_expand "logbdf2" 16915 [(set (match_dup 2) 16916 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16917 (parallel [(set (match_dup 3) 16918 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT)) 16919 (set (match_dup 4) 16920 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]) 16921 (set (match_operand:DF 0 "register_operand" "") 16922 (float_truncate:DF (match_dup 4)))] 16923 "TARGET_USE_FANCY_MATH_387 16924 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16925 && flag_unsafe_math_optimizations" 16926{ 16927 operands[2] = gen_reg_rtx (XFmode); 16928 operands[3] = gen_reg_rtx (XFmode); 16929 operands[4] = gen_reg_rtx (XFmode); 16930}) 16931 16932(define_expand "logbxf2" 16933 [(parallel [(set (match_dup 2) 16934 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 16935 UNSPEC_XTRACT_FRACT)) 16936 (set (match_operand:XF 0 "register_operand" "") 16937 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 16938 "TARGET_USE_FANCY_MATH_387 16939 && flag_unsafe_math_optimizations" 16940{ 16941 operands[2] = gen_reg_rtx (XFmode); 16942}) 16943 16944(define_expand "ilogbsi2" 16945 [(parallel [(set (match_dup 2) 16946 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 16947 UNSPEC_XTRACT_FRACT)) 16948 (set (match_operand:XF 3 "register_operand" "") 16949 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))]) 16950 (parallel [(set (match_operand:SI 0 "register_operand" "") 16951 (fix:SI (match_dup 3))) 16952 (clobber (reg:CC FLAGS_REG))])] 16953 "TARGET_USE_FANCY_MATH_387 16954 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16955 && flag_unsafe_math_optimizations" 16956{ 16957 operands[2] = gen_reg_rtx (XFmode); 16958 operands[3] = gen_reg_rtx (XFmode); 16959}) 16960 16961(define_insn "*f2xm1xf2" 16962 [(set (match_operand:XF 0 "register_operand" "=f") 16963 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16964 UNSPEC_F2XM1))] 16965 "TARGET_USE_FANCY_MATH_387 16966 && flag_unsafe_math_optimizations" 16967 "f2xm1" 16968 [(set_attr "type" "fpspc") 16969 (set_attr "mode" "XF")]) 16970 16971(define_insn "*fscalexf4" 16972 [(set (match_operand:XF 0 "register_operand" "=f") 16973 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16974 (match_operand:XF 3 "register_operand" "1")] 16975 UNSPEC_FSCALE_FRACT)) 16976 (set (match_operand:XF 1 "register_operand" "=u") 16977 (unspec:XF [(match_dup 2) (match_dup 3)] 16978 UNSPEC_FSCALE_EXP))] 16979 "TARGET_USE_FANCY_MATH_387 16980 && flag_unsafe_math_optimizations" 16981 "fscale" 16982 [(set_attr "type" "fpspc") 16983 (set_attr "mode" "XF")]) 16984 16985(define_expand "expsf2" 16986 [(set (match_dup 2) 16987 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16988 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16989 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16990 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16991 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16992 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 16993 (parallel [(set (match_dup 10) 16994 (unspec:XF [(match_dup 9) (match_dup 5)] 16995 UNSPEC_FSCALE_FRACT)) 16996 (set (match_dup 11) 16997 (unspec:XF [(match_dup 9) (match_dup 5)] 16998 UNSPEC_FSCALE_EXP))]) 16999 (set (match_operand:SF 0 "register_operand" "") 17000 (float_truncate:SF (match_dup 10)))] 17001 "TARGET_USE_FANCY_MATH_387 17002 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17003 && flag_unsafe_math_optimizations" 17004{ 17005 rtx temp; 17006 int i; 17007 17008 for (i=2; i<12; i++) 17009 operands[i] = gen_reg_rtx (XFmode); 17010 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17011 emit_move_insn (operands[3], temp); 17012 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 17013}) 17014 17015(define_expand "expdf2" 17016 [(set (match_dup 2) 17017 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 17018 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 17019 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 17020 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 17021 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 17022 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 17023 (parallel [(set (match_dup 10) 17024 (unspec:XF [(match_dup 9) (match_dup 5)] 17025 UNSPEC_FSCALE_FRACT)) 17026 (set (match_dup 11) 17027 (unspec:XF [(match_dup 9) (match_dup 5)] 17028 UNSPEC_FSCALE_EXP))]) 17029 (set (match_operand:DF 0 "register_operand" "") 17030 (float_truncate:DF (match_dup 10)))] 17031 "TARGET_USE_FANCY_MATH_387 17032 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17033 && flag_unsafe_math_optimizations" 17034{ 17035 rtx temp; 17036 int i; 17037 17038 for (i=2; i<12; i++) 17039 operands[i] = gen_reg_rtx (XFmode); 17040 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17041 emit_move_insn (operands[3], temp); 17042 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 17043}) 17044 17045(define_expand "expxf2" 17046 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 17047 (match_dup 2))) 17048 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 17049 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 17050 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 17051 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 17052 (parallel [(set (match_operand:XF 0 "register_operand" "") 17053 (unspec:XF [(match_dup 8) (match_dup 4)] 17054 UNSPEC_FSCALE_FRACT)) 17055 (set (match_dup 9) 17056 (unspec:XF [(match_dup 8) (match_dup 4)] 17057 UNSPEC_FSCALE_EXP))])] 17058 "TARGET_USE_FANCY_MATH_387 17059 && flag_unsafe_math_optimizations" 17060{ 17061 rtx temp; 17062 int i; 17063 17064 for (i=2; i<10; i++) 17065 operands[i] = gen_reg_rtx (XFmode); 17066 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17067 emit_move_insn (operands[2], temp); 17068 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ 17069}) 17070 17071(define_expand "exp10sf2" 17072 [(set (match_dup 2) 17073 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 17074 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 17075 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 17076 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 17077 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 17078 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 17079 (parallel [(set (match_dup 10) 17080 (unspec:XF [(match_dup 9) (match_dup 5)] 17081 UNSPEC_FSCALE_FRACT)) 17082 (set (match_dup 11) 17083 (unspec:XF [(match_dup 9) (match_dup 5)] 17084 UNSPEC_FSCALE_EXP))]) 17085 (set (match_operand:SF 0 "register_operand" "") 17086 (float_truncate:SF (match_dup 10)))] 17087 "TARGET_USE_FANCY_MATH_387 17088 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17089 && flag_unsafe_math_optimizations" 17090{ 17091 rtx temp; 17092 int i; 17093 17094 for (i=2; i<12; i++) 17095 operands[i] = gen_reg_rtx (XFmode); 17096 temp = standard_80387_constant_rtx (6); /* fldl2t */ 17097 emit_move_insn (operands[3], temp); 17098 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 17099}) 17100 17101(define_expand "exp10df2" 17102 [(set (match_dup 2) 17103 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 17104 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 17105 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 17106 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 17107 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 17108 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 17109 (parallel [(set (match_dup 10) 17110 (unspec:XF [(match_dup 9) (match_dup 5)] 17111 UNSPEC_FSCALE_FRACT)) 17112 (set (match_dup 11) 17113 (unspec:XF [(match_dup 9) (match_dup 5)] 17114 UNSPEC_FSCALE_EXP))]) 17115 (set (match_operand:DF 0 "register_operand" "") 17116 (float_truncate:DF (match_dup 10)))] 17117 "TARGET_USE_FANCY_MATH_387 17118 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17119 && flag_unsafe_math_optimizations" 17120{ 17121 rtx temp; 17122 int i; 17123 17124 for (i=2; i<12; i++) 17125 operands[i] = gen_reg_rtx (XFmode); 17126 temp = standard_80387_constant_rtx (6); /* fldl2t */ 17127 emit_move_insn (operands[3], temp); 17128 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 17129}) 17130 17131(define_expand "exp10xf2" 17132 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 17133 (match_dup 2))) 17134 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 17135 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 17136 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 17137 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 17138 (parallel [(set (match_operand:XF 0 "register_operand" "") 17139 (unspec:XF [(match_dup 8) (match_dup 4)] 17140 UNSPEC_FSCALE_FRACT)) 17141 (set (match_dup 9) 17142 (unspec:XF [(match_dup 8) (match_dup 4)] 17143 UNSPEC_FSCALE_EXP))])] 17144 "TARGET_USE_FANCY_MATH_387 17145 && flag_unsafe_math_optimizations" 17146{ 17147 rtx temp; 17148 int i; 17149 17150 for (i=2; i<10; i++) 17151 operands[i] = gen_reg_rtx (XFmode); 17152 temp = standard_80387_constant_rtx (6); /* fldl2t */ 17153 emit_move_insn (operands[2], temp); 17154 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ 17155}) 17156 17157(define_expand "exp2sf2" 17158 [(set (match_dup 2) 17159 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 17160 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT)) 17161 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3))) 17162 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1)) 17163 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6))) 17164 (parallel [(set (match_dup 8) 17165 (unspec:XF [(match_dup 7) (match_dup 3)] 17166 UNSPEC_FSCALE_FRACT)) 17167 (set (match_dup 9) 17168 (unspec:XF [(match_dup 7) (match_dup 3)] 17169 UNSPEC_FSCALE_EXP))]) 17170 (set (match_operand:SF 0 "register_operand" "") 17171 (float_truncate:SF (match_dup 8)))] 17172 "TARGET_USE_FANCY_MATH_387 17173 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17174 && flag_unsafe_math_optimizations" 17175{ 17176 int i; 17177 17178 for (i=2; i<10; i++) 17179 operands[i] = gen_reg_rtx (XFmode); 17180 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */ 17181}) 17182 17183(define_expand "exp2df2" 17184 [(set (match_dup 2) 17185 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 17186 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT)) 17187 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3))) 17188 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1)) 17189 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6))) 17190 (parallel [(set (match_dup 8) 17191 (unspec:XF [(match_dup 7) (match_dup 3)] 17192 UNSPEC_FSCALE_FRACT)) 17193 (set (match_dup 9) 17194 (unspec:XF [(match_dup 7) (match_dup 3)] 17195 UNSPEC_FSCALE_EXP))]) 17196 (set (match_operand:DF 0 "register_operand" "") 17197 (float_truncate:DF (match_dup 8)))] 17198 "TARGET_USE_FANCY_MATH_387 17199 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17200 && flag_unsafe_math_optimizations" 17201{ 17202 int i; 17203 17204 for (i=2; i<10; i++) 17205 operands[i] = gen_reg_rtx (XFmode); 17206 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */ 17207}) 17208 17209(define_expand "exp2xf2" 17210 [(set (match_dup 2) (match_operand:XF 1 "register_operand" "")) 17211 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT)) 17212 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3))) 17213 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1)) 17214 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6))) 17215 (parallel [(set (match_operand:XF 0 "register_operand" "") 17216 (unspec:XF [(match_dup 7) (match_dup 3)] 17217 UNSPEC_FSCALE_FRACT)) 17218 (set (match_dup 8) 17219 (unspec:XF [(match_dup 7) (match_dup 3)] 17220 UNSPEC_FSCALE_EXP))])] 17221 "TARGET_USE_FANCY_MATH_387 17222 && flag_unsafe_math_optimizations" 17223{ 17224 int i; 17225 17226 for (i=2; i<9; i++) 17227 operands[i] = gen_reg_rtx (XFmode); 17228 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */ 17229}) 17230 17231(define_expand "expm1df2" 17232 [(set (match_dup 2) 17233 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 17234 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 17235 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 17236 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 17237 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 17238 (parallel [(set (match_dup 8) 17239 (unspec:XF [(match_dup 7) (match_dup 5)] 17240 UNSPEC_FSCALE_FRACT)) 17241 (set (match_dup 9) 17242 (unspec:XF [(match_dup 7) (match_dup 5)] 17243 UNSPEC_FSCALE_EXP))]) 17244 (parallel [(set (match_dup 11) 17245 (unspec:XF [(match_dup 10) (match_dup 9)] 17246 UNSPEC_FSCALE_FRACT)) 17247 (set (match_dup 12) 17248 (unspec:XF [(match_dup 10) (match_dup 9)] 17249 UNSPEC_FSCALE_EXP))]) 17250 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10))) 17251 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8))) 17252 (set (match_operand:DF 0 "register_operand" "") 17253 (float_truncate:DF (match_dup 14)))] 17254 "TARGET_USE_FANCY_MATH_387 17255 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17256 && flag_unsafe_math_optimizations" 17257{ 17258 rtx temp; 17259 int i; 17260 17261 for (i=2; i<15; i++) 17262 operands[i] = gen_reg_rtx (XFmode); 17263 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17264 emit_move_insn (operands[3], temp); 17265 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */ 17266}) 17267 17268(define_expand "expm1sf2" 17269 [(set (match_dup 2) 17270 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 17271 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 17272 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 17273 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 17274 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 17275 (parallel [(set (match_dup 8) 17276 (unspec:XF [(match_dup 7) (match_dup 5)] 17277 UNSPEC_FSCALE_FRACT)) 17278 (set (match_dup 9) 17279 (unspec:XF [(match_dup 7) (match_dup 5)] 17280 UNSPEC_FSCALE_EXP))]) 17281 (parallel [(set (match_dup 11) 17282 (unspec:XF [(match_dup 10) (match_dup 9)] 17283 UNSPEC_FSCALE_FRACT)) 17284 (set (match_dup 12) 17285 (unspec:XF [(match_dup 10) (match_dup 9)] 17286 UNSPEC_FSCALE_EXP))]) 17287 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10))) 17288 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8))) 17289 (set (match_operand:SF 0 "register_operand" "") 17290 (float_truncate:SF (match_dup 14)))] 17291 "TARGET_USE_FANCY_MATH_387 17292 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17293 && flag_unsafe_math_optimizations" 17294{ 17295 rtx temp; 17296 int i; 17297 17298 for (i=2; i<15; i++) 17299 operands[i] = gen_reg_rtx (XFmode); 17300 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17301 emit_move_insn (operands[3], temp); 17302 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */ 17303}) 17304 17305(define_expand "expm1xf2" 17306 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 17307 (match_dup 2))) 17308 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 17309 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 17310 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 17311 (parallel [(set (match_dup 7) 17312 (unspec:XF [(match_dup 6) (match_dup 4)] 17313 UNSPEC_FSCALE_FRACT)) 17314 (set (match_dup 8) 17315 (unspec:XF [(match_dup 6) (match_dup 4)] 17316 UNSPEC_FSCALE_EXP))]) 17317 (parallel [(set (match_dup 10) 17318 (unspec:XF [(match_dup 9) (match_dup 8)] 17319 UNSPEC_FSCALE_FRACT)) 17320 (set (match_dup 11) 17321 (unspec:XF [(match_dup 9) (match_dup 8)] 17322 UNSPEC_FSCALE_EXP))]) 17323 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9))) 17324 (set (match_operand:XF 0 "register_operand" "") 17325 (plus:XF (match_dup 12) (match_dup 7)))] 17326 "TARGET_USE_FANCY_MATH_387 17327 && flag_unsafe_math_optimizations" 17328{ 17329 rtx temp; 17330 int i; 17331 17332 for (i=2; i<13; i++) 17333 operands[i] = gen_reg_rtx (XFmode); 17334 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17335 emit_move_insn (operands[2], temp); 17336 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */ 17337}) 17338 17339(define_expand "ldexpdf3" 17340 [(set (match_dup 3) 17341 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 17342 (set (match_dup 4) 17343 (float:XF (match_operand:SI 2 "register_operand" ""))) 17344 (parallel [(set (match_dup 5) 17345 (unspec:XF [(match_dup 3) (match_dup 4)] 17346 UNSPEC_FSCALE_FRACT)) 17347 (set (match_dup 6) 17348 (unspec:XF [(match_dup 3) (match_dup 4)] 17349 UNSPEC_FSCALE_EXP))]) 17350 (set (match_operand:DF 0 "register_operand" "") 17351 (float_truncate:DF (match_dup 5)))] 17352 "TARGET_USE_FANCY_MATH_387 17353 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17354 && flag_unsafe_math_optimizations" 17355{ 17356 int i; 17357 17358 for (i=3; i<7; i++) 17359 operands[i] = gen_reg_rtx (XFmode); 17360}) 17361 17362(define_expand "ldexpsf3" 17363 [(set (match_dup 3) 17364 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 17365 (set (match_dup 4) 17366 (float:XF (match_operand:SI 2 "register_operand" ""))) 17367 (parallel [(set (match_dup 5) 17368 (unspec:XF [(match_dup 3) (match_dup 4)] 17369 UNSPEC_FSCALE_FRACT)) 17370 (set (match_dup 6) 17371 (unspec:XF [(match_dup 3) (match_dup 4)] 17372 UNSPEC_FSCALE_EXP))]) 17373 (set (match_operand:SF 0 "register_operand" "") 17374 (float_truncate:SF (match_dup 5)))] 17375 "TARGET_USE_FANCY_MATH_387 17376 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17377 && flag_unsafe_math_optimizations" 17378{ 17379 int i; 17380 17381 for (i=3; i<7; i++) 17382 operands[i] = gen_reg_rtx (XFmode); 17383}) 17384 17385(define_expand "ldexpxf3" 17386 [(set (match_dup 3) 17387 (float:XF (match_operand:SI 2 "register_operand" ""))) 17388 (parallel [(set (match_operand:XF 0 " register_operand" "") 17389 (unspec:XF [(match_operand:XF 1 "register_operand" "") 17390 (match_dup 3)] 17391 UNSPEC_FSCALE_FRACT)) 17392 (set (match_dup 4) 17393 (unspec:XF [(match_dup 1) (match_dup 3)] 17394 UNSPEC_FSCALE_EXP))])] 17395 "TARGET_USE_FANCY_MATH_387 17396 && flag_unsafe_math_optimizations" 17397{ 17398 int i; 17399 17400 for (i=3; i<5; i++) 17401 operands[i] = gen_reg_rtx (XFmode); 17402}) 17403 17404 17405(define_insn "frndintxf2" 17406 [(set (match_operand:XF 0 "register_operand" "=f") 17407 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17408 UNSPEC_FRNDINT))] 17409 "TARGET_USE_FANCY_MATH_387 17410 && flag_unsafe_math_optimizations" 17411 "frndint" 17412 [(set_attr "type" "fpspc") 17413 (set_attr "mode" "XF")]) 17414 17415(define_expand "rintdf2" 17416 [(use (match_operand:DF 0 "register_operand" "")) 17417 (use (match_operand:DF 1 "register_operand" ""))] 17418 "TARGET_USE_FANCY_MATH_387 17419 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17420 && flag_unsafe_math_optimizations" 17421{ 17422 rtx op0 = gen_reg_rtx (XFmode); 17423 rtx op1 = gen_reg_rtx (XFmode); 17424 17425 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17426 emit_insn (gen_frndintxf2 (op0, op1)); 17427 17428 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17429 DONE; 17430}) 17431 17432(define_expand "rintsf2" 17433 [(use (match_operand:SF 0 "register_operand" "")) 17434 (use (match_operand:SF 1 "register_operand" ""))] 17435 "TARGET_USE_FANCY_MATH_387 17436 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17437 && flag_unsafe_math_optimizations" 17438{ 17439 rtx op0 = gen_reg_rtx (XFmode); 17440 rtx op1 = gen_reg_rtx (XFmode); 17441 17442 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17443 emit_insn (gen_frndintxf2 (op0, op1)); 17444 17445 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17446 DONE; 17447}) 17448 17449(define_expand "rintxf2" 17450 [(use (match_operand:XF 0 "register_operand" "")) 17451 (use (match_operand:XF 1 "register_operand" ""))] 17452 "TARGET_USE_FANCY_MATH_387 17453 && flag_unsafe_math_optimizations" 17454{ 17455 emit_insn (gen_frndintxf2 (operands[0], operands[1])); 17456 DONE; 17457}) 17458 17459(define_insn_and_split "*fistdi2_1" 17460 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17461 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17462 UNSPEC_FIST))] 17463 "TARGET_USE_FANCY_MATH_387 17464 && flag_unsafe_math_optimizations 17465 && !(reload_completed || reload_in_progress)" 17466 "#" 17467 "&& 1" 17468 [(const_int 0)] 17469{ 17470 if (memory_operand (operands[0], VOIDmode)) 17471 emit_insn (gen_fistdi2 (operands[0], operands[1])); 17472 else 17473 { 17474 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP); 17475 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1], 17476 operands[2])); 17477 } 17478 DONE; 17479} 17480 [(set_attr "type" "fpspc") 17481 (set_attr "mode" "DI")]) 17482 17483(define_insn "fistdi2" 17484 [(set (match_operand:DI 0 "memory_operand" "=m") 17485 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 17486 UNSPEC_FIST)) 17487 (clobber (match_scratch:XF 2 "=&1f"))] 17488 "TARGET_USE_FANCY_MATH_387 17489 && flag_unsafe_math_optimizations" 17490 "* return output_fix_trunc (insn, operands, 0);" 17491 [(set_attr "type" "fpspc") 17492 (set_attr "mode" "DI")]) 17493 17494(define_insn "fistdi2_with_temp" 17495 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17496 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17497 UNSPEC_FIST)) 17498 (clobber (match_operand:DI 2 "memory_operand" "=m,m")) 17499 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 17500 "TARGET_USE_FANCY_MATH_387 17501 && flag_unsafe_math_optimizations" 17502 "#" 17503 [(set_attr "type" "fpspc") 17504 (set_attr "mode" "DI")]) 17505 17506(define_split 17507 [(set (match_operand:DI 0 "register_operand" "") 17508 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17509 UNSPEC_FIST)) 17510 (clobber (match_operand:DI 2 "memory_operand" "")) 17511 (clobber (match_scratch 3 ""))] 17512 "reload_completed" 17513 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 17514 (clobber (match_dup 3))]) 17515 (set (match_dup 0) (match_dup 2))] 17516 "") 17517 17518(define_split 17519 [(set (match_operand:DI 0 "memory_operand" "") 17520 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17521 UNSPEC_FIST)) 17522 (clobber (match_operand:DI 2 "memory_operand" "")) 17523 (clobber (match_scratch 3 ""))] 17524 "reload_completed" 17525 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 17526 (clobber (match_dup 3))])] 17527 "") 17528 17529(define_insn_and_split "*fist<mode>2_1" 17530 [(set (match_operand:X87MODEI12 0 "register_operand" "=r") 17531 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17532 UNSPEC_FIST))] 17533 "TARGET_USE_FANCY_MATH_387 17534 && flag_unsafe_math_optimizations 17535 && !(reload_completed || reload_in_progress)" 17536 "#" 17537 "&& 1" 17538 [(const_int 0)] 17539{ 17540 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17541 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1], 17542 operands[2])); 17543 DONE; 17544} 17545 [(set_attr "type" "fpspc") 17546 (set_attr "mode" "<MODE>")]) 17547 17548(define_insn "fist<mode>2" 17549 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 17550 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17551 UNSPEC_FIST))] 17552 "TARGET_USE_FANCY_MATH_387 17553 && flag_unsafe_math_optimizations" 17554 "* return output_fix_trunc (insn, operands, 0);" 17555 [(set_attr "type" "fpspc") 17556 (set_attr "mode" "<MODE>")]) 17557 17558(define_insn "fist<mode>2_with_temp" 17559 [(set (match_operand:X87MODEI12 0 "register_operand" "=r") 17560 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17561 UNSPEC_FIST)) 17562 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))] 17563 "TARGET_USE_FANCY_MATH_387 17564 && flag_unsafe_math_optimizations" 17565 "#" 17566 [(set_attr "type" "fpspc") 17567 (set_attr "mode" "<MODE>")]) 17568 17569(define_split 17570 [(set (match_operand:X87MODEI12 0 "register_operand" "") 17571 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17572 UNSPEC_FIST)) 17573 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))] 17574 "reload_completed" 17575 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] 17576 UNSPEC_FIST)) 17577 (set (match_dup 0) (match_dup 2))] 17578 "") 17579 17580(define_split 17581 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 17582 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17583 UNSPEC_FIST)) 17584 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))] 17585 "reload_completed" 17586 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] 17587 UNSPEC_FIST))] 17588 "") 17589 17590(define_expand "lrint<mode>2" 17591 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") 17592 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] 17593 UNSPEC_FIST))] 17594 "TARGET_USE_FANCY_MATH_387 17595 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17596 && flag_unsafe_math_optimizations" 17597 "") 17598 17599;; Rounding mode control word calculation could clobber FLAGS_REG. 17600(define_insn_and_split "frndintxf2_floor" 17601 [(set (match_operand:XF 0 "register_operand" "=f") 17602 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17603 UNSPEC_FRNDINT_FLOOR)) 17604 (clobber (reg:CC FLAGS_REG))] 17605 "TARGET_USE_FANCY_MATH_387 17606 && flag_unsafe_math_optimizations 17607 && !(reload_completed || reload_in_progress)" 17608 "#" 17609 "&& 1" 17610 [(const_int 0)] 17611{ 17612 ix86_optimize_mode_switching[I387_FLOOR] = 1; 17613 17614 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17615 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); 17616 17617 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1], 17618 operands[2], operands[3])); 17619 DONE; 17620} 17621 [(set_attr "type" "frndint") 17622 (set_attr "i387_cw" "floor") 17623 (set_attr "mode" "XF")]) 17624 17625(define_insn "frndintxf2_floor_i387" 17626 [(set (match_operand:XF 0 "register_operand" "=f") 17627 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17628 UNSPEC_FRNDINT_FLOOR)) 17629 (use (match_operand:HI 2 "memory_operand" "m")) 17630 (use (match_operand:HI 3 "memory_operand" "m"))] 17631 "TARGET_USE_FANCY_MATH_387 17632 && flag_unsafe_math_optimizations" 17633 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 17634 [(set_attr "type" "frndint") 17635 (set_attr "i387_cw" "floor") 17636 (set_attr "mode" "XF")]) 17637 17638(define_expand "floorxf2" 17639 [(use (match_operand:XF 0 "register_operand" "")) 17640 (use (match_operand:XF 1 "register_operand" ""))] 17641 "TARGET_USE_FANCY_MATH_387 17642 && flag_unsafe_math_optimizations" 17643{ 17644 emit_insn (gen_frndintxf2_floor (operands[0], operands[1])); 17645 DONE; 17646}) 17647 17648(define_expand "floordf2" 17649 [(use (match_operand:DF 0 "register_operand" "")) 17650 (use (match_operand:DF 1 "register_operand" ""))] 17651 "TARGET_USE_FANCY_MATH_387 17652 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17653 && flag_unsafe_math_optimizations" 17654{ 17655 rtx op0 = gen_reg_rtx (XFmode); 17656 rtx op1 = gen_reg_rtx (XFmode); 17657 17658 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17659 emit_insn (gen_frndintxf2_floor (op0, op1)); 17660 17661 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17662 DONE; 17663}) 17664 17665(define_expand "floorsf2" 17666 [(use (match_operand:SF 0 "register_operand" "")) 17667 (use (match_operand:SF 1 "register_operand" ""))] 17668 "TARGET_USE_FANCY_MATH_387 17669 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17670 && flag_unsafe_math_optimizations" 17671{ 17672 rtx op0 = gen_reg_rtx (XFmode); 17673 rtx op1 = gen_reg_rtx (XFmode); 17674 17675 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17676 emit_insn (gen_frndintxf2_floor (op0, op1)); 17677 17678 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17679 DONE; 17680}) 17681 17682(define_insn_and_split "*fist<mode>2_floor_1" 17683 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 17684 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")] 17685 UNSPEC_FIST_FLOOR)) 17686 (clobber (reg:CC FLAGS_REG))] 17687 "TARGET_USE_FANCY_MATH_387 17688 && flag_unsafe_math_optimizations 17689 && !(reload_completed || reload_in_progress)" 17690 "#" 17691 "&& 1" 17692 [(const_int 0)] 17693{ 17694 ix86_optimize_mode_switching[I387_FLOOR] = 1; 17695 17696 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17697 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); 17698 if (memory_operand (operands[0], VOIDmode)) 17699 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1], 17700 operands[2], operands[3])); 17701 else 17702 { 17703 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17704 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1], 17705 operands[2], operands[3], 17706 operands[4])); 17707 } 17708 DONE; 17709} 17710 [(set_attr "type" "fistp") 17711 (set_attr "i387_cw" "floor") 17712 (set_attr "mode" "<MODE>")]) 17713 17714(define_insn "fistdi2_floor" 17715 [(set (match_operand:DI 0 "memory_operand" "=m") 17716 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 17717 UNSPEC_FIST_FLOOR)) 17718 (use (match_operand:HI 2 "memory_operand" "m")) 17719 (use (match_operand:HI 3 "memory_operand" "m")) 17720 (clobber (match_scratch:XF 4 "=&1f"))] 17721 "TARGET_USE_FANCY_MATH_387 17722 && flag_unsafe_math_optimizations" 17723 "* return output_fix_trunc (insn, operands, 0);" 17724 [(set_attr "type" "fistp") 17725 (set_attr "i387_cw" "floor") 17726 (set_attr "mode" "DI")]) 17727 17728(define_insn "fistdi2_floor_with_temp" 17729 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17730 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17731 UNSPEC_FIST_FLOOR)) 17732 (use (match_operand:HI 2 "memory_operand" "m,m")) 17733 (use (match_operand:HI 3 "memory_operand" "m,m")) 17734 (clobber (match_operand:DI 4 "memory_operand" "=m,m")) 17735 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 17736 "TARGET_USE_FANCY_MATH_387 17737 && flag_unsafe_math_optimizations" 17738 "#" 17739 [(set_attr "type" "fistp") 17740 (set_attr "i387_cw" "floor") 17741 (set_attr "mode" "DI")]) 17742 17743(define_split 17744 [(set (match_operand:DI 0 "register_operand" "") 17745 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17746 UNSPEC_FIST_FLOOR)) 17747 (use (match_operand:HI 2 "memory_operand" "")) 17748 (use (match_operand:HI 3 "memory_operand" "")) 17749 (clobber (match_operand:DI 4 "memory_operand" "")) 17750 (clobber (match_scratch 5 ""))] 17751 "reload_completed" 17752 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) 17753 (use (match_dup 2)) 17754 (use (match_dup 3)) 17755 (clobber (match_dup 5))]) 17756 (set (match_dup 0) (match_dup 4))] 17757 "") 17758 17759(define_split 17760 [(set (match_operand:DI 0 "memory_operand" "") 17761 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17762 UNSPEC_FIST_FLOOR)) 17763 (use (match_operand:HI 2 "memory_operand" "")) 17764 (use (match_operand:HI 3 "memory_operand" "")) 17765 (clobber (match_operand:DI 4 "memory_operand" "")) 17766 (clobber (match_scratch 5 ""))] 17767 "reload_completed" 17768 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) 17769 (use (match_dup 2)) 17770 (use (match_dup 3)) 17771 (clobber (match_dup 5))])] 17772 "") 17773 17774(define_insn "fist<mode>2_floor" 17775 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 17776 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17777 UNSPEC_FIST_FLOOR)) 17778 (use (match_operand:HI 2 "memory_operand" "m")) 17779 (use (match_operand:HI 3 "memory_operand" "m"))] 17780 "TARGET_USE_FANCY_MATH_387 17781 && flag_unsafe_math_optimizations" 17782 "* return output_fix_trunc (insn, operands, 0);" 17783 [(set_attr "type" "fistp") 17784 (set_attr "i387_cw" "floor") 17785 (set_attr "mode" "<MODE>")]) 17786 17787(define_insn "fist<mode>2_floor_with_temp" 17788 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") 17789 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")] 17790 UNSPEC_FIST_FLOOR)) 17791 (use (match_operand:HI 2 "memory_operand" "m,m")) 17792 (use (match_operand:HI 3 "memory_operand" "m,m")) 17793 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))] 17794 "TARGET_USE_FANCY_MATH_387 17795 && flag_unsafe_math_optimizations" 17796 "#" 17797 [(set_attr "type" "fistp") 17798 (set_attr "i387_cw" "floor") 17799 (set_attr "mode" "<MODE>")]) 17800 17801(define_split 17802 [(set (match_operand:X87MODEI12 0 "register_operand" "") 17803 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17804 UNSPEC_FIST_FLOOR)) 17805 (use (match_operand:HI 2 "memory_operand" "")) 17806 (use (match_operand:HI 3 "memory_operand" "")) 17807 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 17808 "reload_completed" 17809 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)] 17810 UNSPEC_FIST_FLOOR)) 17811 (use (match_dup 2)) 17812 (use (match_dup 3))]) 17813 (set (match_dup 0) (match_dup 4))] 17814 "") 17815 17816(define_split 17817 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 17818 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17819 UNSPEC_FIST_FLOOR)) 17820 (use (match_operand:HI 2 "memory_operand" "")) 17821 (use (match_operand:HI 3 "memory_operand" "")) 17822 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 17823 "reload_completed" 17824 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] 17825 UNSPEC_FIST_FLOOR)) 17826 (use (match_dup 2)) 17827 (use (match_dup 3))])] 17828 "") 17829 17830(define_expand "lfloor<mode>2" 17831 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") 17832 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] 17833 UNSPEC_FIST_FLOOR)) 17834 (clobber (reg:CC FLAGS_REG))])] 17835 "TARGET_USE_FANCY_MATH_387 17836 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17837 && flag_unsafe_math_optimizations" 17838 "") 17839 17840;; Rounding mode control word calculation could clobber FLAGS_REG. 17841(define_insn_and_split "frndintxf2_ceil" 17842 [(set (match_operand:XF 0 "register_operand" "=f") 17843 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17844 UNSPEC_FRNDINT_CEIL)) 17845 (clobber (reg:CC FLAGS_REG))] 17846 "TARGET_USE_FANCY_MATH_387 17847 && flag_unsafe_math_optimizations 17848 && !(reload_completed || reload_in_progress)" 17849 "#" 17850 "&& 1" 17851 [(const_int 0)] 17852{ 17853 ix86_optimize_mode_switching[I387_CEIL] = 1; 17854 17855 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17856 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); 17857 17858 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1], 17859 operands[2], operands[3])); 17860 DONE; 17861} 17862 [(set_attr "type" "frndint") 17863 (set_attr "i387_cw" "ceil") 17864 (set_attr "mode" "XF")]) 17865 17866(define_insn "frndintxf2_ceil_i387" 17867 [(set (match_operand:XF 0 "register_operand" "=f") 17868 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17869 UNSPEC_FRNDINT_CEIL)) 17870 (use (match_operand:HI 2 "memory_operand" "m")) 17871 (use (match_operand:HI 3 "memory_operand" "m"))] 17872 "TARGET_USE_FANCY_MATH_387 17873 && flag_unsafe_math_optimizations" 17874 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 17875 [(set_attr "type" "frndint") 17876 (set_attr "i387_cw" "ceil") 17877 (set_attr "mode" "XF")]) 17878 17879(define_expand "ceilxf2" 17880 [(use (match_operand:XF 0 "register_operand" "")) 17881 (use (match_operand:XF 1 "register_operand" ""))] 17882 "TARGET_USE_FANCY_MATH_387 17883 && flag_unsafe_math_optimizations" 17884{ 17885 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1])); 17886 DONE; 17887}) 17888 17889(define_expand "ceildf2" 17890 [(use (match_operand:DF 0 "register_operand" "")) 17891 (use (match_operand:DF 1 "register_operand" ""))] 17892 "TARGET_USE_FANCY_MATH_387 17893 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17894 && flag_unsafe_math_optimizations" 17895{ 17896 rtx op0 = gen_reg_rtx (XFmode); 17897 rtx op1 = gen_reg_rtx (XFmode); 17898 17899 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17900 emit_insn (gen_frndintxf2_ceil (op0, op1)); 17901 17902 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17903 DONE; 17904}) 17905 17906(define_expand "ceilsf2" 17907 [(use (match_operand:SF 0 "register_operand" "")) 17908 (use (match_operand:SF 1 "register_operand" ""))] 17909 "TARGET_USE_FANCY_MATH_387 17910 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17911 && flag_unsafe_math_optimizations" 17912{ 17913 rtx op0 = gen_reg_rtx (XFmode); 17914 rtx op1 = gen_reg_rtx (XFmode); 17915 17916 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17917 emit_insn (gen_frndintxf2_ceil (op0, op1)); 17918 17919 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17920 DONE; 17921}) 17922 17923(define_insn_and_split "*fist<mode>2_ceil_1" 17924 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 17925 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")] 17926 UNSPEC_FIST_CEIL)) 17927 (clobber (reg:CC FLAGS_REG))] 17928 "TARGET_USE_FANCY_MATH_387 17929 && flag_unsafe_math_optimizations 17930 && !(reload_completed || reload_in_progress)" 17931 "#" 17932 "&& 1" 17933 [(const_int 0)] 17934{ 17935 ix86_optimize_mode_switching[I387_CEIL] = 1; 17936 17937 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17938 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); 17939 if (memory_operand (operands[0], VOIDmode)) 17940 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1], 17941 operands[2], operands[3])); 17942 else 17943 { 17944 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17945 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1], 17946 operands[2], operands[3], 17947 operands[4])); 17948 } 17949 DONE; 17950} 17951 [(set_attr "type" "fistp") 17952 (set_attr "i387_cw" "ceil") 17953 (set_attr "mode" "<MODE>")]) 17954 17955(define_insn "fistdi2_ceil" 17956 [(set (match_operand:DI 0 "memory_operand" "=m") 17957 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 17958 UNSPEC_FIST_CEIL)) 17959 (use (match_operand:HI 2 "memory_operand" "m")) 17960 (use (match_operand:HI 3 "memory_operand" "m")) 17961 (clobber (match_scratch:XF 4 "=&1f"))] 17962 "TARGET_USE_FANCY_MATH_387 17963 && flag_unsafe_math_optimizations" 17964 "* return output_fix_trunc (insn, operands, 0);" 17965 [(set_attr "type" "fistp") 17966 (set_attr "i387_cw" "ceil") 17967 (set_attr "mode" "DI")]) 17968 17969(define_insn "fistdi2_ceil_with_temp" 17970 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17971 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17972 UNSPEC_FIST_CEIL)) 17973 (use (match_operand:HI 2 "memory_operand" "m,m")) 17974 (use (match_operand:HI 3 "memory_operand" "m,m")) 17975 (clobber (match_operand:DI 4 "memory_operand" "=m,m")) 17976 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 17977 "TARGET_USE_FANCY_MATH_387 17978 && flag_unsafe_math_optimizations" 17979 "#" 17980 [(set_attr "type" "fistp") 17981 (set_attr "i387_cw" "ceil") 17982 (set_attr "mode" "DI")]) 17983 17984(define_split 17985 [(set (match_operand:DI 0 "register_operand" "") 17986 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17987 UNSPEC_FIST_CEIL)) 17988 (use (match_operand:HI 2 "memory_operand" "")) 17989 (use (match_operand:HI 3 "memory_operand" "")) 17990 (clobber (match_operand:DI 4 "memory_operand" "")) 17991 (clobber (match_scratch 5 ""))] 17992 "reload_completed" 17993 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) 17994 (use (match_dup 2)) 17995 (use (match_dup 3)) 17996 (clobber (match_dup 5))]) 17997 (set (match_dup 0) (match_dup 4))] 17998 "") 17999 18000(define_split 18001 [(set (match_operand:DI 0 "memory_operand" "") 18002 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 18003 UNSPEC_FIST_CEIL)) 18004 (use (match_operand:HI 2 "memory_operand" "")) 18005 (use (match_operand:HI 3 "memory_operand" "")) 18006 (clobber (match_operand:DI 4 "memory_operand" "")) 18007 (clobber (match_scratch 5 ""))] 18008 "reload_completed" 18009 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) 18010 (use (match_dup 2)) 18011 (use (match_dup 3)) 18012 (clobber (match_dup 5))])] 18013 "") 18014 18015(define_insn "fist<mode>2_ceil" 18016 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 18017 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 18018 UNSPEC_FIST_CEIL)) 18019 (use (match_operand:HI 2 "memory_operand" "m")) 18020 (use (match_operand:HI 3 "memory_operand" "m"))] 18021 "TARGET_USE_FANCY_MATH_387 18022 && flag_unsafe_math_optimizations" 18023 "* return output_fix_trunc (insn, operands, 0);" 18024 [(set_attr "type" "fistp") 18025 (set_attr "i387_cw" "ceil") 18026 (set_attr "mode" "<MODE>")]) 18027 18028(define_insn "fist<mode>2_ceil_with_temp" 18029 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") 18030 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")] 18031 UNSPEC_FIST_CEIL)) 18032 (use (match_operand:HI 2 "memory_operand" "m,m")) 18033 (use (match_operand:HI 3 "memory_operand" "m,m")) 18034 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))] 18035 "TARGET_USE_FANCY_MATH_387 18036 && flag_unsafe_math_optimizations" 18037 "#" 18038 [(set_attr "type" "fistp") 18039 (set_attr "i387_cw" "ceil") 18040 (set_attr "mode" "<MODE>")]) 18041 18042(define_split 18043 [(set (match_operand:X87MODEI12 0 "register_operand" "") 18044 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 18045 UNSPEC_FIST_CEIL)) 18046 (use (match_operand:HI 2 "memory_operand" "")) 18047 (use (match_operand:HI 3 "memory_operand" "")) 18048 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 18049 "reload_completed" 18050 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)] 18051 UNSPEC_FIST_CEIL)) 18052 (use (match_dup 2)) 18053 (use (match_dup 3))]) 18054 (set (match_dup 0) (match_dup 4))] 18055 "") 18056 18057(define_split 18058 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 18059 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 18060 UNSPEC_FIST_CEIL)) 18061 (use (match_operand:HI 2 "memory_operand" "")) 18062 (use (match_operand:HI 3 "memory_operand" "")) 18063 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 18064 "reload_completed" 18065 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] 18066 UNSPEC_FIST_CEIL)) 18067 (use (match_dup 2)) 18068 (use (match_dup 3))])] 18069 "") 18070 18071(define_expand "lceil<mode>2" 18072 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") 18073 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] 18074 UNSPEC_FIST_CEIL)) 18075 (clobber (reg:CC FLAGS_REG))])] 18076 "TARGET_USE_FANCY_MATH_387 18077 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 18078 && flag_unsafe_math_optimizations" 18079 "") 18080 18081;; Rounding mode control word calculation could clobber FLAGS_REG. 18082(define_insn_and_split "frndintxf2_trunc" 18083 [(set (match_operand:XF 0 "register_operand" "=f") 18084 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 18085 UNSPEC_FRNDINT_TRUNC)) 18086 (clobber (reg:CC FLAGS_REG))] 18087 "TARGET_USE_FANCY_MATH_387 18088 && flag_unsafe_math_optimizations 18089 && !(reload_completed || reload_in_progress)" 18090 "#" 18091 "&& 1" 18092 [(const_int 0)] 18093{ 18094 ix86_optimize_mode_switching[I387_TRUNC] = 1; 18095 18096 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 18097 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 18098 18099 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1], 18100 operands[2], operands[3])); 18101 DONE; 18102} 18103 [(set_attr "type" "frndint") 18104 (set_attr "i387_cw" "trunc") 18105 (set_attr "mode" "XF")]) 18106 18107(define_insn "frndintxf2_trunc_i387" 18108 [(set (match_operand:XF 0 "register_operand" "=f") 18109 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 18110 UNSPEC_FRNDINT_TRUNC)) 18111 (use (match_operand:HI 2 "memory_operand" "m")) 18112 (use (match_operand:HI 3 "memory_operand" "m"))] 18113 "TARGET_USE_FANCY_MATH_387 18114 && flag_unsafe_math_optimizations" 18115 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 18116 [(set_attr "type" "frndint") 18117 (set_attr "i387_cw" "trunc") 18118 (set_attr "mode" "XF")]) 18119 18120(define_expand "btruncxf2" 18121 [(use (match_operand:XF 0 "register_operand" "")) 18122 (use (match_operand:XF 1 "register_operand" ""))] 18123 "TARGET_USE_FANCY_MATH_387 18124 && flag_unsafe_math_optimizations" 18125{ 18126 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1])); 18127 DONE; 18128}) 18129 18130(define_expand "btruncdf2" 18131 [(use (match_operand:DF 0 "register_operand" "")) 18132 (use (match_operand:DF 1 "register_operand" ""))] 18133 "TARGET_USE_FANCY_MATH_387 18134 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 18135 && flag_unsafe_math_optimizations" 18136{ 18137 rtx op0 = gen_reg_rtx (XFmode); 18138 rtx op1 = gen_reg_rtx (XFmode); 18139 18140 emit_insn (gen_extenddfxf2 (op1, operands[1])); 18141 emit_insn (gen_frndintxf2_trunc (op0, op1)); 18142 18143 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 18144 DONE; 18145}) 18146 18147(define_expand "btruncsf2" 18148 [(use (match_operand:SF 0 "register_operand" "")) 18149 (use (match_operand:SF 1 "register_operand" ""))] 18150 "TARGET_USE_FANCY_MATH_387 18151 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 18152 && flag_unsafe_math_optimizations" 18153{ 18154 rtx op0 = gen_reg_rtx (XFmode); 18155 rtx op1 = gen_reg_rtx (XFmode); 18156 18157 emit_insn (gen_extendsfxf2 (op1, operands[1])); 18158 emit_insn (gen_frndintxf2_trunc (op0, op1)); 18159 18160 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 18161 DONE; 18162}) 18163 18164;; Rounding mode control word calculation could clobber FLAGS_REG. 18165(define_insn_and_split "frndintxf2_mask_pm" 18166 [(set (match_operand:XF 0 "register_operand" "=f") 18167 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 18168 UNSPEC_FRNDINT_MASK_PM)) 18169 (clobber (reg:CC FLAGS_REG))] 18170 "TARGET_USE_FANCY_MATH_387 18171 && flag_unsafe_math_optimizations 18172 && !(reload_completed || reload_in_progress)" 18173 "#" 18174 "&& 1" 18175 [(const_int 0)] 18176{ 18177 ix86_optimize_mode_switching[I387_MASK_PM] = 1; 18178 18179 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 18180 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM); 18181 18182 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1], 18183 operands[2], operands[3])); 18184 DONE; 18185} 18186 [(set_attr "type" "frndint") 18187 (set_attr "i387_cw" "mask_pm") 18188 (set_attr "mode" "XF")]) 18189 18190(define_insn "frndintxf2_mask_pm_i387" 18191 [(set (match_operand:XF 0 "register_operand" "=f") 18192 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 18193 UNSPEC_FRNDINT_MASK_PM)) 18194 (use (match_operand:HI 2 "memory_operand" "m")) 18195 (use (match_operand:HI 3 "memory_operand" "m"))] 18196 "TARGET_USE_FANCY_MATH_387 18197 && flag_unsafe_math_optimizations" 18198 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2" 18199 [(set_attr "type" "frndint") 18200 (set_attr "i387_cw" "mask_pm") 18201 (set_attr "mode" "XF")]) 18202 18203(define_expand "nearbyintxf2" 18204 [(use (match_operand:XF 0 "register_operand" "")) 18205 (use (match_operand:XF 1 "register_operand" ""))] 18206 "TARGET_USE_FANCY_MATH_387 18207 && flag_unsafe_math_optimizations" 18208{ 18209 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1])); 18210 18211 DONE; 18212}) 18213 18214(define_expand "nearbyintdf2" 18215 [(use (match_operand:DF 0 "register_operand" "")) 18216 (use (match_operand:DF 1 "register_operand" ""))] 18217 "TARGET_USE_FANCY_MATH_387 18218 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 18219 && flag_unsafe_math_optimizations" 18220{ 18221 rtx op0 = gen_reg_rtx (XFmode); 18222 rtx op1 = gen_reg_rtx (XFmode); 18223 18224 emit_insn (gen_extenddfxf2 (op1, operands[1])); 18225 emit_insn (gen_frndintxf2_mask_pm (op0, op1)); 18226 18227 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 18228 DONE; 18229}) 18230 18231(define_expand "nearbyintsf2" 18232 [(use (match_operand:SF 0 "register_operand" "")) 18233 (use (match_operand:SF 1 "register_operand" ""))] 18234 "TARGET_USE_FANCY_MATH_387 18235 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 18236 && flag_unsafe_math_optimizations" 18237{ 18238 rtx op0 = gen_reg_rtx (XFmode); 18239 rtx op1 = gen_reg_rtx (XFmode); 18240 18241 emit_insn (gen_extendsfxf2 (op1, operands[1])); 18242 emit_insn (gen_frndintxf2_mask_pm (op0, op1)); 18243 18244 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 18245 DONE; 18246}) 18247 18248 18249;; Block operation instructions 18250 18251(define_insn "cld" 18252 [(set (reg:SI DIRFLAG_REG) (const_int 0))] 18253 "" 18254 "cld" 18255 [(set_attr "type" "cld")]) 18256 18257(define_expand "movmemsi" 18258 [(use (match_operand:BLK 0 "memory_operand" "")) 18259 (use (match_operand:BLK 1 "memory_operand" "")) 18260 (use (match_operand:SI 2 "nonmemory_operand" "")) 18261 (use (match_operand:SI 3 "const_int_operand" ""))] 18262 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS" 18263{ 18264 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3])) 18265 DONE; 18266 else 18267 FAIL; 18268}) 18269 18270(define_expand "movmemdi" 18271 [(use (match_operand:BLK 0 "memory_operand" "")) 18272 (use (match_operand:BLK 1 "memory_operand" "")) 18273 (use (match_operand:DI 2 "nonmemory_operand" "")) 18274 (use (match_operand:DI 3 "const_int_operand" ""))] 18275 "TARGET_64BIT" 18276{ 18277 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3])) 18278 DONE; 18279 else 18280 FAIL; 18281}) 18282 18283;; Most CPUs don't like single string operations 18284;; Handle this case here to simplify previous expander. 18285 18286(define_expand "strmov" 18287 [(set (match_dup 4) (match_operand 3 "memory_operand" "")) 18288 (set (match_operand 1 "memory_operand" "") (match_dup 4)) 18289 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5)) 18290 (clobber (reg:CC FLAGS_REG))]) 18291 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6)) 18292 (clobber (reg:CC FLAGS_REG))])] 18293 "" 18294{ 18295 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1]))); 18296 18297 /* If .md ever supports :P for Pmode, these can be directly 18298 in the pattern above. */ 18299 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust); 18300 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust); 18301 18302 if (TARGET_SINGLE_STRINGOP || optimize_size) 18303 { 18304 emit_insn (gen_strmov_singleop (operands[0], operands[1], 18305 operands[2], operands[3], 18306 operands[5], operands[6])); 18307 DONE; 18308 } 18309 18310 operands[4] = gen_reg_rtx (GET_MODE (operands[1])); 18311}) 18312 18313(define_expand "strmov_singleop" 18314 [(parallel [(set (match_operand 1 "memory_operand" "") 18315 (match_operand 3 "memory_operand" "")) 18316 (set (match_operand 0 "register_operand" "") 18317 (match_operand 4 "" "")) 18318 (set (match_operand 2 "register_operand" "") 18319 (match_operand 5 "" "")) 18320 (use (reg:SI DIRFLAG_REG))])] 18321 "TARGET_SINGLE_STRINGOP || optimize_size" 18322 "") 18323 18324(define_insn "*strmovdi_rex_1" 18325 [(set (mem:DI (match_operand:DI 2 "register_operand" "0")) 18326 (mem:DI (match_operand:DI 3 "register_operand" "1"))) 18327 (set (match_operand:DI 0 "register_operand" "=D") 18328 (plus:DI (match_dup 2) 18329 (const_int 8))) 18330 (set (match_operand:DI 1 "register_operand" "=S") 18331 (plus:DI (match_dup 3) 18332 (const_int 8))) 18333 (use (reg:SI DIRFLAG_REG))] 18334 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18335 "movsq" 18336 [(set_attr "type" "str") 18337 (set_attr "mode" "DI") 18338 (set_attr "memory" "both")]) 18339 18340(define_insn "*strmovsi_1" 18341 [(set (mem:SI (match_operand:SI 2 "register_operand" "0")) 18342 (mem:SI (match_operand:SI 3 "register_operand" "1"))) 18343 (set (match_operand:SI 0 "register_operand" "=D") 18344 (plus:SI (match_dup 2) 18345 (const_int 4))) 18346 (set (match_operand:SI 1 "register_operand" "=S") 18347 (plus:SI (match_dup 3) 18348 (const_int 4))) 18349 (use (reg:SI DIRFLAG_REG))] 18350 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18351 "{movsl|movsd}" 18352 [(set_attr "type" "str") 18353 (set_attr "mode" "SI") 18354 (set_attr "memory" "both")]) 18355 18356(define_insn "*strmovsi_rex_1" 18357 [(set (mem:SI (match_operand:DI 2 "register_operand" "0")) 18358 (mem:SI (match_operand:DI 3 "register_operand" "1"))) 18359 (set (match_operand:DI 0 "register_operand" "=D") 18360 (plus:DI (match_dup 2) 18361 (const_int 4))) 18362 (set (match_operand:DI 1 "register_operand" "=S") 18363 (plus:DI (match_dup 3) 18364 (const_int 4))) 18365 (use (reg:SI DIRFLAG_REG))] 18366 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18367 "{movsl|movsd}" 18368 [(set_attr "type" "str") 18369 (set_attr "mode" "SI") 18370 (set_attr "memory" "both")]) 18371 18372(define_insn "*strmovhi_1" 18373 [(set (mem:HI (match_operand:SI 2 "register_operand" "0")) 18374 (mem:HI (match_operand:SI 3 "register_operand" "1"))) 18375 (set (match_operand:SI 0 "register_operand" "=D") 18376 (plus:SI (match_dup 2) 18377 (const_int 2))) 18378 (set (match_operand:SI 1 "register_operand" "=S") 18379 (plus:SI (match_dup 3) 18380 (const_int 2))) 18381 (use (reg:SI DIRFLAG_REG))] 18382 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18383 "movsw" 18384 [(set_attr "type" "str") 18385 (set_attr "memory" "both") 18386 (set_attr "mode" "HI")]) 18387 18388(define_insn "*strmovhi_rex_1" 18389 [(set (mem:HI (match_operand:DI 2 "register_operand" "0")) 18390 (mem:HI (match_operand:DI 3 "register_operand" "1"))) 18391 (set (match_operand:DI 0 "register_operand" "=D") 18392 (plus:DI (match_dup 2) 18393 (const_int 2))) 18394 (set (match_operand:DI 1 "register_operand" "=S") 18395 (plus:DI (match_dup 3) 18396 (const_int 2))) 18397 (use (reg:SI DIRFLAG_REG))] 18398 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18399 "movsw" 18400 [(set_attr "type" "str") 18401 (set_attr "memory" "both") 18402 (set_attr "mode" "HI")]) 18403 18404(define_insn "*strmovqi_1" 18405 [(set (mem:QI (match_operand:SI 2 "register_operand" "0")) 18406 (mem:QI (match_operand:SI 3 "register_operand" "1"))) 18407 (set (match_operand:SI 0 "register_operand" "=D") 18408 (plus:SI (match_dup 2) 18409 (const_int 1))) 18410 (set (match_operand:SI 1 "register_operand" "=S") 18411 (plus:SI (match_dup 3) 18412 (const_int 1))) 18413 (use (reg:SI DIRFLAG_REG))] 18414 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18415 "movsb" 18416 [(set_attr "type" "str") 18417 (set_attr "memory" "both") 18418 (set_attr "mode" "QI")]) 18419 18420(define_insn "*strmovqi_rex_1" 18421 [(set (mem:QI (match_operand:DI 2 "register_operand" "0")) 18422 (mem:QI (match_operand:DI 3 "register_operand" "1"))) 18423 (set (match_operand:DI 0 "register_operand" "=D") 18424 (plus:DI (match_dup 2) 18425 (const_int 1))) 18426 (set (match_operand:DI 1 "register_operand" "=S") 18427 (plus:DI (match_dup 3) 18428 (const_int 1))) 18429 (use (reg:SI DIRFLAG_REG))] 18430 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18431 "movsb" 18432 [(set_attr "type" "str") 18433 (set_attr "memory" "both") 18434 (set_attr "mode" "QI")]) 18435 18436(define_expand "rep_mov" 18437 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0)) 18438 (set (match_operand 0 "register_operand" "") 18439 (match_operand 5 "" "")) 18440 (set (match_operand 2 "register_operand" "") 18441 (match_operand 6 "" "")) 18442 (set (match_operand 1 "memory_operand" "") 18443 (match_operand 3 "memory_operand" "")) 18444 (use (match_dup 4)) 18445 (use (reg:SI DIRFLAG_REG))])] 18446 "" 18447 "") 18448 18449(define_insn "*rep_movdi_rex64" 18450 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) 18451 (set (match_operand:DI 0 "register_operand" "=D") 18452 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2") 18453 (const_int 3)) 18454 (match_operand:DI 3 "register_operand" "0"))) 18455 (set (match_operand:DI 1 "register_operand" "=S") 18456 (plus:DI (ashift:DI (match_dup 5) (const_int 3)) 18457 (match_operand:DI 4 "register_operand" "1"))) 18458 (set (mem:BLK (match_dup 3)) 18459 (mem:BLK (match_dup 4))) 18460 (use (match_dup 5)) 18461 (use (reg:SI DIRFLAG_REG))] 18462 "TARGET_64BIT" 18463 "{rep\;movsq|rep movsq}" 18464 [(set_attr "type" "str") 18465 (set_attr "prefix_rep" "1") 18466 (set_attr "memory" "both") 18467 (set_attr "mode" "DI")]) 18468 18469(define_insn "*rep_movsi" 18470 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0)) 18471 (set (match_operand:SI 0 "register_operand" "=D") 18472 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2") 18473 (const_int 2)) 18474 (match_operand:SI 3 "register_operand" "0"))) 18475 (set (match_operand:SI 1 "register_operand" "=S") 18476 (plus:SI (ashift:SI (match_dup 5) (const_int 2)) 18477 (match_operand:SI 4 "register_operand" "1"))) 18478 (set (mem:BLK (match_dup 3)) 18479 (mem:BLK (match_dup 4))) 18480 (use (match_dup 5)) 18481 (use (reg:SI DIRFLAG_REG))] 18482 "!TARGET_64BIT" 18483 "{rep\;movsl|rep movsd}" 18484 [(set_attr "type" "str") 18485 (set_attr "prefix_rep" "1") 18486 (set_attr "memory" "both") 18487 (set_attr "mode" "SI")]) 18488 18489(define_insn "*rep_movsi_rex64" 18490 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) 18491 (set (match_operand:DI 0 "register_operand" "=D") 18492 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2") 18493 (const_int 2)) 18494 (match_operand:DI 3 "register_operand" "0"))) 18495 (set (match_operand:DI 1 "register_operand" "=S") 18496 (plus:DI (ashift:DI (match_dup 5) (const_int 2)) 18497 (match_operand:DI 4 "register_operand" "1"))) 18498 (set (mem:BLK (match_dup 3)) 18499 (mem:BLK (match_dup 4))) 18500 (use (match_dup 5)) 18501 (use (reg:SI DIRFLAG_REG))] 18502 "TARGET_64BIT" 18503 "{rep\;movsl|rep movsd}" 18504 [(set_attr "type" "str") 18505 (set_attr "prefix_rep" "1") 18506 (set_attr "memory" "both") 18507 (set_attr "mode" "SI")]) 18508 18509(define_insn "*rep_movqi" 18510 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0)) 18511 (set (match_operand:SI 0 "register_operand" "=D") 18512 (plus:SI (match_operand:SI 3 "register_operand" "0") 18513 (match_operand:SI 5 "register_operand" "2"))) 18514 (set (match_operand:SI 1 "register_operand" "=S") 18515 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5))) 18516 (set (mem:BLK (match_dup 3)) 18517 (mem:BLK (match_dup 4))) 18518 (use (match_dup 5)) 18519 (use (reg:SI DIRFLAG_REG))] 18520 "!TARGET_64BIT" 18521 "{rep\;movsb|rep movsb}" 18522 [(set_attr "type" "str") 18523 (set_attr "prefix_rep" "1") 18524 (set_attr "memory" "both") 18525 (set_attr "mode" "SI")]) 18526 18527(define_insn "*rep_movqi_rex64" 18528 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) 18529 (set (match_operand:DI 0 "register_operand" "=D") 18530 (plus:DI (match_operand:DI 3 "register_operand" "0") 18531 (match_operand:DI 5 "register_operand" "2"))) 18532 (set (match_operand:DI 1 "register_operand" "=S") 18533 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5))) 18534 (set (mem:BLK (match_dup 3)) 18535 (mem:BLK (match_dup 4))) 18536 (use (match_dup 5)) 18537 (use (reg:SI DIRFLAG_REG))] 18538 "TARGET_64BIT" 18539 "{rep\;movsb|rep movsb}" 18540 [(set_attr "type" "str") 18541 (set_attr "prefix_rep" "1") 18542 (set_attr "memory" "both") 18543 (set_attr "mode" "SI")]) 18544 18545(define_expand "setmemsi" 18546 [(use (match_operand:BLK 0 "memory_operand" "")) 18547 (use (match_operand:SI 1 "nonmemory_operand" "")) 18548 (use (match_operand 2 "const_int_operand" "")) 18549 (use (match_operand 3 "const_int_operand" ""))] 18550 "" 18551{ 18552 /* If value to set is not zero, use the library routine. */ 18553 if (operands[2] != const0_rtx) 18554 FAIL; 18555 18556 if (ix86_expand_clrmem (operands[0], operands[1], operands[3])) 18557 DONE; 18558 else 18559 FAIL; 18560}) 18561 18562(define_expand "setmemdi" 18563 [(use (match_operand:BLK 0 "memory_operand" "")) 18564 (use (match_operand:DI 1 "nonmemory_operand" "")) 18565 (use (match_operand 2 "const_int_operand" "")) 18566 (use (match_operand 3 "const_int_operand" ""))] 18567 "TARGET_64BIT" 18568{ 18569 /* If value to set is not zero, use the library routine. */ 18570 if (operands[2] != const0_rtx) 18571 FAIL; 18572 18573 if (ix86_expand_clrmem (operands[0], operands[1], operands[3])) 18574 DONE; 18575 else 18576 FAIL; 18577}) 18578 18579;; Most CPUs don't like single string operations 18580;; Handle this case here to simplify previous expander. 18581 18582(define_expand "strset" 18583 [(set (match_operand 1 "memory_operand" "") 18584 (match_operand 2 "register_operand" "")) 18585 (parallel [(set (match_operand 0 "register_operand" "") 18586 (match_dup 3)) 18587 (clobber (reg:CC FLAGS_REG))])] 18588 "" 18589{ 18590 if (GET_MODE (operands[1]) != GET_MODE (operands[2])) 18591 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0); 18592 18593 /* If .md ever supports :P for Pmode, this can be directly 18594 in the pattern above. */ 18595 operands[3] = gen_rtx_PLUS (Pmode, operands[0], 18596 GEN_INT (GET_MODE_SIZE (GET_MODE 18597 (operands[2])))); 18598 if (TARGET_SINGLE_STRINGOP || optimize_size) 18599 { 18600 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2], 18601 operands[3])); 18602 DONE; 18603 } 18604}) 18605 18606(define_expand "strset_singleop" 18607 [(parallel [(set (match_operand 1 "memory_operand" "") 18608 (match_operand 2 "register_operand" "")) 18609 (set (match_operand 0 "register_operand" "") 18610 (match_operand 3 "" "")) 18611 (use (reg:SI DIRFLAG_REG))])] 18612 "TARGET_SINGLE_STRINGOP || optimize_size" 18613 "") 18614 18615(define_insn "*strsetdi_rex_1" 18616 [(set (mem:DI (match_operand:DI 1 "register_operand" "0")) 18617 (match_operand:DI 2 "register_operand" "a")) 18618 (set (match_operand:DI 0 "register_operand" "=D") 18619 (plus:DI (match_dup 1) 18620 (const_int 8))) 18621 (use (reg:SI DIRFLAG_REG))] 18622 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18623 "stosq" 18624 [(set_attr "type" "str") 18625 (set_attr "memory" "store") 18626 (set_attr "mode" "DI")]) 18627 18628(define_insn "*strsetsi_1" 18629 [(set (mem:SI (match_operand:SI 1 "register_operand" "0")) 18630 (match_operand:SI 2 "register_operand" "a")) 18631 (set (match_operand:SI 0 "register_operand" "=D") 18632 (plus:SI (match_dup 1) 18633 (const_int 4))) 18634 (use (reg:SI DIRFLAG_REG))] 18635 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18636 "{stosl|stosd}" 18637 [(set_attr "type" "str") 18638 (set_attr "memory" "store") 18639 (set_attr "mode" "SI")]) 18640 18641(define_insn "*strsetsi_rex_1" 18642 [(set (mem:SI (match_operand:DI 1 "register_operand" "0")) 18643 (match_operand:SI 2 "register_operand" "a")) 18644 (set (match_operand:DI 0 "register_operand" "=D") 18645 (plus:DI (match_dup 1) 18646 (const_int 4))) 18647 (use (reg:SI DIRFLAG_REG))] 18648 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18649 "{stosl|stosd}" 18650 [(set_attr "type" "str") 18651 (set_attr "memory" "store") 18652 (set_attr "mode" "SI")]) 18653 18654(define_insn "*strsethi_1" 18655 [(set (mem:HI (match_operand:SI 1 "register_operand" "0")) 18656 (match_operand:HI 2 "register_operand" "a")) 18657 (set (match_operand:SI 0 "register_operand" "=D") 18658 (plus:SI (match_dup 1) 18659 (const_int 2))) 18660 (use (reg:SI DIRFLAG_REG))] 18661 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18662 "stosw" 18663 [(set_attr "type" "str") 18664 (set_attr "memory" "store") 18665 (set_attr "mode" "HI")]) 18666 18667(define_insn "*strsethi_rex_1" 18668 [(set (mem:HI (match_operand:DI 1 "register_operand" "0")) 18669 (match_operand:HI 2 "register_operand" "a")) 18670 (set (match_operand:DI 0 "register_operand" "=D") 18671 (plus:DI (match_dup 1) 18672 (const_int 2))) 18673 (use (reg:SI DIRFLAG_REG))] 18674 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18675 "stosw" 18676 [(set_attr "type" "str") 18677 (set_attr "memory" "store") 18678 (set_attr "mode" "HI")]) 18679 18680(define_insn "*strsetqi_1" 18681 [(set (mem:QI (match_operand:SI 1 "register_operand" "0")) 18682 (match_operand:QI 2 "register_operand" "a")) 18683 (set (match_operand:SI 0 "register_operand" "=D") 18684 (plus:SI (match_dup 1) 18685 (const_int 1))) 18686 (use (reg:SI DIRFLAG_REG))] 18687 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18688 "stosb" 18689 [(set_attr "type" "str") 18690 (set_attr "memory" "store") 18691 (set_attr "mode" "QI")]) 18692 18693(define_insn "*strsetqi_rex_1" 18694 [(set (mem:QI (match_operand:DI 1 "register_operand" "0")) 18695 (match_operand:QI 2 "register_operand" "a")) 18696 (set (match_operand:DI 0 "register_operand" "=D") 18697 (plus:DI (match_dup 1) 18698 (const_int 1))) 18699 (use (reg:SI DIRFLAG_REG))] 18700 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18701 "stosb" 18702 [(set_attr "type" "str") 18703 (set_attr "memory" "store") 18704 (set_attr "mode" "QI")]) 18705 18706(define_expand "rep_stos" 18707 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0)) 18708 (set (match_operand 0 "register_operand" "") 18709 (match_operand 4 "" "")) 18710 (set (match_operand 2 "memory_operand" "") (const_int 0)) 18711 (use (match_operand 3 "register_operand" "")) 18712 (use (match_dup 1)) 18713 (use (reg:SI DIRFLAG_REG))])] 18714 "" 18715 "") 18716 18717(define_insn "*rep_stosdi_rex64" 18718 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) 18719 (set (match_operand:DI 0 "register_operand" "=D") 18720 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1") 18721 (const_int 3)) 18722 (match_operand:DI 3 "register_operand" "0"))) 18723 (set (mem:BLK (match_dup 3)) 18724 (const_int 0)) 18725 (use (match_operand:DI 2 "register_operand" "a")) 18726 (use (match_dup 4)) 18727 (use (reg:SI DIRFLAG_REG))] 18728 "TARGET_64BIT" 18729 "{rep\;stosq|rep stosq}" 18730 [(set_attr "type" "str") 18731 (set_attr "prefix_rep" "1") 18732 (set_attr "memory" "store") 18733 (set_attr "mode" "DI")]) 18734 18735(define_insn "*rep_stossi" 18736 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0)) 18737 (set (match_operand:SI 0 "register_operand" "=D") 18738 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1") 18739 (const_int 2)) 18740 (match_operand:SI 3 "register_operand" "0"))) 18741 (set (mem:BLK (match_dup 3)) 18742 (const_int 0)) 18743 (use (match_operand:SI 2 "register_operand" "a")) 18744 (use (match_dup 4)) 18745 (use (reg:SI DIRFLAG_REG))] 18746 "!TARGET_64BIT" 18747 "{rep\;stosl|rep stosd}" 18748 [(set_attr "type" "str") 18749 (set_attr "prefix_rep" "1") 18750 (set_attr "memory" "store") 18751 (set_attr "mode" "SI")]) 18752 18753(define_insn "*rep_stossi_rex64" 18754 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) 18755 (set (match_operand:DI 0 "register_operand" "=D") 18756 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1") 18757 (const_int 2)) 18758 (match_operand:DI 3 "register_operand" "0"))) 18759 (set (mem:BLK (match_dup 3)) 18760 (const_int 0)) 18761 (use (match_operand:SI 2 "register_operand" "a")) 18762 (use (match_dup 4)) 18763 (use (reg:SI DIRFLAG_REG))] 18764 "TARGET_64BIT" 18765 "{rep\;stosl|rep stosd}" 18766 [(set_attr "type" "str") 18767 (set_attr "prefix_rep" "1") 18768 (set_attr "memory" "store") 18769 (set_attr "mode" "SI")]) 18770 18771(define_insn "*rep_stosqi" 18772 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0)) 18773 (set (match_operand:SI 0 "register_operand" "=D") 18774 (plus:SI (match_operand:SI 3 "register_operand" "0") 18775 (match_operand:SI 4 "register_operand" "1"))) 18776 (set (mem:BLK (match_dup 3)) 18777 (const_int 0)) 18778 (use (match_operand:QI 2 "register_operand" "a")) 18779 (use (match_dup 4)) 18780 (use (reg:SI DIRFLAG_REG))] 18781 "!TARGET_64BIT" 18782 "{rep\;stosb|rep stosb}" 18783 [(set_attr "type" "str") 18784 (set_attr "prefix_rep" "1") 18785 (set_attr "memory" "store") 18786 (set_attr "mode" "QI")]) 18787 18788(define_insn "*rep_stosqi_rex64" 18789 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) 18790 (set (match_operand:DI 0 "register_operand" "=D") 18791 (plus:DI (match_operand:DI 3 "register_operand" "0") 18792 (match_operand:DI 4 "register_operand" "1"))) 18793 (set (mem:BLK (match_dup 3)) 18794 (const_int 0)) 18795 (use (match_operand:QI 2 "register_operand" "a")) 18796 (use (match_dup 4)) 18797 (use (reg:SI DIRFLAG_REG))] 18798 "TARGET_64BIT" 18799 "{rep\;stosb|rep stosb}" 18800 [(set_attr "type" "str") 18801 (set_attr "prefix_rep" "1") 18802 (set_attr "memory" "store") 18803 (set_attr "mode" "QI")]) 18804 18805(define_expand "cmpstrnsi" 18806 [(set (match_operand:SI 0 "register_operand" "") 18807 (compare:SI (match_operand:BLK 1 "general_operand" "") 18808 (match_operand:BLK 2 "general_operand" ""))) 18809 (use (match_operand 3 "general_operand" "")) 18810 (use (match_operand 4 "immediate_operand" ""))] 18811 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS" 18812{ 18813 rtx addr1, addr2, out, outlow, count, countreg, align; 18814 18815 /* Can't use this if the user has appropriated esi or edi. */ 18816 if (global_regs[4] || global_regs[5]) 18817 FAIL; 18818 18819 out = operands[0]; 18820 if (GET_CODE (out) != REG) 18821 out = gen_reg_rtx (SImode); 18822 18823 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); 18824 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0)); 18825 if (addr1 != XEXP (operands[1], 0)) 18826 operands[1] = replace_equiv_address_nv (operands[1], addr1); 18827 if (addr2 != XEXP (operands[2], 0)) 18828 operands[2] = replace_equiv_address_nv (operands[2], addr2); 18829 18830 count = operands[3]; 18831 countreg = ix86_zero_extend_to_Pmode (count); 18832 18833 /* %%% Iff we are testing strict equality, we can use known alignment 18834 to good advantage. This may be possible with combine, particularly 18835 once cc0 is dead. */ 18836 align = operands[4]; 18837 18838 emit_insn (gen_cld ()); 18839 if (GET_CODE (count) == CONST_INT) 18840 { 18841 if (INTVAL (count) == 0) 18842 { 18843 emit_move_insn (operands[0], const0_rtx); 18844 DONE; 18845 } 18846 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align, 18847 operands[1], operands[2])); 18848 } 18849 else 18850 { 18851 if (TARGET_64BIT) 18852 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg)); 18853 else 18854 emit_insn (gen_cmpsi_1 (countreg, countreg)); 18855 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align, 18856 operands[1], operands[2])); 18857 } 18858 18859 outlow = gen_lowpart (QImode, out); 18860 emit_insn (gen_cmpintqi (outlow)); 18861 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow)); 18862 18863 if (operands[0] != out) 18864 emit_move_insn (operands[0], out); 18865 18866 DONE; 18867}) 18868 18869;; Produce a tri-state integer (-1, 0, 1) from condition codes. 18870 18871(define_expand "cmpintqi" 18872 [(set (match_dup 1) 18873 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 18874 (set (match_dup 2) 18875 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 18876 (parallel [(set (match_operand:QI 0 "register_operand" "") 18877 (minus:QI (match_dup 1) 18878 (match_dup 2))) 18879 (clobber (reg:CC FLAGS_REG))])] 18880 "" 18881 "operands[1] = gen_reg_rtx (QImode); 18882 operands[2] = gen_reg_rtx (QImode);") 18883 18884;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is 18885;; zero. Emit extra code to make sure that a zero-length compare is EQ. 18886 18887(define_expand "cmpstrnqi_nz_1" 18888 [(parallel [(set (reg:CC FLAGS_REG) 18889 (compare:CC (match_operand 4 "memory_operand" "") 18890 (match_operand 5 "memory_operand" ""))) 18891 (use (match_operand 2 "register_operand" "")) 18892 (use (match_operand:SI 3 "immediate_operand" "")) 18893 (use (reg:SI DIRFLAG_REG)) 18894 (clobber (match_operand 0 "register_operand" "")) 18895 (clobber (match_operand 1 "register_operand" "")) 18896 (clobber (match_dup 2))])] 18897 "" 18898 "") 18899 18900(define_insn "*cmpstrnqi_nz_1" 18901 [(set (reg:CC FLAGS_REG) 18902 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0")) 18903 (mem:BLK (match_operand:SI 5 "register_operand" "1")))) 18904 (use (match_operand:SI 6 "register_operand" "2")) 18905 (use (match_operand:SI 3 "immediate_operand" "i")) 18906 (use (reg:SI DIRFLAG_REG)) 18907 (clobber (match_operand:SI 0 "register_operand" "=S")) 18908 (clobber (match_operand:SI 1 "register_operand" "=D")) 18909 (clobber (match_operand:SI 2 "register_operand" "=c"))] 18910 "!TARGET_64BIT" 18911 "repz{\;| }cmpsb" 18912 [(set_attr "type" "str") 18913 (set_attr "mode" "QI") 18914 (set_attr "prefix_rep" "1")]) 18915 18916(define_insn "*cmpstrnqi_nz_rex_1" 18917 [(set (reg:CC FLAGS_REG) 18918 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0")) 18919 (mem:BLK (match_operand:DI 5 "register_operand" "1")))) 18920 (use (match_operand:DI 6 "register_operand" "2")) 18921 (use (match_operand:SI 3 "immediate_operand" "i")) 18922 (use (reg:SI DIRFLAG_REG)) 18923 (clobber (match_operand:DI 0 "register_operand" "=S")) 18924 (clobber (match_operand:DI 1 "register_operand" "=D")) 18925 (clobber (match_operand:DI 2 "register_operand" "=c"))] 18926 "TARGET_64BIT" 18927 "repz{\;| }cmpsb" 18928 [(set_attr "type" "str") 18929 (set_attr "mode" "QI") 18930 (set_attr "prefix_rep" "1")]) 18931 18932;; The same, but the count is not known to not be zero. 18933 18934(define_expand "cmpstrnqi_1" 18935 [(parallel [(set (reg:CC FLAGS_REG) 18936 (if_then_else:CC (ne (match_operand 2 "register_operand" "") 18937 (const_int 0)) 18938 (compare:CC (match_operand 4 "memory_operand" "") 18939 (match_operand 5 "memory_operand" "")) 18940 (const_int 0))) 18941 (use (match_operand:SI 3 "immediate_operand" "")) 18942 (use (reg:CC FLAGS_REG)) 18943 (use (reg:SI DIRFLAG_REG)) 18944 (clobber (match_operand 0 "register_operand" "")) 18945 (clobber (match_operand 1 "register_operand" "")) 18946 (clobber (match_dup 2))])] 18947 "" 18948 "") 18949 18950(define_insn "*cmpstrnqi_1" 18951 [(set (reg:CC FLAGS_REG) 18952 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2") 18953 (const_int 0)) 18954 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0")) 18955 (mem:BLK (match_operand:SI 5 "register_operand" "1"))) 18956 (const_int 0))) 18957 (use (match_operand:SI 3 "immediate_operand" "i")) 18958 (use (reg:CC FLAGS_REG)) 18959 (use (reg:SI DIRFLAG_REG)) 18960 (clobber (match_operand:SI 0 "register_operand" "=S")) 18961 (clobber (match_operand:SI 1 "register_operand" "=D")) 18962 (clobber (match_operand:SI 2 "register_operand" "=c"))] 18963 "!TARGET_64BIT" 18964 "repz{\;| }cmpsb" 18965 [(set_attr "type" "str") 18966 (set_attr "mode" "QI") 18967 (set_attr "prefix_rep" "1")]) 18968 18969(define_insn "*cmpstrnqi_rex_1" 18970 [(set (reg:CC FLAGS_REG) 18971 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2") 18972 (const_int 0)) 18973 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0")) 18974 (mem:BLK (match_operand:DI 5 "register_operand" "1"))) 18975 (const_int 0))) 18976 (use (match_operand:SI 3 "immediate_operand" "i")) 18977 (use (reg:CC FLAGS_REG)) 18978 (use (reg:SI DIRFLAG_REG)) 18979 (clobber (match_operand:DI 0 "register_operand" "=S")) 18980 (clobber (match_operand:DI 1 "register_operand" "=D")) 18981 (clobber (match_operand:DI 2 "register_operand" "=c"))] 18982 "TARGET_64BIT" 18983 "repz{\;| }cmpsb" 18984 [(set_attr "type" "str") 18985 (set_attr "mode" "QI") 18986 (set_attr "prefix_rep" "1")]) 18987 18988(define_expand "strlensi" 18989 [(set (match_operand:SI 0 "register_operand" "") 18990 (unspec:SI [(match_operand:BLK 1 "general_operand" "") 18991 (match_operand:QI 2 "immediate_operand" "") 18992 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))] 18993 "" 18994{ 18995 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) 18996 DONE; 18997 else 18998 FAIL; 18999}) 19000 19001(define_expand "strlendi" 19002 [(set (match_operand:DI 0 "register_operand" "") 19003 (unspec:DI [(match_operand:BLK 1 "general_operand" "") 19004 (match_operand:QI 2 "immediate_operand" "") 19005 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))] 19006 "" 19007{ 19008 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) 19009 DONE; 19010 else 19011 FAIL; 19012}) 19013 19014(define_expand "strlenqi_1" 19015 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" "")) 19016 (use (reg:SI DIRFLAG_REG)) 19017 (clobber (match_operand 1 "register_operand" "")) 19018 (clobber (reg:CC FLAGS_REG))])] 19019 "" 19020 "") 19021 19022(define_insn "*strlenqi_1" 19023 [(set (match_operand:SI 0 "register_operand" "=&c") 19024 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1")) 19025 (match_operand:QI 2 "register_operand" "a") 19026 (match_operand:SI 3 "immediate_operand" "i") 19027 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS)) 19028 (use (reg:SI DIRFLAG_REG)) 19029 (clobber (match_operand:SI 1 "register_operand" "=D")) 19030 (clobber (reg:CC FLAGS_REG))] 19031 "!TARGET_64BIT" 19032 "repnz{\;| }scasb" 19033 [(set_attr "type" "str") 19034 (set_attr "mode" "QI") 19035 (set_attr "prefix_rep" "1")]) 19036 19037(define_insn "*strlenqi_rex_1" 19038 [(set (match_operand:DI 0 "register_operand" "=&c") 19039 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1")) 19040 (match_operand:QI 2 "register_operand" "a") 19041 (match_operand:DI 3 "immediate_operand" "i") 19042 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS)) 19043 (use (reg:SI DIRFLAG_REG)) 19044 (clobber (match_operand:DI 1 "register_operand" "=D")) 19045 (clobber (reg:CC FLAGS_REG))] 19046 "TARGET_64BIT" 19047 "repnz{\;| }scasb" 19048 [(set_attr "type" "str") 19049 (set_attr "mode" "QI") 19050 (set_attr "prefix_rep" "1")]) 19051 19052;; Peephole optimizations to clean up after cmpstrn*. This should be 19053;; handled in combine, but it is not currently up to the task. 19054;; When used for their truth value, the cmpstrn* expanders generate 19055;; code like this: 19056;; 19057;; repz cmpsb 19058;; seta %al 19059;; setb %dl 19060;; cmpb %al, %dl 19061;; jcc label 19062;; 19063;; The intermediate three instructions are unnecessary. 19064 19065;; This one handles cmpstrn*_nz_1... 19066(define_peephole2 19067 [(parallel[ 19068 (set (reg:CC FLAGS_REG) 19069 (compare:CC (mem:BLK (match_operand 4 "register_operand" "")) 19070 (mem:BLK (match_operand 5 "register_operand" "")))) 19071 (use (match_operand 6 "register_operand" "")) 19072 (use (match_operand:SI 3 "immediate_operand" "")) 19073 (use (reg:SI DIRFLAG_REG)) 19074 (clobber (match_operand 0 "register_operand" "")) 19075 (clobber (match_operand 1 "register_operand" "")) 19076 (clobber (match_operand 2 "register_operand" ""))]) 19077 (set (match_operand:QI 7 "register_operand" "") 19078 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 19079 (set (match_operand:QI 8 "register_operand" "") 19080 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 19081 (set (reg FLAGS_REG) 19082 (compare (match_dup 7) (match_dup 8))) 19083 ] 19084 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 19085 [(parallel[ 19086 (set (reg:CC FLAGS_REG) 19087 (compare:CC (mem:BLK (match_dup 4)) 19088 (mem:BLK (match_dup 5)))) 19089 (use (match_dup 6)) 19090 (use (match_dup 3)) 19091 (use (reg:SI DIRFLAG_REG)) 19092 (clobber (match_dup 0)) 19093 (clobber (match_dup 1)) 19094 (clobber (match_dup 2))])] 19095 "") 19096 19097;; ...and this one handles cmpstrn*_1. 19098(define_peephole2 19099 [(parallel[ 19100 (set (reg:CC FLAGS_REG) 19101 (if_then_else:CC (ne (match_operand 6 "register_operand" "") 19102 (const_int 0)) 19103 (compare:CC (mem:BLK (match_operand 4 "register_operand" "")) 19104 (mem:BLK (match_operand 5 "register_operand" ""))) 19105 (const_int 0))) 19106 (use (match_operand:SI 3 "immediate_operand" "")) 19107 (use (reg:CC FLAGS_REG)) 19108 (use (reg:SI DIRFLAG_REG)) 19109 (clobber (match_operand 0 "register_operand" "")) 19110 (clobber (match_operand 1 "register_operand" "")) 19111 (clobber (match_operand 2 "register_operand" ""))]) 19112 (set (match_operand:QI 7 "register_operand" "") 19113 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 19114 (set (match_operand:QI 8 "register_operand" "") 19115 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 19116 (set (reg FLAGS_REG) 19117 (compare (match_dup 7) (match_dup 8))) 19118 ] 19119 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 19120 [(parallel[ 19121 (set (reg:CC FLAGS_REG) 19122 (if_then_else:CC (ne (match_dup 6) 19123 (const_int 0)) 19124 (compare:CC (mem:BLK (match_dup 4)) 19125 (mem:BLK (match_dup 5))) 19126 (const_int 0))) 19127 (use (match_dup 3)) 19128 (use (reg:CC FLAGS_REG)) 19129 (use (reg:SI DIRFLAG_REG)) 19130 (clobber (match_dup 0)) 19131 (clobber (match_dup 1)) 19132 (clobber (match_dup 2))])] 19133 "") 19134 19135 19136 19137;; Conditional move instructions. 19138 19139(define_expand "movdicc" 19140 [(set (match_operand:DI 0 "register_operand" "") 19141 (if_then_else:DI (match_operand 1 "comparison_operator" "") 19142 (match_operand:DI 2 "general_operand" "") 19143 (match_operand:DI 3 "general_operand" "")))] 19144 "TARGET_64BIT" 19145 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 19146 19147(define_insn "x86_movdicc_0_m1_rex64" 19148 [(set (match_operand:DI 0 "register_operand" "=r") 19149 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "") 19150 (const_int -1) 19151 (const_int 0))) 19152 (clobber (reg:CC FLAGS_REG))] 19153 "TARGET_64BIT" 19154 "sbb{q}\t%0, %0" 19155 ; Since we don't have the proper number of operands for an alu insn, 19156 ; fill in all the blanks. 19157 [(set_attr "type" "alu") 19158 (set_attr "pent_pair" "pu") 19159 (set_attr "memory" "none") 19160 (set_attr "imm_disp" "false") 19161 (set_attr "mode" "DI") 19162 (set_attr "length_immediate" "0")]) 19163 19164(define_insn "*movdicc_c_rex64" 19165 [(set (match_operand:DI 0 "register_operand" "=r,r") 19166 (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 19167 [(reg FLAGS_REG) (const_int 0)]) 19168 (match_operand:DI 2 "nonimmediate_operand" "rm,0") 19169 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))] 19170 "TARGET_64BIT && TARGET_CMOVE 19171 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19172 "@ 19173 cmov%O2%C1\t{%2, %0|%0, %2} 19174 cmov%O2%c1\t{%3, %0|%0, %3}" 19175 [(set_attr "type" "icmov") 19176 (set_attr "mode" "DI")]) 19177 19178(define_expand "movsicc" 19179 [(set (match_operand:SI 0 "register_operand" "") 19180 (if_then_else:SI (match_operand 1 "comparison_operator" "") 19181 (match_operand:SI 2 "general_operand" "") 19182 (match_operand:SI 3 "general_operand" "")))] 19183 "" 19184 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 19185 19186;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing 19187;; the register first winds up with `sbbl $0,reg', which is also weird. 19188;; So just document what we're doing explicitly. 19189 19190(define_insn "x86_movsicc_0_m1" 19191 [(set (match_operand:SI 0 "register_operand" "=r") 19192 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "") 19193 (const_int -1) 19194 (const_int 0))) 19195 (clobber (reg:CC FLAGS_REG))] 19196 "" 19197 "sbb{l}\t%0, %0" 19198 ; Since we don't have the proper number of operands for an alu insn, 19199 ; fill in all the blanks. 19200 [(set_attr "type" "alu") 19201 (set_attr "pent_pair" "pu") 19202 (set_attr "memory" "none") 19203 (set_attr "imm_disp" "false") 19204 (set_attr "mode" "SI") 19205 (set_attr "length_immediate" "0")]) 19206 19207(define_insn "*movsicc_noc" 19208 [(set (match_operand:SI 0 "register_operand" "=r,r") 19209 (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 19210 [(reg FLAGS_REG) (const_int 0)]) 19211 (match_operand:SI 2 "nonimmediate_operand" "rm,0") 19212 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))] 19213 "TARGET_CMOVE 19214 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19215 "@ 19216 cmov%O2%C1\t{%2, %0|%0, %2} 19217 cmov%O2%c1\t{%3, %0|%0, %3}" 19218 [(set_attr "type" "icmov") 19219 (set_attr "mode" "SI")]) 19220 19221(define_expand "movhicc" 19222 [(set (match_operand:HI 0 "register_operand" "") 19223 (if_then_else:HI (match_operand 1 "comparison_operator" "") 19224 (match_operand:HI 2 "general_operand" "") 19225 (match_operand:HI 3 "general_operand" "")))] 19226 "TARGET_HIMODE_MATH" 19227 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 19228 19229(define_insn "*movhicc_noc" 19230 [(set (match_operand:HI 0 "register_operand" "=r,r") 19231 (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 19232 [(reg FLAGS_REG) (const_int 0)]) 19233 (match_operand:HI 2 "nonimmediate_operand" "rm,0") 19234 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))] 19235 "TARGET_CMOVE 19236 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19237 "@ 19238 cmov%O2%C1\t{%2, %0|%0, %2} 19239 cmov%O2%c1\t{%3, %0|%0, %3}" 19240 [(set_attr "type" "icmov") 19241 (set_attr "mode" "HI")]) 19242 19243(define_expand "movqicc" 19244 [(set (match_operand:QI 0 "register_operand" "") 19245 (if_then_else:QI (match_operand 1 "comparison_operator" "") 19246 (match_operand:QI 2 "general_operand" "") 19247 (match_operand:QI 3 "general_operand" "")))] 19248 "TARGET_QIMODE_MATH" 19249 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 19250 19251(define_insn_and_split "*movqicc_noc" 19252 [(set (match_operand:QI 0 "register_operand" "=r,r") 19253 (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 19254 [(match_operand 4 "flags_reg_operand" "") 19255 (const_int 0)]) 19256 (match_operand:QI 2 "register_operand" "r,0") 19257 (match_operand:QI 3 "register_operand" "0,r")))] 19258 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL" 19259 "#" 19260 "&& reload_completed" 19261 [(set (match_dup 0) 19262 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) 19263 (match_dup 2) 19264 (match_dup 3)))] 19265 "operands[0] = gen_lowpart (SImode, operands[0]); 19266 operands[2] = gen_lowpart (SImode, operands[2]); 19267 operands[3] = gen_lowpart (SImode, operands[3]);" 19268 [(set_attr "type" "icmov") 19269 (set_attr "mode" "SI")]) 19270 19271(define_expand "movsfcc" 19272 [(set (match_operand:SF 0 "register_operand" "") 19273 (if_then_else:SF (match_operand 1 "comparison_operator" "") 19274 (match_operand:SF 2 "register_operand" "") 19275 (match_operand:SF 3 "register_operand" "")))] 19276 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH" 19277 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") 19278 19279(define_insn "*movsfcc_1_387" 19280 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r") 19281 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 19282 [(reg FLAGS_REG) (const_int 0)]) 19283 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0") 19284 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))] 19285 "TARGET_80387 && TARGET_CMOVE 19286 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19287 "@ 19288 fcmov%F1\t{%2, %0|%0, %2} 19289 fcmov%f1\t{%3, %0|%0, %3} 19290 cmov%O2%C1\t{%2, %0|%0, %2} 19291 cmov%O2%c1\t{%3, %0|%0, %3}" 19292 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 19293 (set_attr "mode" "SF,SF,SI,SI")]) 19294 19295(define_expand "movdfcc" 19296 [(set (match_operand:DF 0 "register_operand" "") 19297 (if_then_else:DF (match_operand 1 "comparison_operator" "") 19298 (match_operand:DF 2 "register_operand" "") 19299 (match_operand:DF 3 "register_operand" "")))] 19300 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)" 19301 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") 19302 19303(define_insn "*movdfcc_1" 19304 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r") 19305 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 19306 [(reg FLAGS_REG) (const_int 0)]) 19307 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") 19308 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] 19309 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 19310 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19311 "@ 19312 fcmov%F1\t{%2, %0|%0, %2} 19313 fcmov%f1\t{%3, %0|%0, %3} 19314 # 19315 #" 19316 [(set_attr "type" "fcmov,fcmov,multi,multi") 19317 (set_attr "mode" "DF")]) 19318 19319(define_insn "*movdfcc_1_rex64" 19320 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r") 19321 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 19322 [(reg FLAGS_REG) (const_int 0)]) 19323 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") 19324 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] 19325 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 19326 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19327 "@ 19328 fcmov%F1\t{%2, %0|%0, %2} 19329 fcmov%f1\t{%3, %0|%0, %3} 19330 cmov%O2%C1\t{%2, %0|%0, %2} 19331 cmov%O2%c1\t{%3, %0|%0, %3}" 19332 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 19333 (set_attr "mode" "DF")]) 19334 19335(define_split 19336 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "") 19337 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 19338 [(match_operand 4 "flags_reg_operand" "") 19339 (const_int 0)]) 19340 (match_operand:DF 2 "nonimmediate_operand" "") 19341 (match_operand:DF 3 "nonimmediate_operand" "")))] 19342 "!TARGET_64BIT && reload_completed" 19343 [(set (match_dup 2) 19344 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) 19345 (match_dup 5) 19346 (match_dup 7))) 19347 (set (match_dup 3) 19348 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) 19349 (match_dup 6) 19350 (match_dup 8)))] 19351 "split_di (operands+2, 1, operands+5, operands+6); 19352 split_di (operands+3, 1, operands+7, operands+8); 19353 split_di (operands, 1, operands+2, operands+3);") 19354 19355(define_expand "movxfcc" 19356 [(set (match_operand:XF 0 "register_operand" "") 19357 (if_then_else:XF (match_operand 1 "comparison_operator" "") 19358 (match_operand:XF 2 "register_operand" "") 19359 (match_operand:XF 3 "register_operand" "")))] 19360 "TARGET_80387 && TARGET_CMOVE" 19361 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") 19362 19363(define_insn "*movxfcc_1" 19364 [(set (match_operand:XF 0 "register_operand" "=f,f") 19365 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 19366 [(reg FLAGS_REG) (const_int 0)]) 19367 (match_operand:XF 2 "register_operand" "f,0") 19368 (match_operand:XF 3 "register_operand" "0,f")))] 19369 "TARGET_80387 && TARGET_CMOVE" 19370 "@ 19371 fcmov%F1\t{%2, %0|%0, %2} 19372 fcmov%f1\t{%3, %0|%0, %3}" 19373 [(set_attr "type" "fcmov") 19374 (set_attr "mode" "XF")]) 19375 19376;; These versions of the min/max patterns are intentionally ignorant of 19377;; their behavior wrt -0.0 and NaN (via the commutative operand mark). 19378;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator 19379;; are undefined in this condition, we're certain this is correct. 19380 19381(define_insn "sminsf3" 19382 [(set (match_operand:SF 0 "register_operand" "=x") 19383 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0") 19384 (match_operand:SF 2 "nonimmediate_operand" "xm")))] 19385 "TARGET_SSE_MATH" 19386 "minss\t{%2, %0|%0, %2}" 19387 [(set_attr "type" "sseadd") 19388 (set_attr "mode" "SF")]) 19389 19390(define_insn "smaxsf3" 19391 [(set (match_operand:SF 0 "register_operand" "=x") 19392 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0") 19393 (match_operand:SF 2 "nonimmediate_operand" "xm")))] 19394 "TARGET_SSE_MATH" 19395 "maxss\t{%2, %0|%0, %2}" 19396 [(set_attr "type" "sseadd") 19397 (set_attr "mode" "SF")]) 19398 19399(define_insn "smindf3" 19400 [(set (match_operand:DF 0 "register_operand" "=x") 19401 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0") 19402 (match_operand:DF 2 "nonimmediate_operand" "xm")))] 19403 "TARGET_SSE2 && TARGET_SSE_MATH" 19404 "minsd\t{%2, %0|%0, %2}" 19405 [(set_attr "type" "sseadd") 19406 (set_attr "mode" "DF")]) 19407 19408(define_insn "smaxdf3" 19409 [(set (match_operand:DF 0 "register_operand" "=x") 19410 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0") 19411 (match_operand:DF 2 "nonimmediate_operand" "xm")))] 19412 "TARGET_SSE2 && TARGET_SSE_MATH" 19413 "maxsd\t{%2, %0|%0, %2}" 19414 [(set_attr "type" "sseadd") 19415 (set_attr "mode" "DF")]) 19416 19417;; These versions of the min/max patterns implement exactly the operations 19418;; min = (op1 < op2 ? op1 : op2) 19419;; max = (!(op1 < op2) ? op1 : op2) 19420;; Their operands are not commutative, and thus they may be used in the 19421;; presence of -0.0 and NaN. 19422 19423(define_insn "*ieee_sminsf3" 19424 [(set (match_operand:SF 0 "register_operand" "=x") 19425 (unspec:SF [(match_operand:SF 1 "register_operand" "0") 19426 (match_operand:SF 2 "nonimmediate_operand" "xm")] 19427 UNSPEC_IEEE_MIN))] 19428 "TARGET_SSE_MATH" 19429 "minss\t{%2, %0|%0, %2}" 19430 [(set_attr "type" "sseadd") 19431 (set_attr "mode" "SF")]) 19432 19433(define_insn "*ieee_smaxsf3" 19434 [(set (match_operand:SF 0 "register_operand" "=x") 19435 (unspec:SF [(match_operand:SF 1 "register_operand" "0") 19436 (match_operand:SF 2 "nonimmediate_operand" "xm")] 19437 UNSPEC_IEEE_MAX))] 19438 "TARGET_SSE_MATH" 19439 "maxss\t{%2, %0|%0, %2}" 19440 [(set_attr "type" "sseadd") 19441 (set_attr "mode" "SF")]) 19442 19443(define_insn "*ieee_smindf3" 19444 [(set (match_operand:DF 0 "register_operand" "=x") 19445 (unspec:DF [(match_operand:DF 1 "register_operand" "0") 19446 (match_operand:DF 2 "nonimmediate_operand" "xm")] 19447 UNSPEC_IEEE_MIN))] 19448 "TARGET_SSE2 && TARGET_SSE_MATH" 19449 "minsd\t{%2, %0|%0, %2}" 19450 [(set_attr "type" "sseadd") 19451 (set_attr "mode" "DF")]) 19452 19453(define_insn "*ieee_smaxdf3" 19454 [(set (match_operand:DF 0 "register_operand" "=x") 19455 (unspec:DF [(match_operand:DF 1 "register_operand" "0") 19456 (match_operand:DF 2 "nonimmediate_operand" "xm")] 19457 UNSPEC_IEEE_MAX))] 19458 "TARGET_SSE2 && TARGET_SSE_MATH" 19459 "maxsd\t{%2, %0|%0, %2}" 19460 [(set_attr "type" "sseadd") 19461 (set_attr "mode" "DF")]) 19462 19463;; Make two stack loads independent: 19464;; fld aa fld aa 19465;; fld %st(0) -> fld bb 19466;; fmul bb fmul %st(1), %st 19467;; 19468;; Actually we only match the last two instructions for simplicity. 19469(define_peephole2 19470 [(set (match_operand 0 "fp_register_operand" "") 19471 (match_operand 1 "fp_register_operand" "")) 19472 (set (match_dup 0) 19473 (match_operator 2 "binary_fp_operator" 19474 [(match_dup 0) 19475 (match_operand 3 "memory_operand" "")]))] 19476 "REGNO (operands[0]) != REGNO (operands[1])" 19477 [(set (match_dup 0) (match_dup 3)) 19478 (set (match_dup 0) (match_dup 4))] 19479 19480 ;; The % modifier is not operational anymore in peephole2's, so we have to 19481 ;; swap the operands manually in the case of addition and multiplication. 19482 "if (COMMUTATIVE_ARITH_P (operands[2])) 19483 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), 19484 operands[0], operands[1]); 19485 else 19486 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), 19487 operands[1], operands[0]);") 19488 19489;; Conditional addition patterns 19490(define_expand "addqicc" 19491 [(match_operand:QI 0 "register_operand" "") 19492 (match_operand 1 "comparison_operator" "") 19493 (match_operand:QI 2 "register_operand" "") 19494 (match_operand:QI 3 "const_int_operand" "")] 19495 "" 19496 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 19497 19498(define_expand "addhicc" 19499 [(match_operand:HI 0 "register_operand" "") 19500 (match_operand 1 "comparison_operator" "") 19501 (match_operand:HI 2 "register_operand" "") 19502 (match_operand:HI 3 "const_int_operand" "")] 19503 "" 19504 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 19505 19506(define_expand "addsicc" 19507 [(match_operand:SI 0 "register_operand" "") 19508 (match_operand 1 "comparison_operator" "") 19509 (match_operand:SI 2 "register_operand" "") 19510 (match_operand:SI 3 "const_int_operand" "")] 19511 "" 19512 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 19513 19514(define_expand "adddicc" 19515 [(match_operand:DI 0 "register_operand" "") 19516 (match_operand 1 "comparison_operator" "") 19517 (match_operand:DI 2 "register_operand" "") 19518 (match_operand:DI 3 "const_int_operand" "")] 19519 "TARGET_64BIT" 19520 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 19521 19522 19523;; Misc patterns (?) 19524 19525;; This pattern exists to put a dependency on all ebp-based memory accesses. 19526;; Otherwise there will be nothing to keep 19527;; 19528;; [(set (reg ebp) (reg esp))] 19529;; [(set (reg esp) (plus (reg esp) (const_int -160000))) 19530;; (clobber (eflags)] 19531;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))] 19532;; 19533;; in proper program order. 19534(define_insn "pro_epilogue_adjust_stack_1" 19535 [(set (match_operand:SI 0 "register_operand" "=r,r") 19536 (plus:SI (match_operand:SI 1 "register_operand" "0,r") 19537 (match_operand:SI 2 "immediate_operand" "i,i"))) 19538 (clobber (reg:CC FLAGS_REG)) 19539 (clobber (mem:BLK (scratch)))] 19540 "!TARGET_64BIT" 19541{ 19542 switch (get_attr_type (insn)) 19543 { 19544 case TYPE_IMOV: 19545 return "mov{l}\t{%1, %0|%0, %1}"; 19546 19547 case TYPE_ALU: 19548 if (GET_CODE (operands[2]) == CONST_INT 19549 && (INTVAL (operands[2]) == 128 19550 || (INTVAL (operands[2]) < 0 19551 && INTVAL (operands[2]) != -128))) 19552 { 19553 operands[2] = GEN_INT (-INTVAL (operands[2])); 19554 return "sub{l}\t{%2, %0|%0, %2}"; 19555 } 19556 return "add{l}\t{%2, %0|%0, %2}"; 19557 19558 case TYPE_LEA: 19559 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 19560 return "lea{l}\t{%a2, %0|%0, %a2}"; 19561 19562 default: 19563 gcc_unreachable (); 19564 } 19565} 19566 [(set (attr "type") 19567 (cond [(eq_attr "alternative" "0") 19568 (const_string "alu") 19569 (match_operand:SI 2 "const0_operand" "") 19570 (const_string "imov") 19571 ] 19572 (const_string "lea"))) 19573 (set_attr "mode" "SI")]) 19574 19575(define_insn "pro_epilogue_adjust_stack_rex64" 19576 [(set (match_operand:DI 0 "register_operand" "=r,r") 19577 (plus:DI (match_operand:DI 1 "register_operand" "0,r") 19578 (match_operand:DI 2 "x86_64_immediate_operand" "e,e"))) 19579 (clobber (reg:CC FLAGS_REG)) 19580 (clobber (mem:BLK (scratch)))] 19581 "TARGET_64BIT" 19582{ 19583 switch (get_attr_type (insn)) 19584 { 19585 case TYPE_IMOV: 19586 return "mov{q}\t{%1, %0|%0, %1}"; 19587 19588 case TYPE_ALU: 19589 if (GET_CODE (operands[2]) == CONST_INT 19590 /* Avoid overflows. */ 19591 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 19592 && (INTVAL (operands[2]) == 128 19593 || (INTVAL (operands[2]) < 0 19594 && INTVAL (operands[2]) != -128))) 19595 { 19596 operands[2] = GEN_INT (-INTVAL (operands[2])); 19597 return "sub{q}\t{%2, %0|%0, %2}"; 19598 } 19599 return "add{q}\t{%2, %0|%0, %2}"; 19600 19601 case TYPE_LEA: 19602 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 19603 return "lea{q}\t{%a2, %0|%0, %a2}"; 19604 19605 default: 19606 gcc_unreachable (); 19607 } 19608} 19609 [(set (attr "type") 19610 (cond [(eq_attr "alternative" "0") 19611 (const_string "alu") 19612 (match_operand:DI 2 "const0_operand" "") 19613 (const_string "imov") 19614 ] 19615 (const_string "lea"))) 19616 (set_attr "mode" "DI")]) 19617 19618(define_insn "pro_epilogue_adjust_stack_rex64_2" 19619 [(set (match_operand:DI 0 "register_operand" "=r,r") 19620 (plus:DI (match_operand:DI 1 "register_operand" "0,r") 19621 (match_operand:DI 3 "immediate_operand" "i,i"))) 19622 (use (match_operand:DI 2 "register_operand" "r,r")) 19623 (clobber (reg:CC FLAGS_REG)) 19624 (clobber (mem:BLK (scratch)))] 19625 "TARGET_64BIT" 19626{ 19627 switch (get_attr_type (insn)) 19628 { 19629 case TYPE_ALU: 19630 return "add{q}\t{%2, %0|%0, %2}"; 19631 19632 case TYPE_LEA: 19633 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]); 19634 return "lea{q}\t{%a2, %0|%0, %a2}"; 19635 19636 default: 19637 gcc_unreachable (); 19638 } 19639} 19640 [(set_attr "type" "alu,lea") 19641 (set_attr "mode" "DI")]) 19642 19643(define_expand "allocate_stack_worker" 19644 [(match_operand:SI 0 "register_operand" "")] 19645 "TARGET_STACK_PROBE" 19646{ 19647 if (reload_completed) 19648 { 19649 if (TARGET_64BIT) 19650 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0])); 19651 else 19652 emit_insn (gen_allocate_stack_worker_postreload (operands[0])); 19653 } 19654 else 19655 { 19656 if (TARGET_64BIT) 19657 emit_insn (gen_allocate_stack_worker_rex64 (operands[0])); 19658 else 19659 emit_insn (gen_allocate_stack_worker_1 (operands[0])); 19660 } 19661 DONE; 19662}) 19663 19664(define_insn "allocate_stack_worker_1" 19665 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")] 19666 UNSPECV_STACK_PROBE) 19667 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0))) 19668 (clobber (match_scratch:SI 1 "=0")) 19669 (clobber (reg:CC FLAGS_REG))] 19670 "!TARGET_64BIT && TARGET_STACK_PROBE" 19671 "call\t__alloca" 19672 [(set_attr "type" "multi") 19673 (set_attr "length" "5")]) 19674 19675(define_expand "allocate_stack_worker_postreload" 19676 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")] 19677 UNSPECV_STACK_PROBE) 19678 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0))) 19679 (clobber (match_dup 0)) 19680 (clobber (reg:CC FLAGS_REG))])] 19681 "" 19682 "") 19683 19684(define_insn "allocate_stack_worker_rex64" 19685 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")] 19686 UNSPECV_STACK_PROBE) 19687 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0))) 19688 (clobber (match_scratch:DI 1 "=0")) 19689 (clobber (reg:CC FLAGS_REG))] 19690 "TARGET_64BIT && TARGET_STACK_PROBE" 19691 "call\t__alloca" 19692 [(set_attr "type" "multi") 19693 (set_attr "length" "5")]) 19694 19695(define_expand "allocate_stack_worker_rex64_postreload" 19696 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")] 19697 UNSPECV_STACK_PROBE) 19698 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0))) 19699 (clobber (match_dup 0)) 19700 (clobber (reg:CC FLAGS_REG))])] 19701 "" 19702 "") 19703 19704(define_expand "allocate_stack" 19705 [(parallel [(set (match_operand:SI 0 "register_operand" "=r") 19706 (minus:SI (reg:SI SP_REG) 19707 (match_operand:SI 1 "general_operand" ""))) 19708 (clobber (reg:CC FLAGS_REG))]) 19709 (parallel [(set (reg:SI SP_REG) 19710 (minus:SI (reg:SI SP_REG) (match_dup 1))) 19711 (clobber (reg:CC FLAGS_REG))])] 19712 "TARGET_STACK_PROBE" 19713{ 19714#ifdef CHECK_STACK_LIMIT 19715 if (GET_CODE (operands[1]) == CONST_INT 19716 && INTVAL (operands[1]) < CHECK_STACK_LIMIT) 19717 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, 19718 operands[1])); 19719 else 19720#endif 19721 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode, 19722 operands[1]))); 19723 19724 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 19725 DONE; 19726}) 19727 19728(define_expand "builtin_setjmp_receiver" 19729 [(label_ref (match_operand 0 "" ""))] 19730 "!TARGET_64BIT && flag_pic" 19731{ 19732 if (TARGET_MACHO) 19733 { 19734 rtx xops[3]; 19735 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM); 19736 rtx label_rtx = gen_label_rtx (); 19737 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx)); 19738 xops[0] = xops[1] = picreg; 19739 xops[2] = gen_rtx_CONST (SImode, 19740 gen_rtx_MINUS (SImode, 19741 gen_rtx_LABEL_REF (SImode, label_rtx), 19742 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME))); 19743 ix86_expand_binary_operator (MINUS, SImode, xops); 19744 } 19745 else 19746 emit_insn (gen_set_got (pic_offset_table_rtx)); 19747 DONE; 19748}) 19749 19750;; Avoid redundant prefixes by splitting HImode arithmetic to SImode. 19751 19752(define_split 19753 [(set (match_operand 0 "register_operand" "") 19754 (match_operator 3 "promotable_binary_operator" 19755 [(match_operand 1 "register_operand" "") 19756 (match_operand 2 "aligned_operand" "")])) 19757 (clobber (reg:CC FLAGS_REG))] 19758 "! TARGET_PARTIAL_REG_STALL && reload_completed 19759 && ((GET_MODE (operands[0]) == HImode 19760 && ((!optimize_size && !TARGET_FAST_PREFIX) 19761 /* ??? next two lines just !satisfies_constraint_K (...) */ 19762 || GET_CODE (operands[2]) != CONST_INT 19763 || satisfies_constraint_K (operands[2]))) 19764 || (GET_MODE (operands[0]) == QImode 19765 && (TARGET_PROMOTE_QImode || optimize_size)))" 19766 [(parallel [(set (match_dup 0) 19767 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 19768 (clobber (reg:CC FLAGS_REG))])] 19769 "operands[0] = gen_lowpart (SImode, operands[0]); 19770 operands[1] = gen_lowpart (SImode, operands[1]); 19771 if (GET_CODE (operands[3]) != ASHIFT) 19772 operands[2] = gen_lowpart (SImode, operands[2]); 19773 PUT_MODE (operands[3], SImode);") 19774 19775; Promote the QImode tests, as i386 has encoding of the AND 19776; instruction with 32-bit sign-extended immediate and thus the 19777; instruction size is unchanged, except in the %eax case for 19778; which it is increased by one byte, hence the ! optimize_size. 19779(define_split 19780 [(set (match_operand 0 "flags_reg_operand" "") 19781 (match_operator 2 "compare_operator" 19782 [(and (match_operand 3 "aligned_operand" "") 19783 (match_operand 4 "const_int_operand" "")) 19784 (const_int 0)])) 19785 (set (match_operand 1 "register_operand" "") 19786 (and (match_dup 3) (match_dup 4)))] 19787 "! TARGET_PARTIAL_REG_STALL && reload_completed 19788 /* Ensure that the operand will remain sign-extended immediate. */ 19789 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode) 19790 && ! optimize_size 19791 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX) 19792 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))" 19793 [(parallel [(set (match_dup 0) 19794 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4)) 19795 (const_int 0)])) 19796 (set (match_dup 1) 19797 (and:SI (match_dup 3) (match_dup 4)))])] 19798{ 19799 operands[4] 19800 = gen_int_mode (INTVAL (operands[4]) 19801 & GET_MODE_MASK (GET_MODE (operands[1])), SImode); 19802 operands[1] = gen_lowpart (SImode, operands[1]); 19803 operands[3] = gen_lowpart (SImode, operands[3]); 19804}) 19805 19806; Don't promote the QImode tests, as i386 doesn't have encoding of 19807; the TEST instruction with 32-bit sign-extended immediate and thus 19808; the instruction size would at least double, which is not what we 19809; want even with ! optimize_size. 19810(define_split 19811 [(set (match_operand 0 "flags_reg_operand" "") 19812 (match_operator 1 "compare_operator" 19813 [(and (match_operand:HI 2 "aligned_operand" "") 19814 (match_operand:HI 3 "const_int_operand" "")) 19815 (const_int 0)]))] 19816 "! TARGET_PARTIAL_REG_STALL && reload_completed 19817 /* Ensure that the operand will remain sign-extended immediate. */ 19818 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode) 19819 && ! TARGET_FAST_PREFIX 19820 && ! optimize_size" 19821 [(set (match_dup 0) 19822 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 19823 (const_int 0)]))] 19824{ 19825 operands[3] 19826 = gen_int_mode (INTVAL (operands[3]) 19827 & GET_MODE_MASK (GET_MODE (operands[2])), SImode); 19828 operands[2] = gen_lowpart (SImode, operands[2]); 19829}) 19830 19831(define_split 19832 [(set (match_operand 0 "register_operand" "") 19833 (neg (match_operand 1 "register_operand" ""))) 19834 (clobber (reg:CC FLAGS_REG))] 19835 "! TARGET_PARTIAL_REG_STALL && reload_completed 19836 && (GET_MODE (operands[0]) == HImode 19837 || (GET_MODE (operands[0]) == QImode 19838 && (TARGET_PROMOTE_QImode || optimize_size)))" 19839 [(parallel [(set (match_dup 0) 19840 (neg:SI (match_dup 1))) 19841 (clobber (reg:CC FLAGS_REG))])] 19842 "operands[0] = gen_lowpart (SImode, operands[0]); 19843 operands[1] = gen_lowpart (SImode, operands[1]);") 19844 19845(define_split 19846 [(set (match_operand 0 "register_operand" "") 19847 (not (match_operand 1 "register_operand" "")))] 19848 "! TARGET_PARTIAL_REG_STALL && reload_completed 19849 && (GET_MODE (operands[0]) == HImode 19850 || (GET_MODE (operands[0]) == QImode 19851 && (TARGET_PROMOTE_QImode || optimize_size)))" 19852 [(set (match_dup 0) 19853 (not:SI (match_dup 1)))] 19854 "operands[0] = gen_lowpart (SImode, operands[0]); 19855 operands[1] = gen_lowpart (SImode, operands[1]);") 19856 19857(define_split 19858 [(set (match_operand 0 "register_operand" "") 19859 (if_then_else (match_operator 1 "comparison_operator" 19860 [(reg FLAGS_REG) (const_int 0)]) 19861 (match_operand 2 "register_operand" "") 19862 (match_operand 3 "register_operand" "")))] 19863 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE 19864 && (GET_MODE (operands[0]) == HImode 19865 || (GET_MODE (operands[0]) == QImode 19866 && (TARGET_PROMOTE_QImode || optimize_size)))" 19867 [(set (match_dup 0) 19868 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))] 19869 "operands[0] = gen_lowpart (SImode, operands[0]); 19870 operands[2] = gen_lowpart (SImode, operands[2]); 19871 operands[3] = gen_lowpart (SImode, operands[3]);") 19872 19873 19874;; RTL Peephole optimizations, run before sched2. These primarily look to 19875;; transform a complex memory operation into two memory to register operations. 19876 19877;; Don't push memory operands 19878(define_peephole2 19879 [(set (match_operand:SI 0 "push_operand" "") 19880 (match_operand:SI 1 "memory_operand" "")) 19881 (match_scratch:SI 2 "r")] 19882 "!optimize_size && !TARGET_PUSH_MEMORY 19883 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19884 [(set (match_dup 2) (match_dup 1)) 19885 (set (match_dup 0) (match_dup 2))] 19886 "") 19887 19888(define_peephole2 19889 [(set (match_operand:DI 0 "push_operand" "") 19890 (match_operand:DI 1 "memory_operand" "")) 19891 (match_scratch:DI 2 "r")] 19892 "!optimize_size && !TARGET_PUSH_MEMORY 19893 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19894 [(set (match_dup 2) (match_dup 1)) 19895 (set (match_dup 0) (match_dup 2))] 19896 "") 19897 19898;; We need to handle SFmode only, because DFmode and XFmode is split to 19899;; SImode pushes. 19900(define_peephole2 19901 [(set (match_operand:SF 0 "push_operand" "") 19902 (match_operand:SF 1 "memory_operand" "")) 19903 (match_scratch:SF 2 "r")] 19904 "!optimize_size && !TARGET_PUSH_MEMORY 19905 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19906 [(set (match_dup 2) (match_dup 1)) 19907 (set (match_dup 0) (match_dup 2))] 19908 "") 19909 19910(define_peephole2 19911 [(set (match_operand:HI 0 "push_operand" "") 19912 (match_operand:HI 1 "memory_operand" "")) 19913 (match_scratch:HI 2 "r")] 19914 "!optimize_size && !TARGET_PUSH_MEMORY 19915 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19916 [(set (match_dup 2) (match_dup 1)) 19917 (set (match_dup 0) (match_dup 2))] 19918 "") 19919 19920(define_peephole2 19921 [(set (match_operand:QI 0 "push_operand" "") 19922 (match_operand:QI 1 "memory_operand" "")) 19923 (match_scratch:QI 2 "q")] 19924 "!optimize_size && !TARGET_PUSH_MEMORY 19925 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19926 [(set (match_dup 2) (match_dup 1)) 19927 (set (match_dup 0) (match_dup 2))] 19928 "") 19929 19930;; Don't move an immediate directly to memory when the instruction 19931;; gets too big. 19932(define_peephole2 19933 [(match_scratch:SI 1 "r") 19934 (set (match_operand:SI 0 "memory_operand" "") 19935 (const_int 0))] 19936 "! optimize_size 19937 && ! TARGET_USE_MOV0 19938 && TARGET_SPLIT_LONG_MOVES 19939 && get_attr_length (insn) >= ix86_cost->large_insn 19940 && peep2_regno_dead_p (0, FLAGS_REG)" 19941 [(parallel [(set (match_dup 1) (const_int 0)) 19942 (clobber (reg:CC FLAGS_REG))]) 19943 (set (match_dup 0) (match_dup 1))] 19944 "") 19945 19946(define_peephole2 19947 [(match_scratch:HI 1 "r") 19948 (set (match_operand:HI 0 "memory_operand" "") 19949 (const_int 0))] 19950 "! optimize_size 19951 && ! TARGET_USE_MOV0 19952 && TARGET_SPLIT_LONG_MOVES 19953 && get_attr_length (insn) >= ix86_cost->large_insn 19954 && peep2_regno_dead_p (0, FLAGS_REG)" 19955 [(parallel [(set (match_dup 2) (const_int 0)) 19956 (clobber (reg:CC FLAGS_REG))]) 19957 (set (match_dup 0) (match_dup 1))] 19958 "operands[2] = gen_lowpart (SImode, operands[1]);") 19959 19960(define_peephole2 19961 [(match_scratch:QI 1 "q") 19962 (set (match_operand:QI 0 "memory_operand" "") 19963 (const_int 0))] 19964 "! optimize_size 19965 && ! TARGET_USE_MOV0 19966 && TARGET_SPLIT_LONG_MOVES 19967 && get_attr_length (insn) >= ix86_cost->large_insn 19968 && peep2_regno_dead_p (0, FLAGS_REG)" 19969 [(parallel [(set (match_dup 2) (const_int 0)) 19970 (clobber (reg:CC FLAGS_REG))]) 19971 (set (match_dup 0) (match_dup 1))] 19972 "operands[2] = gen_lowpart (SImode, operands[1]);") 19973 19974(define_peephole2 19975 [(match_scratch:SI 2 "r") 19976 (set (match_operand:SI 0 "memory_operand" "") 19977 (match_operand:SI 1 "immediate_operand" ""))] 19978 "! optimize_size 19979 && get_attr_length (insn) >= ix86_cost->large_insn 19980 && TARGET_SPLIT_LONG_MOVES" 19981 [(set (match_dup 2) (match_dup 1)) 19982 (set (match_dup 0) (match_dup 2))] 19983 "") 19984 19985(define_peephole2 19986 [(match_scratch:HI 2 "r") 19987 (set (match_operand:HI 0 "memory_operand" "") 19988 (match_operand:HI 1 "immediate_operand" ""))] 19989 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn 19990 && TARGET_SPLIT_LONG_MOVES" 19991 [(set (match_dup 2) (match_dup 1)) 19992 (set (match_dup 0) (match_dup 2))] 19993 "") 19994 19995(define_peephole2 19996 [(match_scratch:QI 2 "q") 19997 (set (match_operand:QI 0 "memory_operand" "") 19998 (match_operand:QI 1 "immediate_operand" ""))] 19999 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn 20000 && TARGET_SPLIT_LONG_MOVES" 20001 [(set (match_dup 2) (match_dup 1)) 20002 (set (match_dup 0) (match_dup 2))] 20003 "") 20004 20005;; Don't compare memory with zero, load and use a test instead. 20006(define_peephole2 20007 [(set (match_operand 0 "flags_reg_operand" "") 20008 (match_operator 1 "compare_operator" 20009 [(match_operand:SI 2 "memory_operand" "") 20010 (const_int 0)])) 20011 (match_scratch:SI 3 "r")] 20012 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size" 20013 [(set (match_dup 3) (match_dup 2)) 20014 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))] 20015 "") 20016 20017;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 20018;; Don't split NOTs with a displacement operand, because resulting XOR 20019;; will not be pairable anyway. 20020;; 20021;; On AMD K6, NOT is vector decoded with memory operand that cannot be 20022;; represented using a modRM byte. The XOR replacement is long decoded, 20023;; so this split helps here as well. 20024;; 20025;; Note: Can't do this as a regular split because we can't get proper 20026;; lifetime information then. 20027 20028(define_peephole2 20029 [(set (match_operand:SI 0 "nonimmediate_operand" "") 20030 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))] 20031 "!optimize_size 20032 && peep2_regno_dead_p (0, FLAGS_REG) 20033 && ((TARGET_PENTIUM 20034 && (GET_CODE (operands[0]) != MEM 20035 || !memory_displacement_operand (operands[0], SImode))) 20036 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))" 20037 [(parallel [(set (match_dup 0) 20038 (xor:SI (match_dup 1) (const_int -1))) 20039 (clobber (reg:CC FLAGS_REG))])] 20040 "") 20041 20042(define_peephole2 20043 [(set (match_operand:HI 0 "nonimmediate_operand" "") 20044 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))] 20045 "!optimize_size 20046 && peep2_regno_dead_p (0, FLAGS_REG) 20047 && ((TARGET_PENTIUM 20048 && (GET_CODE (operands[0]) != MEM 20049 || !memory_displacement_operand (operands[0], HImode))) 20050 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))" 20051 [(parallel [(set (match_dup 0) 20052 (xor:HI (match_dup 1) (const_int -1))) 20053 (clobber (reg:CC FLAGS_REG))])] 20054 "") 20055 20056(define_peephole2 20057 [(set (match_operand:QI 0 "nonimmediate_operand" "") 20058 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))] 20059 "!optimize_size 20060 && peep2_regno_dead_p (0, FLAGS_REG) 20061 && ((TARGET_PENTIUM 20062 && (GET_CODE (operands[0]) != MEM 20063 || !memory_displacement_operand (operands[0], QImode))) 20064 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))" 20065 [(parallel [(set (match_dup 0) 20066 (xor:QI (match_dup 1) (const_int -1))) 20067 (clobber (reg:CC FLAGS_REG))])] 20068 "") 20069 20070;; Non pairable "test imm, reg" instructions can be translated to 20071;; "and imm, reg" if reg dies. The "and" form is also shorter (one 20072;; byte opcode instead of two, have a short form for byte operands), 20073;; so do it for other CPUs as well. Given that the value was dead, 20074;; this should not create any new dependencies. Pass on the sub-word 20075;; versions if we're concerned about partial register stalls. 20076 20077(define_peephole2 20078 [(set (match_operand 0 "flags_reg_operand" "") 20079 (match_operator 1 "compare_operator" 20080 [(and:SI (match_operand:SI 2 "register_operand" "") 20081 (match_operand:SI 3 "immediate_operand" "")) 20082 (const_int 0)]))] 20083 "ix86_match_ccmode (insn, CCNOmode) 20084 && (true_regnum (operands[2]) != 0 20085 || satisfies_constraint_K (operands[3])) 20086 && peep2_reg_dead_p (1, operands[2])" 20087 [(parallel 20088 [(set (match_dup 0) 20089 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 20090 (const_int 0)])) 20091 (set (match_dup 2) 20092 (and:SI (match_dup 2) (match_dup 3)))])] 20093 "") 20094 20095;; We don't need to handle HImode case, because it will be promoted to SImode 20096;; on ! TARGET_PARTIAL_REG_STALL 20097 20098(define_peephole2 20099 [(set (match_operand 0 "flags_reg_operand" "") 20100 (match_operator 1 "compare_operator" 20101 [(and:QI (match_operand:QI 2 "register_operand" "") 20102 (match_operand:QI 3 "immediate_operand" "")) 20103 (const_int 0)]))] 20104 "! TARGET_PARTIAL_REG_STALL 20105 && ix86_match_ccmode (insn, CCNOmode) 20106 && true_regnum (operands[2]) != 0 20107 && peep2_reg_dead_p (1, operands[2])" 20108 [(parallel 20109 [(set (match_dup 0) 20110 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 20111 (const_int 0)])) 20112 (set (match_dup 2) 20113 (and:QI (match_dup 2) (match_dup 3)))])] 20114 "") 20115 20116(define_peephole2 20117 [(set (match_operand 0 "flags_reg_operand" "") 20118 (match_operator 1 "compare_operator" 20119 [(and:SI 20120 (zero_extract:SI 20121 (match_operand 2 "ext_register_operand" "") 20122 (const_int 8) 20123 (const_int 8)) 20124 (match_operand 3 "const_int_operand" "")) 20125 (const_int 0)]))] 20126 "! TARGET_PARTIAL_REG_STALL 20127 && ix86_match_ccmode (insn, CCNOmode) 20128 && true_regnum (operands[2]) != 0 20129 && peep2_reg_dead_p (1, operands[2])" 20130 [(parallel [(set (match_dup 0) 20131 (match_op_dup 1 20132 [(and:SI 20133 (zero_extract:SI 20134 (match_dup 2) 20135 (const_int 8) 20136 (const_int 8)) 20137 (match_dup 3)) 20138 (const_int 0)])) 20139 (set (zero_extract:SI (match_dup 2) 20140 (const_int 8) 20141 (const_int 8)) 20142 (and:SI 20143 (zero_extract:SI 20144 (match_dup 2) 20145 (const_int 8) 20146 (const_int 8)) 20147 (match_dup 3)))])] 20148 "") 20149 20150;; Don't do logical operations with memory inputs. 20151(define_peephole2 20152 [(match_scratch:SI 2 "r") 20153 (parallel [(set (match_operand:SI 0 "register_operand" "") 20154 (match_operator:SI 3 "arith_or_logical_operator" 20155 [(match_dup 0) 20156 (match_operand:SI 1 "memory_operand" "")])) 20157 (clobber (reg:CC FLAGS_REG))])] 20158 "! optimize_size && ! TARGET_READ_MODIFY" 20159 [(set (match_dup 2) (match_dup 1)) 20160 (parallel [(set (match_dup 0) 20161 (match_op_dup 3 [(match_dup 0) (match_dup 2)])) 20162 (clobber (reg:CC FLAGS_REG))])] 20163 "") 20164 20165(define_peephole2 20166 [(match_scratch:SI 2 "r") 20167 (parallel [(set (match_operand:SI 0 "register_operand" "") 20168 (match_operator:SI 3 "arith_or_logical_operator" 20169 [(match_operand:SI 1 "memory_operand" "") 20170 (match_dup 0)])) 20171 (clobber (reg:CC FLAGS_REG))])] 20172 "! optimize_size && ! TARGET_READ_MODIFY" 20173 [(set (match_dup 2) (match_dup 1)) 20174 (parallel [(set (match_dup 0) 20175 (match_op_dup 3 [(match_dup 2) (match_dup 0)])) 20176 (clobber (reg:CC FLAGS_REG))])] 20177 "") 20178 20179; Don't do logical operations with memory outputs 20180; 20181; These two don't make sense for PPro/PII -- we're expanding a 4-uop 20182; instruction into two 1-uop insns plus a 2-uop insn. That last has 20183; the same decoder scheduling characteristics as the original. 20184 20185(define_peephole2 20186 [(match_scratch:SI 2 "r") 20187 (parallel [(set (match_operand:SI 0 "memory_operand" "") 20188 (match_operator:SI 3 "arith_or_logical_operator" 20189 [(match_dup 0) 20190 (match_operand:SI 1 "nonmemory_operand" "")])) 20191 (clobber (reg:CC FLAGS_REG))])] 20192 "! optimize_size && ! TARGET_READ_MODIFY_WRITE" 20193 [(set (match_dup 2) (match_dup 0)) 20194 (parallel [(set (match_dup 2) 20195 (match_op_dup 3 [(match_dup 2) (match_dup 1)])) 20196 (clobber (reg:CC FLAGS_REG))]) 20197 (set (match_dup 0) (match_dup 2))] 20198 "") 20199 20200(define_peephole2 20201 [(match_scratch:SI 2 "r") 20202 (parallel [(set (match_operand:SI 0 "memory_operand" "") 20203 (match_operator:SI 3 "arith_or_logical_operator" 20204 [(match_operand:SI 1 "nonmemory_operand" "") 20205 (match_dup 0)])) 20206 (clobber (reg:CC FLAGS_REG))])] 20207 "! optimize_size && ! TARGET_READ_MODIFY_WRITE" 20208 [(set (match_dup 2) (match_dup 0)) 20209 (parallel [(set (match_dup 2) 20210 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 20211 (clobber (reg:CC FLAGS_REG))]) 20212 (set (match_dup 0) (match_dup 2))] 20213 "") 20214 20215;; Attempt to always use XOR for zeroing registers. 20216(define_peephole2 20217 [(set (match_operand 0 "register_operand" "") 20218 (match_operand 1 "const0_operand" ""))] 20219 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD 20220 && (! TARGET_USE_MOV0 || optimize_size) 20221 && GENERAL_REG_P (operands[0]) 20222 && peep2_regno_dead_p (0, FLAGS_REG)" 20223 [(parallel [(set (match_dup 0) (const_int 0)) 20224 (clobber (reg:CC FLAGS_REG))])] 20225{ 20226 operands[0] = gen_lowpart (word_mode, operands[0]); 20227}) 20228 20229(define_peephole2 20230 [(set (strict_low_part (match_operand 0 "register_operand" "")) 20231 (const_int 0))] 20232 "(GET_MODE (operands[0]) == QImode 20233 || GET_MODE (operands[0]) == HImode) 20234 && (! TARGET_USE_MOV0 || optimize_size) 20235 && peep2_regno_dead_p (0, FLAGS_REG)" 20236 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0)) 20237 (clobber (reg:CC FLAGS_REG))])]) 20238 20239;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg. 20240(define_peephole2 20241 [(set (match_operand 0 "register_operand" "") 20242 (const_int -1))] 20243 "(GET_MODE (operands[0]) == HImode 20244 || GET_MODE (operands[0]) == SImode 20245 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT)) 20246 && (optimize_size || TARGET_PENTIUM) 20247 && peep2_regno_dead_p (0, FLAGS_REG)" 20248 [(parallel [(set (match_dup 0) (const_int -1)) 20249 (clobber (reg:CC FLAGS_REG))])] 20250 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode, 20251 operands[0]);") 20252 20253;; Attempt to convert simple leas to adds. These can be created by 20254;; move expanders. 20255(define_peephole2 20256 [(set (match_operand:SI 0 "register_operand" "") 20257 (plus:SI (match_dup 0) 20258 (match_operand:SI 1 "nonmemory_operand" "")))] 20259 "peep2_regno_dead_p (0, FLAGS_REG)" 20260 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) 20261 (clobber (reg:CC FLAGS_REG))])] 20262 "") 20263 20264(define_peephole2 20265 [(set (match_operand:SI 0 "register_operand" "") 20266 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "") 20267 (match_operand:DI 2 "nonmemory_operand" "")) 0))] 20268 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])" 20269 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2))) 20270 (clobber (reg:CC FLAGS_REG))])] 20271 "operands[2] = gen_lowpart (SImode, operands[2]);") 20272 20273(define_peephole2 20274 [(set (match_operand:DI 0 "register_operand" "") 20275 (plus:DI (match_dup 0) 20276 (match_operand:DI 1 "x86_64_general_operand" "")))] 20277 "peep2_regno_dead_p (0, FLAGS_REG)" 20278 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1))) 20279 (clobber (reg:CC FLAGS_REG))])] 20280 "") 20281 20282(define_peephole2 20283 [(set (match_operand:SI 0 "register_operand" "") 20284 (mult:SI (match_dup 0) 20285 (match_operand:SI 1 "const_int_operand" "")))] 20286 "exact_log2 (INTVAL (operands[1])) >= 0 20287 && peep2_regno_dead_p (0, FLAGS_REG)" 20288 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) 20289 (clobber (reg:CC FLAGS_REG))])] 20290 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));") 20291 20292(define_peephole2 20293 [(set (match_operand:DI 0 "register_operand" "") 20294 (mult:DI (match_dup 0) 20295 (match_operand:DI 1 "const_int_operand" "")))] 20296 "exact_log2 (INTVAL (operands[1])) >= 0 20297 && peep2_regno_dead_p (0, FLAGS_REG)" 20298 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2))) 20299 (clobber (reg:CC FLAGS_REG))])] 20300 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));") 20301 20302(define_peephole2 20303 [(set (match_operand:SI 0 "register_operand" "") 20304 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "") 20305 (match_operand:DI 2 "const_int_operand" "")) 0))] 20306 "exact_log2 (INTVAL (operands[2])) >= 0 20307 && REGNO (operands[0]) == REGNO (operands[1]) 20308 && peep2_regno_dead_p (0, FLAGS_REG)" 20309 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) 20310 (clobber (reg:CC FLAGS_REG))])] 20311 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));") 20312 20313;; The ESP adjustments can be done by the push and pop instructions. Resulting 20314;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On 20315;; many CPUs it is also faster, since special hardware to avoid esp 20316;; dependencies is present. 20317 20318;; While some of these conversions may be done using splitters, we use peepholes 20319;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL. 20320 20321;; Convert prologue esp subtractions to push. 20322;; We need register to push. In order to keep verify_flow_info happy we have 20323;; two choices 20324;; - use scratch and clobber it in order to avoid dependencies 20325;; - use already live register 20326;; We can't use the second way right now, since there is no reliable way how to 20327;; verify that given register is live. First choice will also most likely in 20328;; fewer dependencies. On the place of esp adjustments it is very likely that 20329;; call clobbered registers are dead. We may want to use base pointer as an 20330;; alternative when no register is available later. 20331 20332(define_peephole2 20333 [(match_scratch:SI 0 "r") 20334 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) 20335 (clobber (reg:CC FLAGS_REG)) 20336 (clobber (mem:BLK (scratch)))])] 20337 "optimize_size || !TARGET_SUB_ESP_4" 20338 [(clobber (match_dup 0)) 20339 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 20340 (clobber (mem:BLK (scratch)))])]) 20341 20342(define_peephole2 20343 [(match_scratch:SI 0 "r") 20344 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 20345 (clobber (reg:CC FLAGS_REG)) 20346 (clobber (mem:BLK (scratch)))])] 20347 "optimize_size || !TARGET_SUB_ESP_8" 20348 [(clobber (match_dup 0)) 20349 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 20350 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 20351 (clobber (mem:BLK (scratch)))])]) 20352 20353;; Convert esp subtractions to push. 20354(define_peephole2 20355 [(match_scratch:SI 0 "r") 20356 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) 20357 (clobber (reg:CC FLAGS_REG))])] 20358 "optimize_size || !TARGET_SUB_ESP_4" 20359 [(clobber (match_dup 0)) 20360 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))]) 20361 20362(define_peephole2 20363 [(match_scratch:SI 0 "r") 20364 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 20365 (clobber (reg:CC FLAGS_REG))])] 20366 "optimize_size || !TARGET_SUB_ESP_8" 20367 [(clobber (match_dup 0)) 20368 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 20369 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))]) 20370 20371;; Convert epilogue deallocator to pop. 20372(define_peephole2 20373 [(match_scratch:SI 0 "r") 20374 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20375 (clobber (reg:CC FLAGS_REG)) 20376 (clobber (mem:BLK (scratch)))])] 20377 "optimize_size || !TARGET_ADD_ESP_4" 20378 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20379 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20380 (clobber (mem:BLK (scratch)))])] 20381 "") 20382 20383;; Two pops case is tricky, since pop causes dependency on destination register. 20384;; We use two registers if available. 20385(define_peephole2 20386 [(match_scratch:SI 0 "r") 20387 (match_scratch:SI 1 "r") 20388 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 20389 (clobber (reg:CC FLAGS_REG)) 20390 (clobber (mem:BLK (scratch)))])] 20391 "optimize_size || !TARGET_ADD_ESP_8" 20392 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20393 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20394 (clobber (mem:BLK (scratch)))]) 20395 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG))) 20396 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20397 "") 20398 20399(define_peephole2 20400 [(match_scratch:SI 0 "r") 20401 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 20402 (clobber (reg:CC FLAGS_REG)) 20403 (clobber (mem:BLK (scratch)))])] 20404 "optimize_size" 20405 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20406 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20407 (clobber (mem:BLK (scratch)))]) 20408 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20409 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20410 "") 20411 20412;; Convert esp additions to pop. 20413(define_peephole2 20414 [(match_scratch:SI 0 "r") 20415 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20416 (clobber (reg:CC FLAGS_REG))])] 20417 "" 20418 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20419 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20420 "") 20421 20422;; Two pops case is tricky, since pop causes dependency on destination register. 20423;; We use two registers if available. 20424(define_peephole2 20425 [(match_scratch:SI 0 "r") 20426 (match_scratch:SI 1 "r") 20427 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 20428 (clobber (reg:CC FLAGS_REG))])] 20429 "" 20430 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20431 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))]) 20432 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG))) 20433 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20434 "") 20435 20436(define_peephole2 20437 [(match_scratch:SI 0 "r") 20438 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 20439 (clobber (reg:CC FLAGS_REG))])] 20440 "optimize_size" 20441 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20442 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))]) 20443 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20444 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20445 "") 20446 20447;; Convert compares with 1 to shorter inc/dec operations when CF is not 20448;; required and register dies. Similarly for 128 to plus -128. 20449(define_peephole2 20450 [(set (match_operand 0 "flags_reg_operand" "") 20451 (match_operator 1 "compare_operator" 20452 [(match_operand 2 "register_operand" "") 20453 (match_operand 3 "const_int_operand" "")]))] 20454 "(INTVAL (operands[3]) == -1 20455 || INTVAL (operands[3]) == 1 20456 || INTVAL (operands[3]) == 128) 20457 && ix86_match_ccmode (insn, CCGCmode) 20458 && peep2_reg_dead_p (1, operands[2])" 20459 [(parallel [(set (match_dup 0) 20460 (match_op_dup 1 [(match_dup 2) (match_dup 3)])) 20461 (clobber (match_dup 2))])] 20462 "") 20463 20464(define_peephole2 20465 [(match_scratch:DI 0 "r") 20466 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 20467 (clobber (reg:CC FLAGS_REG)) 20468 (clobber (mem:BLK (scratch)))])] 20469 "optimize_size || !TARGET_SUB_ESP_4" 20470 [(clobber (match_dup 0)) 20471 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 20472 (clobber (mem:BLK (scratch)))])]) 20473 20474(define_peephole2 20475 [(match_scratch:DI 0 "r") 20476 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16))) 20477 (clobber (reg:CC FLAGS_REG)) 20478 (clobber (mem:BLK (scratch)))])] 20479 "optimize_size || !TARGET_SUB_ESP_8" 20480 [(clobber (match_dup 0)) 20481 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 20482 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 20483 (clobber (mem:BLK (scratch)))])]) 20484 20485;; Convert esp subtractions to push. 20486(define_peephole2 20487 [(match_scratch:DI 0 "r") 20488 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 20489 (clobber (reg:CC FLAGS_REG))])] 20490 "optimize_size || !TARGET_SUB_ESP_4" 20491 [(clobber (match_dup 0)) 20492 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))]) 20493 20494(define_peephole2 20495 [(match_scratch:DI 0 "r") 20496 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16))) 20497 (clobber (reg:CC FLAGS_REG))])] 20498 "optimize_size || !TARGET_SUB_ESP_8" 20499 [(clobber (match_dup 0)) 20500 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 20501 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))]) 20502 20503;; Convert epilogue deallocator to pop. 20504(define_peephole2 20505 [(match_scratch:DI 0 "r") 20506 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20507 (clobber (reg:CC FLAGS_REG)) 20508 (clobber (mem:BLK (scratch)))])] 20509 "optimize_size || !TARGET_ADD_ESP_4" 20510 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20511 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20512 (clobber (mem:BLK (scratch)))])] 20513 "") 20514 20515;; Two pops case is tricky, since pop causes dependency on destination register. 20516;; We use two registers if available. 20517(define_peephole2 20518 [(match_scratch:DI 0 "r") 20519 (match_scratch:DI 1 "r") 20520 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20521 (clobber (reg:CC FLAGS_REG)) 20522 (clobber (mem:BLK (scratch)))])] 20523 "optimize_size || !TARGET_ADD_ESP_8" 20524 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20525 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20526 (clobber (mem:BLK (scratch)))]) 20527 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG))) 20528 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20529 "") 20530 20531(define_peephole2 20532 [(match_scratch:DI 0 "r") 20533 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20534 (clobber (reg:CC FLAGS_REG)) 20535 (clobber (mem:BLK (scratch)))])] 20536 "optimize_size" 20537 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20538 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20539 (clobber (mem:BLK (scratch)))]) 20540 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20541 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20542 "") 20543 20544;; Convert esp additions to pop. 20545(define_peephole2 20546 [(match_scratch:DI 0 "r") 20547 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20548 (clobber (reg:CC FLAGS_REG))])] 20549 "" 20550 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20551 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20552 "") 20553 20554;; Two pops case is tricky, since pop causes dependency on destination register. 20555;; We use two registers if available. 20556(define_peephole2 20557 [(match_scratch:DI 0 "r") 20558 (match_scratch:DI 1 "r") 20559 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20560 (clobber (reg:CC FLAGS_REG))])] 20561 "" 20562 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20563 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))]) 20564 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG))) 20565 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20566 "") 20567 20568(define_peephole2 20569 [(match_scratch:DI 0 "r") 20570 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20571 (clobber (reg:CC FLAGS_REG))])] 20572 "optimize_size" 20573 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20574 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))]) 20575 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20576 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20577 "") 20578 20579;; Convert imul by three, five and nine into lea 20580(define_peephole2 20581 [(parallel 20582 [(set (match_operand:SI 0 "register_operand" "") 20583 (mult:SI (match_operand:SI 1 "register_operand" "") 20584 (match_operand:SI 2 "const_int_operand" ""))) 20585 (clobber (reg:CC FLAGS_REG))])] 20586 "INTVAL (operands[2]) == 3 20587 || INTVAL (operands[2]) == 5 20588 || INTVAL (operands[2]) == 9" 20589 [(set (match_dup 0) 20590 (plus:SI (mult:SI (match_dup 1) (match_dup 2)) 20591 (match_dup 1)))] 20592 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20593 20594(define_peephole2 20595 [(parallel 20596 [(set (match_operand:SI 0 "register_operand" "") 20597 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "") 20598 (match_operand:SI 2 "const_int_operand" ""))) 20599 (clobber (reg:CC FLAGS_REG))])] 20600 "!optimize_size 20601 && (INTVAL (operands[2]) == 3 20602 || INTVAL (operands[2]) == 5 20603 || INTVAL (operands[2]) == 9)" 20604 [(set (match_dup 0) (match_dup 1)) 20605 (set (match_dup 0) 20606 (plus:SI (mult:SI (match_dup 0) (match_dup 2)) 20607 (match_dup 0)))] 20608 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20609 20610(define_peephole2 20611 [(parallel 20612 [(set (match_operand:DI 0 "register_operand" "") 20613 (mult:DI (match_operand:DI 1 "register_operand" "") 20614 (match_operand:DI 2 "const_int_operand" ""))) 20615 (clobber (reg:CC FLAGS_REG))])] 20616 "TARGET_64BIT 20617 && (INTVAL (operands[2]) == 3 20618 || INTVAL (operands[2]) == 5 20619 || INTVAL (operands[2]) == 9)" 20620 [(set (match_dup 0) 20621 (plus:DI (mult:DI (match_dup 1) (match_dup 2)) 20622 (match_dup 1)))] 20623 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20624 20625(define_peephole2 20626 [(parallel 20627 [(set (match_operand:DI 0 "register_operand" "") 20628 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "") 20629 (match_operand:DI 2 "const_int_operand" ""))) 20630 (clobber (reg:CC FLAGS_REG))])] 20631 "TARGET_64BIT 20632 && !optimize_size 20633 && (INTVAL (operands[2]) == 3 20634 || INTVAL (operands[2]) == 5 20635 || INTVAL (operands[2]) == 9)" 20636 [(set (match_dup 0) (match_dup 1)) 20637 (set (match_dup 0) 20638 (plus:DI (mult:DI (match_dup 0) (match_dup 2)) 20639 (match_dup 0)))] 20640 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20641 20642;; Imul $32bit_imm, mem, reg is vector decoded, while 20643;; imul $32bit_imm, reg, reg is direct decoded. 20644(define_peephole2 20645 [(match_scratch:DI 3 "r") 20646 (parallel [(set (match_operand:DI 0 "register_operand" "") 20647 (mult:DI (match_operand:DI 1 "memory_operand" "") 20648 (match_operand:DI 2 "immediate_operand" ""))) 20649 (clobber (reg:CC FLAGS_REG))])] 20650 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size 20651 && !satisfies_constraint_K (operands[2])" 20652 [(set (match_dup 3) (match_dup 1)) 20653 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2))) 20654 (clobber (reg:CC FLAGS_REG))])] 20655"") 20656 20657(define_peephole2 20658 [(match_scratch:SI 3 "r") 20659 (parallel [(set (match_operand:SI 0 "register_operand" "") 20660 (mult:SI (match_operand:SI 1 "memory_operand" "") 20661 (match_operand:SI 2 "immediate_operand" ""))) 20662 (clobber (reg:CC FLAGS_REG))])] 20663 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size 20664 && !satisfies_constraint_K (operands[2])" 20665 [(set (match_dup 3) (match_dup 1)) 20666 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2))) 20667 (clobber (reg:CC FLAGS_REG))])] 20668"") 20669 20670(define_peephole2 20671 [(match_scratch:SI 3 "r") 20672 (parallel [(set (match_operand:DI 0 "register_operand" "") 20673 (zero_extend:DI 20674 (mult:SI (match_operand:SI 1 "memory_operand" "") 20675 (match_operand:SI 2 "immediate_operand" "")))) 20676 (clobber (reg:CC FLAGS_REG))])] 20677 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size 20678 && !satisfies_constraint_K (operands[2])" 20679 [(set (match_dup 3) (match_dup 1)) 20680 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2)))) 20681 (clobber (reg:CC FLAGS_REG))])] 20682"") 20683 20684;; imul $8/16bit_imm, regmem, reg is vector decoded. 20685;; Convert it into imul reg, reg 20686;; It would be better to force assembler to encode instruction using long 20687;; immediate, but there is apparently no way to do so. 20688(define_peephole2 20689 [(parallel [(set (match_operand:DI 0 "register_operand" "") 20690 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "") 20691 (match_operand:DI 2 "const_int_operand" ""))) 20692 (clobber (reg:CC FLAGS_REG))]) 20693 (match_scratch:DI 3 "r")] 20694 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size 20695 && satisfies_constraint_K (operands[2])" 20696 [(set (match_dup 3) (match_dup 2)) 20697 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3))) 20698 (clobber (reg:CC FLAGS_REG))])] 20699{ 20700 if (!rtx_equal_p (operands[0], operands[1])) 20701 emit_move_insn (operands[0], operands[1]); 20702}) 20703 20704(define_peephole2 20705 [(parallel [(set (match_operand:SI 0 "register_operand" "") 20706 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "") 20707 (match_operand:SI 2 "const_int_operand" ""))) 20708 (clobber (reg:CC FLAGS_REG))]) 20709 (match_scratch:SI 3 "r")] 20710 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size 20711 && satisfies_constraint_K (operands[2])" 20712 [(set (match_dup 3) (match_dup 2)) 20713 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3))) 20714 (clobber (reg:CC FLAGS_REG))])] 20715{ 20716 if (!rtx_equal_p (operands[0], operands[1])) 20717 emit_move_insn (operands[0], operands[1]); 20718}) 20719 20720(define_peephole2 20721 [(parallel [(set (match_operand:HI 0 "register_operand" "") 20722 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "") 20723 (match_operand:HI 2 "immediate_operand" ""))) 20724 (clobber (reg:CC FLAGS_REG))]) 20725 (match_scratch:HI 3 "r")] 20726 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size" 20727 [(set (match_dup 3) (match_dup 2)) 20728 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3))) 20729 (clobber (reg:CC FLAGS_REG))])] 20730{ 20731 if (!rtx_equal_p (operands[0], operands[1])) 20732 emit_move_insn (operands[0], operands[1]); 20733}) 20734 20735;; After splitting up read-modify operations, array accesses with memory 20736;; operands might end up in form: 20737;; sall $2, %eax 20738;; movl 4(%esp), %edx 20739;; addl %edx, %eax 20740;; instead of pre-splitting: 20741;; sall $2, %eax 20742;; addl 4(%esp), %eax 20743;; Turn it into: 20744;; movl 4(%esp), %edx 20745;; leal (%edx,%eax,4), %eax 20746 20747(define_peephole2 20748 [(parallel [(set (match_operand 0 "register_operand" "") 20749 (ashift (match_operand 1 "register_operand" "") 20750 (match_operand 2 "const_int_operand" ""))) 20751 (clobber (reg:CC FLAGS_REG))]) 20752 (set (match_operand 3 "register_operand") 20753 (match_operand 4 "x86_64_general_operand" "")) 20754 (parallel [(set (match_operand 5 "register_operand" "") 20755 (plus (match_operand 6 "register_operand" "") 20756 (match_operand 7 "register_operand" ""))) 20757 (clobber (reg:CC FLAGS_REG))])] 20758 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3 20759 /* Validate MODE for lea. */ 20760 && ((!TARGET_PARTIAL_REG_STALL 20761 && (GET_MODE (operands[0]) == QImode 20762 || GET_MODE (operands[0]) == HImode)) 20763 || GET_MODE (operands[0]) == SImode 20764 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) 20765 /* We reorder load and the shift. */ 20766 && !rtx_equal_p (operands[1], operands[3]) 20767 && !reg_overlap_mentioned_p (operands[0], operands[4]) 20768 /* Last PLUS must consist of operand 0 and 3. */ 20769 && !rtx_equal_p (operands[0], operands[3]) 20770 && (rtx_equal_p (operands[3], operands[6]) 20771 || rtx_equal_p (operands[3], operands[7])) 20772 && (rtx_equal_p (operands[0], operands[6]) 20773 || rtx_equal_p (operands[0], operands[7])) 20774 /* The intermediate operand 0 must die or be same as output. */ 20775 && (rtx_equal_p (operands[0], operands[5]) 20776 || peep2_reg_dead_p (3, operands[0]))" 20777 [(set (match_dup 3) (match_dup 4)) 20778 (set (match_dup 0) (match_dup 1))] 20779{ 20780 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode; 20781 int scale = 1 << INTVAL (operands[2]); 20782 rtx index = gen_lowpart (Pmode, operands[1]); 20783 rtx base = gen_lowpart (Pmode, operands[3]); 20784 rtx dest = gen_lowpart (mode, operands[5]); 20785 20786 operands[1] = gen_rtx_PLUS (Pmode, base, 20787 gen_rtx_MULT (Pmode, index, GEN_INT (scale))); 20788 if (mode != Pmode) 20789 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); 20790 operands[0] = dest; 20791}) 20792 20793;; Call-value patterns last so that the wildcard operand does not 20794;; disrupt insn-recog's switch tables. 20795 20796(define_insn "*call_value_pop_0" 20797 [(set (match_operand 0 "" "") 20798 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) 20799 (match_operand:SI 2 "" ""))) 20800 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 20801 (match_operand:SI 3 "immediate_operand" "")))] 20802 "!TARGET_64BIT" 20803{ 20804 if (SIBLING_CALL_P (insn)) 20805 return "jmp\t%P1"; 20806 else 20807 return "call\t%P1"; 20808} 20809 [(set_attr "type" "callv")]) 20810 20811(define_insn "*call_value_pop_1" 20812 [(set (match_operand 0 "" "") 20813 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm")) 20814 (match_operand:SI 2 "" ""))) 20815 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 20816 (match_operand:SI 3 "immediate_operand" "i")))] 20817 "!TARGET_64BIT" 20818{ 20819 if (constant_call_address_operand (operands[1], Pmode)) 20820 { 20821 if (SIBLING_CALL_P (insn)) 20822 return "jmp\t%P1"; 20823 else 20824 return "call\t%P1"; 20825 } 20826 if (SIBLING_CALL_P (insn)) 20827 return "jmp\t%A1"; 20828 else 20829 return "call\t%A1"; 20830} 20831 [(set_attr "type" "callv")]) 20832 20833(define_insn "*call_value_0" 20834 [(set (match_operand 0 "" "") 20835 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) 20836 (match_operand:SI 2 "" "")))] 20837 "!TARGET_64BIT" 20838{ 20839 if (SIBLING_CALL_P (insn)) 20840 return "jmp\t%P1"; 20841 else 20842 return "call\t%P1"; 20843} 20844 [(set_attr "type" "callv")]) 20845 20846(define_insn "*call_value_0_rex64" 20847 [(set (match_operand 0 "" "") 20848 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) 20849 (match_operand:DI 2 "const_int_operand" "")))] 20850 "TARGET_64BIT" 20851{ 20852 if (SIBLING_CALL_P (insn)) 20853 return "jmp\t%P1"; 20854 else 20855 return "call\t%P1"; 20856} 20857 [(set_attr "type" "callv")]) 20858 20859(define_insn "*call_value_1" 20860 [(set (match_operand 0 "" "") 20861 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm")) 20862 (match_operand:SI 2 "" "")))] 20863 "!SIBLING_CALL_P (insn) && !TARGET_64BIT" 20864{ 20865 if (constant_call_address_operand (operands[1], Pmode)) 20866 return "call\t%P1"; 20867 return "call\t%A1"; 20868} 20869 [(set_attr "type" "callv")]) 20870 20871(define_insn "*sibcall_value_1" 20872 [(set (match_operand 0 "" "") 20873 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a")) 20874 (match_operand:SI 2 "" "")))] 20875 "SIBLING_CALL_P (insn) && !TARGET_64BIT" 20876{ 20877 if (constant_call_address_operand (operands[1], Pmode)) 20878 return "jmp\t%P1"; 20879 return "jmp\t%A1"; 20880} 20881 [(set_attr "type" "callv")]) 20882 20883(define_insn "*call_value_1_rex64" 20884 [(set (match_operand 0 "" "") 20885 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm")) 20886 (match_operand:DI 2 "" "")))] 20887 "!SIBLING_CALL_P (insn) && TARGET_64BIT" 20888{ 20889 if (constant_call_address_operand (operands[1], Pmode)) 20890 return "call\t%P1"; 20891 return "call\t%A1"; 20892} 20893 [(set_attr "type" "callv")]) 20894 20895(define_insn "*sibcall_value_1_rex64" 20896 [(set (match_operand 0 "" "") 20897 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) 20898 (match_operand:DI 2 "" "")))] 20899 "SIBLING_CALL_P (insn) && TARGET_64BIT" 20900 "jmp\t%P1" 20901 [(set_attr "type" "callv")]) 20902 20903(define_insn "*sibcall_value_1_rex64_v" 20904 [(set (match_operand 0 "" "") 20905 (call (mem:QI (reg:DI R11_REG)) 20906 (match_operand:DI 1 "" "")))] 20907 "SIBLING_CALL_P (insn) && TARGET_64BIT" 20908 "jmp\t*%%r11" 20909 [(set_attr "type" "callv")]) 20910 20911;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5. 20912;; That, however, is usually mapped by the OS to SIGSEGV, which is often 20913;; caught for use by garbage collectors and the like. Using an insn that 20914;; maps to SIGILL makes it more likely the program will rightfully die. 20915;; Keeping with tradition, "6" is in honor of #UD. 20916(define_insn "trap" 20917 [(trap_if (const_int 1) (const_int 6))] 20918 "" 20919 { return ASM_SHORT "0x0b0f"; } 20920 [(set_attr "length" "2")]) 20921 20922(define_expand "sse_prologue_save" 20923 [(parallel [(set (match_operand:BLK 0 "" "") 20924 (unspec:BLK [(reg:DI 22) 20925 (reg:DI 23) 20926 (reg:DI 24) 20927 (reg:DI 25) 20928 (reg:DI 26) 20929 (reg:DI 27) 20930 (reg:DI 28) 20931 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE)) 20932 (use (match_operand:DI 1 "register_operand" "")) 20933 (use (match_operand:DI 2 "immediate_operand" "")) 20934 (use (label_ref:DI (match_operand 3 "" "")))])] 20935 "TARGET_64BIT" 20936 "") 20937 20938(define_insn "*sse_prologue_save_insn" 20939 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R") 20940 (match_operand:DI 4 "const_int_operand" "n"))) 20941 (unspec:BLK [(reg:DI 22) 20942 (reg:DI 23) 20943 (reg:DI 24) 20944 (reg:DI 25) 20945 (reg:DI 26) 20946 (reg:DI 27) 20947 (reg:DI 28) 20948 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE)) 20949 (use (match_operand:DI 1 "register_operand" "r")) 20950 (use (match_operand:DI 2 "const_int_operand" "i")) 20951 (use (label_ref:DI (match_operand 3 "" "X")))] 20952 "TARGET_64BIT 20953 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128 20954 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128" 20955 "* 20956{ 20957 int i; 20958 operands[0] = gen_rtx_MEM (Pmode, 20959 gen_rtx_PLUS (Pmode, operands[0], operands[4])); 20960 output_asm_insn (\"jmp\\t%A1\", operands); 20961 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--) 20962 { 20963 operands[4] = adjust_address (operands[0], DImode, i*16); 20964 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i)); 20965 PUT_MODE (operands[4], TImode); 20966 if (GET_CODE (XEXP (operands[0], 0)) != PLUS) 20967 output_asm_insn (\"rex\", operands); 20968 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands); 20969 } 20970 (*targetm.asm_out.internal_label) (asm_out_file, \"L\", 20971 CODE_LABEL_NUMBER (operands[3])); 20972 RET; 20973} 20974 " 20975 [(set_attr "type" "other") 20976 (set_attr "length_immediate" "0") 20977 (set_attr "length_address" "0") 20978 (set_attr "length" "135") 20979 (set_attr "memory" "store") 20980 (set_attr "modrm" "0") 20981 (set_attr "mode" "DI")]) 20982 20983(define_expand "prefetch" 20984 [(prefetch (match_operand 0 "address_operand" "") 20985 (match_operand:SI 1 "const_int_operand" "") 20986 (match_operand:SI 2 "const_int_operand" ""))] 20987 "TARGET_PREFETCH_SSE || TARGET_3DNOW" 20988{ 20989 int rw = INTVAL (operands[1]); 20990 int locality = INTVAL (operands[2]); 20991 20992 gcc_assert (rw == 0 || rw == 1); 20993 gcc_assert (locality >= 0 && locality <= 3); 20994 gcc_assert (GET_MODE (operands[0]) == Pmode 20995 || GET_MODE (operands[0]) == VOIDmode); 20996 20997 /* Use 3dNOW prefetch in case we are asking for write prefetch not 20998 supported by SSE counterpart or the SSE prefetch is not available 20999 (K6 machines). Otherwise use SSE prefetch as it allows specifying 21000 of locality. */ 21001 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw)) 21002 operands[2] = GEN_INT (3); 21003 else 21004 operands[1] = const0_rtx; 21005}) 21006 21007(define_insn "*prefetch_sse" 21008 [(prefetch (match_operand:SI 0 "address_operand" "p") 21009 (const_int 0) 21010 (match_operand:SI 1 "const_int_operand" ""))] 21011 "TARGET_PREFETCH_SSE && !TARGET_64BIT" 21012{ 21013 static const char * const patterns[4] = { 21014 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" 21015 }; 21016 21017 int locality = INTVAL (operands[1]); 21018 gcc_assert (locality >= 0 && locality <= 3); 21019 21020 return patterns[locality]; 21021} 21022 [(set_attr "type" "sse") 21023 (set_attr "memory" "none")]) 21024 21025(define_insn "*prefetch_sse_rex" 21026 [(prefetch (match_operand:DI 0 "address_operand" "p") 21027 (const_int 0) 21028 (match_operand:SI 1 "const_int_operand" ""))] 21029 "TARGET_PREFETCH_SSE && TARGET_64BIT" 21030{ 21031 static const char * const patterns[4] = { 21032 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" 21033 }; 21034 21035 int locality = INTVAL (operands[1]); 21036 gcc_assert (locality >= 0 && locality <= 3); 21037 21038 return patterns[locality]; 21039} 21040 [(set_attr "type" "sse") 21041 (set_attr "memory" "none")]) 21042 21043(define_insn "*prefetch_3dnow" 21044 [(prefetch (match_operand:SI 0 "address_operand" "p") 21045 (match_operand:SI 1 "const_int_operand" "n") 21046 (const_int 3))] 21047 "TARGET_3DNOW && !TARGET_64BIT" 21048{ 21049 if (INTVAL (operands[1]) == 0) 21050 return "prefetch\t%a0"; 21051 else 21052 return "prefetchw\t%a0"; 21053} 21054 [(set_attr "type" "mmx") 21055 (set_attr "memory" "none")]) 21056 21057(define_insn "*prefetch_3dnow_rex" 21058 [(prefetch (match_operand:DI 0 "address_operand" "p") 21059 (match_operand:SI 1 "const_int_operand" "n") 21060 (const_int 3))] 21061 "TARGET_3DNOW && TARGET_64BIT" 21062{ 21063 if (INTVAL (operands[1]) == 0) 21064 return "prefetch\t%a0"; 21065 else 21066 return "prefetchw\t%a0"; 21067} 21068 [(set_attr "type" "mmx") 21069 (set_attr "memory" "none")]) 21070 21071(define_expand "stack_protect_set" 21072 [(match_operand 0 "memory_operand" "") 21073 (match_operand 1 "memory_operand" "")] 21074 "" 21075{ 21076#ifdef TARGET_THREAD_SSP_OFFSET 21077 if (TARGET_64BIT) 21078 emit_insn (gen_stack_tls_protect_set_di (operands[0], 21079 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 21080 else 21081 emit_insn (gen_stack_tls_protect_set_si (operands[0], 21082 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 21083#else 21084 if (TARGET_64BIT) 21085 emit_insn (gen_stack_protect_set_di (operands[0], operands[1])); 21086 else 21087 emit_insn (gen_stack_protect_set_si (operands[0], operands[1])); 21088#endif 21089 DONE; 21090}) 21091 21092(define_insn "stack_protect_set_si" 21093 [(set (match_operand:SI 0 "memory_operand" "=m") 21094 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 21095 (set (match_scratch:SI 2 "=&r") (const_int 0)) 21096 (clobber (reg:CC FLAGS_REG))] 21097 "" 21098 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2" 21099 [(set_attr "type" "multi")]) 21100 21101(define_insn "stack_protect_set_di" 21102 [(set (match_operand:DI 0 "memory_operand" "=m") 21103 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 21104 (set (match_scratch:DI 2 "=&r") (const_int 0)) 21105 (clobber (reg:CC FLAGS_REG))] 21106 "TARGET_64BIT" 21107 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" 21108 [(set_attr "type" "multi")]) 21109 21110(define_insn "stack_tls_protect_set_si" 21111 [(set (match_operand:SI 0 "memory_operand" "=m") 21112 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET)) 21113 (set (match_scratch:SI 2 "=&r") (const_int 0)) 21114 (clobber (reg:CC FLAGS_REG))] 21115 "" 21116 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2" 21117 [(set_attr "type" "multi")]) 21118 21119(define_insn "stack_tls_protect_set_di" 21120 [(set (match_operand:DI 0 "memory_operand" "=m") 21121 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET)) 21122 (set (match_scratch:DI 2 "=&r") (const_int 0)) 21123 (clobber (reg:CC FLAGS_REG))] 21124 "TARGET_64BIT" 21125 { 21126 /* The kernel uses a different segment register for performance reasons; a 21127 system call would not have to trash the userspace segment register, 21128 which would be expensive */ 21129 if (ix86_cmodel != CM_KERNEL) 21130 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"; 21131 else 21132 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"; 21133 } 21134 [(set_attr "type" "multi")]) 21135 21136(define_expand "stack_protect_test" 21137 [(match_operand 0 "memory_operand" "") 21138 (match_operand 1 "memory_operand" "") 21139 (match_operand 2 "" "")] 21140 "" 21141{ 21142 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG); 21143 ix86_compare_op0 = operands[0]; 21144 ix86_compare_op1 = operands[1]; 21145 ix86_compare_emitted = flags; 21146 21147#ifdef TARGET_THREAD_SSP_OFFSET 21148 if (TARGET_64BIT) 21149 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0], 21150 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 21151 else 21152 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0], 21153 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 21154#else 21155 if (TARGET_64BIT) 21156 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1])); 21157 else 21158 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1])); 21159#endif 21160 emit_jump_insn (gen_beq (operands[2])); 21161 DONE; 21162}) 21163 21164(define_insn "stack_protect_test_si" 21165 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 21166 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m") 21167 (match_operand:SI 2 "memory_operand" "m")] 21168 UNSPEC_SP_TEST)) 21169 (clobber (match_scratch:SI 3 "=&r"))] 21170 "" 21171 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}" 21172 [(set_attr "type" "multi")]) 21173 21174(define_insn "stack_protect_test_di" 21175 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 21176 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m") 21177 (match_operand:DI 2 "memory_operand" "m")] 21178 UNSPEC_SP_TEST)) 21179 (clobber (match_scratch:DI 3 "=&r"))] 21180 "TARGET_64BIT" 21181 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}" 21182 [(set_attr "type" "multi")]) 21183 21184(define_insn "stack_tls_protect_test_si" 21185 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 21186 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m") 21187 (match_operand:SI 2 "const_int_operand" "i")] 21188 UNSPEC_SP_TLS_TEST)) 21189 (clobber (match_scratch:SI 3 "=r"))] 21190 "" 21191 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}" 21192 [(set_attr "type" "multi")]) 21193 21194(define_insn "stack_tls_protect_test_di" 21195 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 21196 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m") 21197 (match_operand:DI 2 "const_int_operand" "i")] 21198 UNSPEC_SP_TLS_TEST)) 21199 (clobber (match_scratch:DI 3 "=r"))] 21200 "TARGET_64BIT" 21201 { 21202 /* The kernel uses a different segment register for performance reasons; a 21203 system call would not have to trash the userspace segment register, 21204 which would be expensive */ 21205 if (ix86_cmodel != CM_KERNEL) 21206 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"; 21207 else 21208 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}"; 21209 } 21210 [(set_attr "type" "multi")]) 21211 21212(include "mmx.md") 21213(include "sse.md") 21214(include "sync.md") 21215