i386.md revision 219374
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_LDQQU 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 153(define_constants 154 [(UNSPECV_BLOCKAGE 0) 155 (UNSPECV_STACK_PROBE 1) 156 (UNSPECV_EMMS 2) 157 (UNSPECV_LDMXCSR 3) 158 (UNSPECV_STMXCSR 4) 159 (UNSPECV_FEMMS 5) 160 (UNSPECV_CLFLUSH 6) 161 (UNSPECV_ALIGN 7) 162 (UNSPECV_MONITOR 8) 163 (UNSPECV_MWAIT 9) 164 (UNSPECV_CMPXCHG_1 10) 165 (UNSPECV_CMPXCHG_2 11) 166 (UNSPECV_XCHG 12) 167 (UNSPECV_LOCK 13) 168 ]) 169 170;; Registers by name. 171(define_constants 172 [(BP_REG 6) 173 (SP_REG 7) 174 (FLAGS_REG 17) 175 (FPSR_REG 18) 176 (DIRFLAG_REG 19) 177 ]) 178 179;; Insns whose names begin with "x86_" are emitted by gen_FOO calls 180;; from i386.c. 181 182;; In C guard expressions, put expressions which may be compile-time 183;; constants first. This allows for better optimization. For 184;; example, write "TARGET_64BIT && reload_completed", not 185;; "reload_completed && TARGET_64BIT". 186 187 188;; Processor type. This attribute must exactly match the processor_type 189;; enumeration in i386.h. 190(define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64" 191 (const (symbol_ref "ix86_tune"))) 192 193;; A basic instruction type. Refinements due to arguments to be 194;; provided in other attributes. 195(define_attr "type" 196 "other,multi, 197 alu,alu1,negnot,imov,imovx,lea, 198 incdec,ishift,ishift1,rotate,rotate1,imul,idiv, 199 icmp,test,ibr,setcc,icmov, 200 push,pop,call,callv,leave, 201 str,cld, 202 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint, 203 sselog,sselog1,sseiadd,sseishft,sseimul, 204 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv, 205 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft" 206 (const_string "other")) 207 208;; Main data type used by the insn 209(define_attr "mode" 210 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF" 211 (const_string "unknown")) 212 213;; The CPU unit operations uses. 214(define_attr "unit" "integer,i387,sse,mmx,unknown" 215 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint") 216 (const_string "i387") 217 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul, 218 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv") 219 (const_string "sse") 220 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft") 221 (const_string "mmx") 222 (eq_attr "type" "other") 223 (const_string "unknown")] 224 (const_string "integer"))) 225 226;; The (bounding maximum) length of an instruction immediate. 227(define_attr "length_immediate" "" 228 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave") 229 (const_int 0) 230 (eq_attr "unit" "i387,sse,mmx") 231 (const_int 0) 232 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1, 233 imul,icmp,push,pop") 234 (symbol_ref "ix86_attr_length_immediate_default(insn,1)") 235 (eq_attr "type" "imov,test") 236 (symbol_ref "ix86_attr_length_immediate_default(insn,0)") 237 (eq_attr "type" "call") 238 (if_then_else (match_operand 0 "constant_call_address_operand" "") 239 (const_int 4) 240 (const_int 0)) 241 (eq_attr "type" "callv") 242 (if_then_else (match_operand 1 "constant_call_address_operand" "") 243 (const_int 4) 244 (const_int 0)) 245 ;; We don't know the size before shorten_branches. Expect 246 ;; the instruction to fit for better scheduling. 247 (eq_attr "type" "ibr") 248 (const_int 1) 249 ] 250 (symbol_ref "/* Update immediate_length and other attributes! */ 251 gcc_unreachable (),1"))) 252 253;; The (bounding maximum) length of an instruction address. 254(define_attr "length_address" "" 255 (cond [(eq_attr "type" "str,cld,other,multi,fxch") 256 (const_int 0) 257 (and (eq_attr "type" "call") 258 (match_operand 0 "constant_call_address_operand" "")) 259 (const_int 0) 260 (and (eq_attr "type" "callv") 261 (match_operand 1 "constant_call_address_operand" "")) 262 (const_int 0) 263 ] 264 (symbol_ref "ix86_attr_length_address_default (insn)"))) 265 266;; Set when length prefix is used. 267(define_attr "prefix_data16" "" 268 (if_then_else (ior (eq_attr "mode" "HI") 269 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF"))) 270 (const_int 1) 271 (const_int 0))) 272 273;; Set when string REP prefix is used. 274(define_attr "prefix_rep" "" 275 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF")) 276 (const_int 1) 277 (const_int 0))) 278 279;; Set when 0f opcode prefix is used. 280(define_attr "prefix_0f" "" 281 (if_then_else 282 (ior (eq_attr "type" "imovx,setcc,icmov") 283 (eq_attr "unit" "sse,mmx")) 284 (const_int 1) 285 (const_int 0))) 286 287;; Set when REX opcode prefix is used. 288(define_attr "prefix_rex" "" 289 (cond [(and (eq_attr "mode" "DI") 290 (eq_attr "type" "!push,pop,call,callv,leave,ibr")) 291 (const_int 1) 292 (and (eq_attr "mode" "QI") 293 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)") 294 (const_int 0))) 295 (const_int 1) 296 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)") 297 (const_int 0)) 298 (const_int 1) 299 ] 300 (const_int 0))) 301 302;; Set when modrm byte is used. 303(define_attr "modrm" "" 304 (cond [(eq_attr "type" "str,cld,leave") 305 (const_int 0) 306 (eq_attr "unit" "i387") 307 (const_int 0) 308 (and (eq_attr "type" "incdec") 309 (ior (match_operand:SI 1 "register_operand" "") 310 (match_operand:HI 1 "register_operand" ""))) 311 (const_int 0) 312 (and (eq_attr "type" "push") 313 (not (match_operand 1 "memory_operand" ""))) 314 (const_int 0) 315 (and (eq_attr "type" "pop") 316 (not (match_operand 0 "memory_operand" ""))) 317 (const_int 0) 318 (and (eq_attr "type" "imov") 319 (ior (and (match_operand 0 "register_operand" "") 320 (match_operand 1 "immediate_operand" "")) 321 (ior (and (match_operand 0 "ax_reg_operand" "") 322 (match_operand 1 "memory_displacement_only_operand" "")) 323 (and (match_operand 0 "memory_displacement_only_operand" "") 324 (match_operand 1 "ax_reg_operand" ""))))) 325 (const_int 0) 326 (and (eq_attr "type" "call") 327 (match_operand 0 "constant_call_address_operand" "")) 328 (const_int 0) 329 (and (eq_attr "type" "callv") 330 (match_operand 1 "constant_call_address_operand" "")) 331 (const_int 0) 332 ] 333 (const_int 1))) 334 335;; The (bounding maximum) length of an instruction in bytes. 336;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences. 337;; Later we may want to split them and compute proper length as for 338;; other insns. 339(define_attr "length" "" 340 (cond [(eq_attr "type" "other,multi,fistp,frndint") 341 (const_int 16) 342 (eq_attr "type" "fcmp") 343 (const_int 4) 344 (eq_attr "unit" "i387") 345 (plus (const_int 2) 346 (plus (attr "prefix_data16") 347 (attr "length_address")))] 348 (plus (plus (attr "modrm") 349 (plus (attr "prefix_0f") 350 (plus (attr "prefix_rex") 351 (const_int 1)))) 352 (plus (attr "prefix_rep") 353 (plus (attr "prefix_data16") 354 (plus (attr "length_immediate") 355 (attr "length_address"))))))) 356 357;; The `memory' attribute is `none' if no memory is referenced, `load' or 358;; `store' if there is a simple memory reference therein, or `unknown' 359;; if the instruction is complex. 360 361(define_attr "memory" "none,load,store,both,unknown" 362 (cond [(eq_attr "type" "other,multi,str") 363 (const_string "unknown") 364 (eq_attr "type" "lea,fcmov,fpspc,cld") 365 (const_string "none") 366 (eq_attr "type" "fistp,leave") 367 (const_string "both") 368 (eq_attr "type" "frndint") 369 (const_string "load") 370 (eq_attr "type" "push") 371 (if_then_else (match_operand 1 "memory_operand" "") 372 (const_string "both") 373 (const_string "store")) 374 (eq_attr "type" "pop") 375 (if_then_else (match_operand 0 "memory_operand" "") 376 (const_string "both") 377 (const_string "load")) 378 (eq_attr "type" "setcc") 379 (if_then_else (match_operand 0 "memory_operand" "") 380 (const_string "store") 381 (const_string "none")) 382 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp") 383 (if_then_else (ior (match_operand 0 "memory_operand" "") 384 (match_operand 1 "memory_operand" "")) 385 (const_string "load") 386 (const_string "none")) 387 (eq_attr "type" "ibr") 388 (if_then_else (match_operand 0 "memory_operand" "") 389 (const_string "load") 390 (const_string "none")) 391 (eq_attr "type" "call") 392 (if_then_else (match_operand 0 "constant_call_address_operand" "") 393 (const_string "none") 394 (const_string "load")) 395 (eq_attr "type" "callv") 396 (if_then_else (match_operand 1 "constant_call_address_operand" "") 397 (const_string "none") 398 (const_string "load")) 399 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1") 400 (match_operand 1 "memory_operand" "")) 401 (const_string "both") 402 (and (match_operand 0 "memory_operand" "") 403 (match_operand 1 "memory_operand" "")) 404 (const_string "both") 405 (match_operand 0 "memory_operand" "") 406 (const_string "store") 407 (match_operand 1 "memory_operand" "") 408 (const_string "load") 409 (and (eq_attr "type" 410 "!alu1,negnot,ishift1, 411 imov,imovx,icmp,test, 412 fmov,fcmp,fsgn, 413 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1, 414 mmx,mmxmov,mmxcmp,mmxcvt") 415 (match_operand 2 "memory_operand" "")) 416 (const_string "load") 417 (and (eq_attr "type" "icmov") 418 (match_operand 3 "memory_operand" "")) 419 (const_string "load") 420 ] 421 (const_string "none"))) 422 423;; Indicates if an instruction has both an immediate and a displacement. 424 425(define_attr "imm_disp" "false,true,unknown" 426 (cond [(eq_attr "type" "other,multi") 427 (const_string "unknown") 428 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1") 429 (and (match_operand 0 "memory_displacement_operand" "") 430 (match_operand 1 "immediate_operand" ""))) 431 (const_string "true") 432 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv") 433 (and (match_operand 0 "memory_displacement_operand" "") 434 (match_operand 2 "immediate_operand" ""))) 435 (const_string "true") 436 ] 437 (const_string "false"))) 438 439;; Indicates if an FP operation has an integer source. 440 441(define_attr "fp_int_src" "false,true" 442 (const_string "false")) 443 444;; Defines rounding mode of an FP operation. 445 446(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any" 447 (const_string "any")) 448 449;; Describe a user's asm statement. 450(define_asm_attributes 451 [(set_attr "length" "128") 452 (set_attr "type" "multi")]) 453 454;; All x87 floating point modes 455(define_mode_macro X87MODEF [SF DF XF]) 456 457;; All integer modes handled by x87 fisttp operator. 458(define_mode_macro X87MODEI [HI SI DI]) 459 460;; All integer modes handled by integer x87 operators. 461(define_mode_macro X87MODEI12 [HI SI]) 462 463;; All SSE floating point modes 464(define_mode_macro SSEMODEF [SF DF]) 465 466;; All integer modes handled by SSE cvtts?2si* operators. 467(define_mode_macro SSEMODEI24 [SI DI]) 468 469 470;; Scheduling descriptions 471 472(include "pentium.md") 473(include "ppro.md") 474(include "k6.md") 475(include "athlon.md") 476(include "geode.md") 477 478 479;; Operand and operator predicates and constraints 480 481(include "predicates.md") 482(include "constraints.md") 483 484 485;; Compare instructions. 486 487;; All compare insns have expanders that save the operands away without 488;; actually generating RTL. The bCOND or sCOND (emitted immediately 489;; after the cmp) will actually emit the cmpM. 490 491(define_expand "cmpti" 492 [(set (reg:CC FLAGS_REG) 493 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "") 494 (match_operand:TI 1 "x86_64_general_operand" "")))] 495 "TARGET_64BIT" 496{ 497 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 498 operands[0] = force_reg (TImode, operands[0]); 499 ix86_compare_op0 = operands[0]; 500 ix86_compare_op1 = operands[1]; 501 DONE; 502}) 503 504(define_expand "cmpdi" 505 [(set (reg:CC FLAGS_REG) 506 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "") 507 (match_operand:DI 1 "x86_64_general_operand" "")))] 508 "" 509{ 510 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 511 operands[0] = force_reg (DImode, operands[0]); 512 ix86_compare_op0 = operands[0]; 513 ix86_compare_op1 = operands[1]; 514 DONE; 515}) 516 517(define_expand "cmpsi" 518 [(set (reg:CC FLAGS_REG) 519 (compare:CC (match_operand:SI 0 "cmpsi_operand" "") 520 (match_operand:SI 1 "general_operand" "")))] 521 "" 522{ 523 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 524 operands[0] = force_reg (SImode, operands[0]); 525 ix86_compare_op0 = operands[0]; 526 ix86_compare_op1 = operands[1]; 527 DONE; 528}) 529 530(define_expand "cmphi" 531 [(set (reg:CC FLAGS_REG) 532 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "") 533 (match_operand:HI 1 "general_operand" "")))] 534 "" 535{ 536 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 537 operands[0] = force_reg (HImode, operands[0]); 538 ix86_compare_op0 = operands[0]; 539 ix86_compare_op1 = operands[1]; 540 DONE; 541}) 542 543(define_expand "cmpqi" 544 [(set (reg:CC FLAGS_REG) 545 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "") 546 (match_operand:QI 1 "general_operand" "")))] 547 "TARGET_QIMODE_MATH" 548{ 549 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 550 operands[0] = force_reg (QImode, operands[0]); 551 ix86_compare_op0 = operands[0]; 552 ix86_compare_op1 = operands[1]; 553 DONE; 554}) 555 556(define_insn "cmpdi_ccno_1_rex64" 557 [(set (reg FLAGS_REG) 558 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr") 559 (match_operand:DI 1 "const0_operand" "n,n")))] 560 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 561 "@ 562 test{q}\t{%0, %0|%0, %0} 563 cmp{q}\t{%1, %0|%0, %1}" 564 [(set_attr "type" "test,icmp") 565 (set_attr "length_immediate" "0,1") 566 (set_attr "mode" "DI")]) 567 568(define_insn "*cmpdi_minus_1_rex64" 569 [(set (reg FLAGS_REG) 570 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r") 571 (match_operand:DI 1 "x86_64_general_operand" "re,mr")) 572 (const_int 0)))] 573 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)" 574 "cmp{q}\t{%1, %0|%0, %1}" 575 [(set_attr "type" "icmp") 576 (set_attr "mode" "DI")]) 577 578(define_expand "cmpdi_1_rex64" 579 [(set (reg:CC FLAGS_REG) 580 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "") 581 (match_operand:DI 1 "general_operand" "")))] 582 "TARGET_64BIT" 583 "") 584 585(define_insn "cmpdi_1_insn_rex64" 586 [(set (reg FLAGS_REG) 587 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r") 588 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))] 589 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 590 "cmp{q}\t{%1, %0|%0, %1}" 591 [(set_attr "type" "icmp") 592 (set_attr "mode" "DI")]) 593 594 595(define_insn "*cmpsi_ccno_1" 596 [(set (reg FLAGS_REG) 597 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr") 598 (match_operand:SI 1 "const0_operand" "n,n")))] 599 "ix86_match_ccmode (insn, CCNOmode)" 600 "@ 601 test{l}\t{%0, %0|%0, %0} 602 cmp{l}\t{%1, %0|%0, %1}" 603 [(set_attr "type" "test,icmp") 604 (set_attr "length_immediate" "0,1") 605 (set_attr "mode" "SI")]) 606 607(define_insn "*cmpsi_minus_1" 608 [(set (reg FLAGS_REG) 609 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r") 610 (match_operand:SI 1 "general_operand" "ri,mr")) 611 (const_int 0)))] 612 "ix86_match_ccmode (insn, CCGOCmode)" 613 "cmp{l}\t{%1, %0|%0, %1}" 614 [(set_attr "type" "icmp") 615 (set_attr "mode" "SI")]) 616 617(define_expand "cmpsi_1" 618 [(set (reg:CC FLAGS_REG) 619 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r") 620 (match_operand:SI 1 "general_operand" "ri,mr")))] 621 "" 622 "") 623 624(define_insn "*cmpsi_1_insn" 625 [(set (reg FLAGS_REG) 626 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r") 627 (match_operand:SI 1 "general_operand" "ri,mr")))] 628 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 629 && ix86_match_ccmode (insn, CCmode)" 630 "cmp{l}\t{%1, %0|%0, %1}" 631 [(set_attr "type" "icmp") 632 (set_attr "mode" "SI")]) 633 634(define_insn "*cmphi_ccno_1" 635 [(set (reg FLAGS_REG) 636 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr") 637 (match_operand:HI 1 "const0_operand" "n,n")))] 638 "ix86_match_ccmode (insn, CCNOmode)" 639 "@ 640 test{w}\t{%0, %0|%0, %0} 641 cmp{w}\t{%1, %0|%0, %1}" 642 [(set_attr "type" "test,icmp") 643 (set_attr "length_immediate" "0,1") 644 (set_attr "mode" "HI")]) 645 646(define_insn "*cmphi_minus_1" 647 [(set (reg FLAGS_REG) 648 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r") 649 (match_operand:HI 1 "general_operand" "ri,mr")) 650 (const_int 0)))] 651 "ix86_match_ccmode (insn, CCGOCmode)" 652 "cmp{w}\t{%1, %0|%0, %1}" 653 [(set_attr "type" "icmp") 654 (set_attr "mode" "HI")]) 655 656(define_insn "*cmphi_1" 657 [(set (reg FLAGS_REG) 658 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r") 659 (match_operand:HI 1 "general_operand" "ri,mr")))] 660 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 661 && ix86_match_ccmode (insn, CCmode)" 662 "cmp{w}\t{%1, %0|%0, %1}" 663 [(set_attr "type" "icmp") 664 (set_attr "mode" "HI")]) 665 666(define_insn "*cmpqi_ccno_1" 667 [(set (reg FLAGS_REG) 668 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq") 669 (match_operand:QI 1 "const0_operand" "n,n")))] 670 "ix86_match_ccmode (insn, CCNOmode)" 671 "@ 672 test{b}\t{%0, %0|%0, %0} 673 cmp{b}\t{$0, %0|%0, 0}" 674 [(set_attr "type" "test,icmp") 675 (set_attr "length_immediate" "0,1") 676 (set_attr "mode" "QI")]) 677 678(define_insn "*cmpqi_1" 679 [(set (reg FLAGS_REG) 680 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q") 681 (match_operand:QI 1 "general_operand" "qi,mq")))] 682 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 683 && ix86_match_ccmode (insn, CCmode)" 684 "cmp{b}\t{%1, %0|%0, %1}" 685 [(set_attr "type" "icmp") 686 (set_attr "mode" "QI")]) 687 688(define_insn "*cmpqi_minus_1" 689 [(set (reg FLAGS_REG) 690 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q") 691 (match_operand:QI 1 "general_operand" "qi,mq")) 692 (const_int 0)))] 693 "ix86_match_ccmode (insn, CCGOCmode)" 694 "cmp{b}\t{%1, %0|%0, %1}" 695 [(set_attr "type" "icmp") 696 (set_attr "mode" "QI")]) 697 698(define_insn "*cmpqi_ext_1" 699 [(set (reg FLAGS_REG) 700 (compare 701 (match_operand:QI 0 "general_operand" "Qm") 702 (subreg:QI 703 (zero_extract:SI 704 (match_operand 1 "ext_register_operand" "Q") 705 (const_int 8) 706 (const_int 8)) 0)))] 707 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 708 "cmp{b}\t{%h1, %0|%0, %h1}" 709 [(set_attr "type" "icmp") 710 (set_attr "mode" "QI")]) 711 712(define_insn "*cmpqi_ext_1_rex64" 713 [(set (reg FLAGS_REG) 714 (compare 715 (match_operand:QI 0 "register_operand" "Q") 716 (subreg:QI 717 (zero_extract:SI 718 (match_operand 1 "ext_register_operand" "Q") 719 (const_int 8) 720 (const_int 8)) 0)))] 721 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 722 "cmp{b}\t{%h1, %0|%0, %h1}" 723 [(set_attr "type" "icmp") 724 (set_attr "mode" "QI")]) 725 726(define_insn "*cmpqi_ext_2" 727 [(set (reg FLAGS_REG) 728 (compare 729 (subreg:QI 730 (zero_extract:SI 731 (match_operand 0 "ext_register_operand" "Q") 732 (const_int 8) 733 (const_int 8)) 0) 734 (match_operand:QI 1 "const0_operand" "n")))] 735 "ix86_match_ccmode (insn, CCNOmode)" 736 "test{b}\t%h0, %h0" 737 [(set_attr "type" "test") 738 (set_attr "length_immediate" "0") 739 (set_attr "mode" "QI")]) 740 741(define_expand "cmpqi_ext_3" 742 [(set (reg:CC FLAGS_REG) 743 (compare:CC 744 (subreg:QI 745 (zero_extract:SI 746 (match_operand 0 "ext_register_operand" "") 747 (const_int 8) 748 (const_int 8)) 0) 749 (match_operand:QI 1 "general_operand" "")))] 750 "" 751 "") 752 753(define_insn "cmpqi_ext_3_insn" 754 [(set (reg FLAGS_REG) 755 (compare 756 (subreg:QI 757 (zero_extract:SI 758 (match_operand 0 "ext_register_operand" "Q") 759 (const_int 8) 760 (const_int 8)) 0) 761 (match_operand:QI 1 "general_operand" "Qmn")))] 762 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 763 "cmp{b}\t{%1, %h0|%h0, %1}" 764 [(set_attr "type" "icmp") 765 (set_attr "mode" "QI")]) 766 767(define_insn "cmpqi_ext_3_insn_rex64" 768 [(set (reg FLAGS_REG) 769 (compare 770 (subreg:QI 771 (zero_extract:SI 772 (match_operand 0 "ext_register_operand" "Q") 773 (const_int 8) 774 (const_int 8)) 0) 775 (match_operand:QI 1 "nonmemory_operand" "Qn")))] 776 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 777 "cmp{b}\t{%1, %h0|%h0, %1}" 778 [(set_attr "type" "icmp") 779 (set_attr "mode" "QI")]) 780 781(define_insn "*cmpqi_ext_4" 782 [(set (reg FLAGS_REG) 783 (compare 784 (subreg:QI 785 (zero_extract:SI 786 (match_operand 0 "ext_register_operand" "Q") 787 (const_int 8) 788 (const_int 8)) 0) 789 (subreg:QI 790 (zero_extract:SI 791 (match_operand 1 "ext_register_operand" "Q") 792 (const_int 8) 793 (const_int 8)) 0)))] 794 "ix86_match_ccmode (insn, CCmode)" 795 "cmp{b}\t{%h1, %h0|%h0, %h1}" 796 [(set_attr "type" "icmp") 797 (set_attr "mode" "QI")]) 798 799;; These implement float point compares. 800;; %%% See if we can get away with VOIDmode operands on the actual insns, 801;; which would allow mix and match FP modes on the compares. Which is what 802;; the old patterns did, but with many more of them. 803 804(define_expand "cmpxf" 805 [(set (reg:CC FLAGS_REG) 806 (compare:CC (match_operand:XF 0 "nonmemory_operand" "") 807 (match_operand:XF 1 "nonmemory_operand" "")))] 808 "TARGET_80387" 809{ 810 ix86_compare_op0 = operands[0]; 811 ix86_compare_op1 = operands[1]; 812 DONE; 813}) 814 815(define_expand "cmpdf" 816 [(set (reg:CC FLAGS_REG) 817 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "") 818 (match_operand:DF 1 "cmp_fp_expander_operand" "")))] 819 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 820{ 821 ix86_compare_op0 = operands[0]; 822 ix86_compare_op1 = operands[1]; 823 DONE; 824}) 825 826(define_expand "cmpsf" 827 [(set (reg:CC FLAGS_REG) 828 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "") 829 (match_operand:SF 1 "cmp_fp_expander_operand" "")))] 830 "TARGET_80387 || TARGET_SSE_MATH" 831{ 832 ix86_compare_op0 = operands[0]; 833 ix86_compare_op1 = operands[1]; 834 DONE; 835}) 836 837;; FP compares, step 1: 838;; Set the FP condition codes. 839;; 840;; CCFPmode compare with exceptions 841;; CCFPUmode compare with no exceptions 842 843;; We may not use "#" to split and emit these, since the REG_DEAD notes 844;; used to manage the reg stack popping would not be preserved. 845 846(define_insn "*cmpfp_0" 847 [(set (match_operand:HI 0 "register_operand" "=a") 848 (unspec:HI 849 [(compare:CCFP 850 (match_operand 1 "register_operand" "f") 851 (match_operand 2 "const0_operand" "X"))] 852 UNSPEC_FNSTSW))] 853 "TARGET_80387 854 && FLOAT_MODE_P (GET_MODE (operands[1])) 855 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 856 "* return output_fp_compare (insn, operands, 0, 0);" 857 [(set_attr "type" "multi") 858 (set_attr "unit" "i387") 859 (set (attr "mode") 860 (cond [(match_operand:SF 1 "" "") 861 (const_string "SF") 862 (match_operand:DF 1 "" "") 863 (const_string "DF") 864 ] 865 (const_string "XF")))]) 866 867(define_insn "*cmpfp_sf" 868 [(set (match_operand:HI 0 "register_operand" "=a") 869 (unspec:HI 870 [(compare:CCFP 871 (match_operand:SF 1 "register_operand" "f") 872 (match_operand:SF 2 "nonimmediate_operand" "fm"))] 873 UNSPEC_FNSTSW))] 874 "TARGET_80387" 875 "* return output_fp_compare (insn, operands, 0, 0);" 876 [(set_attr "type" "multi") 877 (set_attr "unit" "i387") 878 (set_attr "mode" "SF")]) 879 880(define_insn "*cmpfp_df" 881 [(set (match_operand:HI 0 "register_operand" "=a") 882 (unspec:HI 883 [(compare:CCFP 884 (match_operand:DF 1 "register_operand" "f") 885 (match_operand:DF 2 "nonimmediate_operand" "fm"))] 886 UNSPEC_FNSTSW))] 887 "TARGET_80387" 888 "* return output_fp_compare (insn, operands, 0, 0);" 889 [(set_attr "type" "multi") 890 (set_attr "unit" "i387") 891 (set_attr "mode" "DF")]) 892 893(define_insn "*cmpfp_xf" 894 [(set (match_operand:HI 0 "register_operand" "=a") 895 (unspec:HI 896 [(compare:CCFP 897 (match_operand:XF 1 "register_operand" "f") 898 (match_operand:XF 2 "register_operand" "f"))] 899 UNSPEC_FNSTSW))] 900 "TARGET_80387" 901 "* return output_fp_compare (insn, operands, 0, 0);" 902 [(set_attr "type" "multi") 903 (set_attr "unit" "i387") 904 (set_attr "mode" "XF")]) 905 906(define_insn "*cmpfp_u" 907 [(set (match_operand:HI 0 "register_operand" "=a") 908 (unspec:HI 909 [(compare:CCFPU 910 (match_operand 1 "register_operand" "f") 911 (match_operand 2 "register_operand" "f"))] 912 UNSPEC_FNSTSW))] 913 "TARGET_80387 914 && FLOAT_MODE_P (GET_MODE (operands[1])) 915 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 916 "* return output_fp_compare (insn, operands, 0, 1);" 917 [(set_attr "type" "multi") 918 (set_attr "unit" "i387") 919 (set (attr "mode") 920 (cond [(match_operand:SF 1 "" "") 921 (const_string "SF") 922 (match_operand:DF 1 "" "") 923 (const_string "DF") 924 ] 925 (const_string "XF")))]) 926 927(define_insn "*cmpfp_<mode>" 928 [(set (match_operand:HI 0 "register_operand" "=a") 929 (unspec:HI 930 [(compare:CCFP 931 (match_operand 1 "register_operand" "f") 932 (match_operator 3 "float_operator" 933 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))] 934 UNSPEC_FNSTSW))] 935 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 936 && FLOAT_MODE_P (GET_MODE (operands[1])) 937 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))" 938 "* return output_fp_compare (insn, operands, 0, 0);" 939 [(set_attr "type" "multi") 940 (set_attr "unit" "i387") 941 (set_attr "fp_int_src" "true") 942 (set_attr "mode" "<MODE>")]) 943 944;; FP compares, step 2 945;; Move the fpsw to ax. 946 947(define_insn "x86_fnstsw_1" 948 [(set (match_operand:HI 0 "register_operand" "=a") 949 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))] 950 "TARGET_80387" 951 "fnstsw\t%0" 952 [(set_attr "length" "2") 953 (set_attr "mode" "SI") 954 (set_attr "unit" "i387")]) 955 956;; FP compares, step 3 957;; Get ax into flags, general case. 958 959(define_insn "x86_sahf_1" 960 [(set (reg:CC FLAGS_REG) 961 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))] 962 "!TARGET_64BIT" 963 "sahf" 964 [(set_attr "length" "1") 965 (set_attr "athlon_decode" "vector") 966 (set_attr "mode" "SI")]) 967 968;; Pentium Pro can do steps 1 through 3 in one go. 969 970(define_insn "*cmpfp_i_mixed" 971 [(set (reg:CCFP FLAGS_REG) 972 (compare:CCFP (match_operand 0 "register_operand" "f,x") 973 (match_operand 1 "nonimmediate_operand" "f,xm")))] 974 "TARGET_MIX_SSE_I387 975 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 976 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 977 "* return output_fp_compare (insn, operands, 1, 0);" 978 [(set_attr "type" "fcmp,ssecomi") 979 (set (attr "mode") 980 (if_then_else (match_operand:SF 1 "" "") 981 (const_string "SF") 982 (const_string "DF"))) 983 (set_attr "athlon_decode" "vector")]) 984 985(define_insn "*cmpfp_i_sse" 986 [(set (reg:CCFP FLAGS_REG) 987 (compare:CCFP (match_operand 0 "register_operand" "x") 988 (match_operand 1 "nonimmediate_operand" "xm")))] 989 "TARGET_SSE_MATH 990 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 991 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 992 "* return output_fp_compare (insn, operands, 1, 0);" 993 [(set_attr "type" "ssecomi") 994 (set (attr "mode") 995 (if_then_else (match_operand:SF 1 "" "") 996 (const_string "SF") 997 (const_string "DF"))) 998 (set_attr "athlon_decode" "vector")]) 999 1000(define_insn "*cmpfp_i_i387" 1001 [(set (reg:CCFP FLAGS_REG) 1002 (compare:CCFP (match_operand 0 "register_operand" "f") 1003 (match_operand 1 "register_operand" "f")))] 1004 "TARGET_80387 && TARGET_CMOVE 1005 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))) 1006 && FLOAT_MODE_P (GET_MODE (operands[0])) 1007 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1008 "* return output_fp_compare (insn, operands, 1, 0);" 1009 [(set_attr "type" "fcmp") 1010 (set (attr "mode") 1011 (cond [(match_operand:SF 1 "" "") 1012 (const_string "SF") 1013 (match_operand:DF 1 "" "") 1014 (const_string "DF") 1015 ] 1016 (const_string "XF"))) 1017 (set_attr "athlon_decode" "vector")]) 1018 1019(define_insn "*cmpfp_iu_mixed" 1020 [(set (reg:CCFPU FLAGS_REG) 1021 (compare:CCFPU (match_operand 0 "register_operand" "f,x") 1022 (match_operand 1 "nonimmediate_operand" "f,xm")))] 1023 "TARGET_MIX_SSE_I387 1024 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1025 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1026 "* return output_fp_compare (insn, operands, 1, 1);" 1027 [(set_attr "type" "fcmp,ssecomi") 1028 (set (attr "mode") 1029 (if_then_else (match_operand:SF 1 "" "") 1030 (const_string "SF") 1031 (const_string "DF"))) 1032 (set_attr "athlon_decode" "vector")]) 1033 1034(define_insn "*cmpfp_iu_sse" 1035 [(set (reg:CCFPU FLAGS_REG) 1036 (compare:CCFPU (match_operand 0 "register_operand" "x") 1037 (match_operand 1 "nonimmediate_operand" "xm")))] 1038 "TARGET_SSE_MATH 1039 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1040 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1041 "* return output_fp_compare (insn, operands, 1, 1);" 1042 [(set_attr "type" "ssecomi") 1043 (set (attr "mode") 1044 (if_then_else (match_operand:SF 1 "" "") 1045 (const_string "SF") 1046 (const_string "DF"))) 1047 (set_attr "athlon_decode" "vector")]) 1048 1049(define_insn "*cmpfp_iu_387" 1050 [(set (reg:CCFPU FLAGS_REG) 1051 (compare:CCFPU (match_operand 0 "register_operand" "f") 1052 (match_operand 1 "register_operand" "f")))] 1053 "TARGET_80387 && TARGET_CMOVE 1054 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))) 1055 && FLOAT_MODE_P (GET_MODE (operands[0])) 1056 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1057 "* return output_fp_compare (insn, operands, 1, 1);" 1058 [(set_attr "type" "fcmp") 1059 (set (attr "mode") 1060 (cond [(match_operand:SF 1 "" "") 1061 (const_string "SF") 1062 (match_operand:DF 1 "" "") 1063 (const_string "DF") 1064 ] 1065 (const_string "XF"))) 1066 (set_attr "athlon_decode" "vector")]) 1067 1068;; Move instructions. 1069 1070;; General case of fullword move. 1071 1072(define_expand "movsi" 1073 [(set (match_operand:SI 0 "nonimmediate_operand" "") 1074 (match_operand:SI 1 "general_operand" ""))] 1075 "" 1076 "ix86_expand_move (SImode, operands); DONE;") 1077 1078;; Push/pop instructions. They are separate since autoinc/dec is not a 1079;; general_operand. 1080;; 1081;; %%% We don't use a post-inc memory reference because x86 is not a 1082;; general AUTO_INC_DEC host, which impacts how it is treated in flow. 1083;; Changing this impacts compiler performance on other non-AUTO_INC_DEC 1084;; targets without our curiosities, and it is just as easy to represent 1085;; this differently. 1086 1087(define_insn "*pushsi2" 1088 [(set (match_operand:SI 0 "push_operand" "=<") 1089 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))] 1090 "!TARGET_64BIT" 1091 "push{l}\t%1" 1092 [(set_attr "type" "push") 1093 (set_attr "mode" "SI")]) 1094 1095;; For 64BIT abi we always round up to 8 bytes. 1096(define_insn "*pushsi2_rex64" 1097 [(set (match_operand:SI 0 "push_operand" "=X") 1098 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))] 1099 "TARGET_64BIT" 1100 "push{q}\t%q1" 1101 [(set_attr "type" "push") 1102 (set_attr "mode" "SI")]) 1103 1104(define_insn "*pushsi2_prologue" 1105 [(set (match_operand:SI 0 "push_operand" "=<") 1106 (match_operand:SI 1 "general_no_elim_operand" "ri*m")) 1107 (clobber (mem:BLK (scratch)))] 1108 "!TARGET_64BIT" 1109 "push{l}\t%1" 1110 [(set_attr "type" "push") 1111 (set_attr "mode" "SI")]) 1112 1113(define_insn "*popsi1_epilogue" 1114 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m") 1115 (mem:SI (reg:SI SP_REG))) 1116 (set (reg:SI SP_REG) 1117 (plus:SI (reg:SI SP_REG) (const_int 4))) 1118 (clobber (mem:BLK (scratch)))] 1119 "!TARGET_64BIT" 1120 "pop{l}\t%0" 1121 [(set_attr "type" "pop") 1122 (set_attr "mode" "SI")]) 1123 1124(define_insn "popsi1" 1125 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m") 1126 (mem:SI (reg:SI SP_REG))) 1127 (set (reg:SI SP_REG) 1128 (plus:SI (reg:SI SP_REG) (const_int 4)))] 1129 "!TARGET_64BIT" 1130 "pop{l}\t%0" 1131 [(set_attr "type" "pop") 1132 (set_attr "mode" "SI")]) 1133 1134(define_insn "*movsi_xor" 1135 [(set (match_operand:SI 0 "register_operand" "=r") 1136 (match_operand:SI 1 "const0_operand" "i")) 1137 (clobber (reg:CC FLAGS_REG))] 1138 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)" 1139 "xor{l}\t{%0, %0|%0, %0}" 1140 [(set_attr "type" "alu1") 1141 (set_attr "mode" "SI") 1142 (set_attr "length_immediate" "0")]) 1143 1144(define_insn "*movsi_or" 1145 [(set (match_operand:SI 0 "register_operand" "=r") 1146 (match_operand:SI 1 "immediate_operand" "i")) 1147 (clobber (reg:CC FLAGS_REG))] 1148 "reload_completed 1149 && operands[1] == constm1_rtx 1150 && (TARGET_PENTIUM || optimize_size)" 1151{ 1152 operands[1] = constm1_rtx; 1153 return "or{l}\t{%1, %0|%0, %1}"; 1154} 1155 [(set_attr "type" "alu1") 1156 (set_attr "mode" "SI") 1157 (set_attr "length_immediate" "1")]) 1158 1159(define_insn "*movsi_1" 1160 [(set (match_operand:SI 0 "nonimmediate_operand" 1161 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x") 1162 (match_operand:SI 1 "general_operand" 1163 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))] 1164 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 1165{ 1166 switch (get_attr_type (insn)) 1167 { 1168 case TYPE_SSELOG1: 1169 if (get_attr_mode (insn) == MODE_TI) 1170 return "pxor\t%0, %0"; 1171 return "xorps\t%0, %0"; 1172 1173 case TYPE_SSEMOV: 1174 switch (get_attr_mode (insn)) 1175 { 1176 case MODE_TI: 1177 return "movdqa\t{%1, %0|%0, %1}"; 1178 case MODE_V4SF: 1179 return "movaps\t{%1, %0|%0, %1}"; 1180 case MODE_SI: 1181 return "movd\t{%1, %0|%0, %1}"; 1182 case MODE_SF: 1183 return "movss\t{%1, %0|%0, %1}"; 1184 default: 1185 gcc_unreachable (); 1186 } 1187 1188 case TYPE_MMXADD: 1189 return "pxor\t%0, %0"; 1190 1191 case TYPE_MMXMOV: 1192 if (get_attr_mode (insn) == MODE_DI) 1193 return "movq\t{%1, %0|%0, %1}"; 1194 return "movd\t{%1, %0|%0, %1}"; 1195 1196 case TYPE_LEA: 1197 return "lea{l}\t{%1, %0|%0, %1}"; 1198 1199 default: 1200 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 1201 return "mov{l}\t{%1, %0|%0, %1}"; 1202 } 1203} 1204 [(set (attr "type") 1205 (cond [(eq_attr "alternative" "2") 1206 (const_string "mmxadd") 1207 (eq_attr "alternative" "3,4,5") 1208 (const_string "mmxmov") 1209 (eq_attr "alternative" "6") 1210 (const_string "sselog1") 1211 (eq_attr "alternative" "7,8,9,10,11") 1212 (const_string "ssemov") 1213 (match_operand:DI 1 "pic_32bit_operand" "") 1214 (const_string "lea") 1215 ] 1216 (const_string "imov"))) 1217 (set (attr "mode") 1218 (cond [(eq_attr "alternative" "2,3") 1219 (const_string "DI") 1220 (eq_attr "alternative" "6,7") 1221 (if_then_else 1222 (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 1223 (const_string "V4SF") 1224 (const_string "TI")) 1225 (and (eq_attr "alternative" "8,9,10,11") 1226 (eq (symbol_ref "TARGET_SSE2") (const_int 0))) 1227 (const_string "SF") 1228 ] 1229 (const_string "SI")))]) 1230 1231;; Stores and loads of ax to arbitrary constant address. 1232;; We fake an second form of instruction to force reload to load address 1233;; into register when rax is not available 1234(define_insn "*movabssi_1_rex64" 1235 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 1236 (match_operand:SI 1 "nonmemory_operand" "a,er"))] 1237 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 1238 "@ 1239 movabs{l}\t{%1, %P0|%P0, %1} 1240 mov{l}\t{%1, %a0|%a0, %1}" 1241 [(set_attr "type" "imov") 1242 (set_attr "modrm" "0,*") 1243 (set_attr "length_address" "8,0") 1244 (set_attr "length_immediate" "0,*") 1245 (set_attr "memory" "store") 1246 (set_attr "mode" "SI")]) 1247 1248(define_insn "*movabssi_2_rex64" 1249 [(set (match_operand:SI 0 "register_operand" "=a,r") 1250 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 1251 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 1252 "@ 1253 movabs{l}\t{%P1, %0|%0, %P1} 1254 mov{l}\t{%a1, %0|%0, %a1}" 1255 [(set_attr "type" "imov") 1256 (set_attr "modrm" "0,*") 1257 (set_attr "length_address" "8,0") 1258 (set_attr "length_immediate" "0") 1259 (set_attr "memory" "load") 1260 (set_attr "mode" "SI")]) 1261 1262(define_insn "*swapsi" 1263 [(set (match_operand:SI 0 "register_operand" "+r") 1264 (match_operand:SI 1 "register_operand" "+r")) 1265 (set (match_dup 1) 1266 (match_dup 0))] 1267 "" 1268 "xchg{l}\t%1, %0" 1269 [(set_attr "type" "imov") 1270 (set_attr "mode" "SI") 1271 (set_attr "pent_pair" "np") 1272 (set_attr "athlon_decode" "vector")]) 1273 1274(define_expand "movhi" 1275 [(set (match_operand:HI 0 "nonimmediate_operand" "") 1276 (match_operand:HI 1 "general_operand" ""))] 1277 "" 1278 "ix86_expand_move (HImode, operands); DONE;") 1279 1280(define_insn "*pushhi2" 1281 [(set (match_operand:HI 0 "push_operand" "=X") 1282 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))] 1283 "!TARGET_64BIT" 1284 "push{l}\t%k1" 1285 [(set_attr "type" "push") 1286 (set_attr "mode" "SI")]) 1287 1288;; For 64BIT abi we always round up to 8 bytes. 1289(define_insn "*pushhi2_rex64" 1290 [(set (match_operand:HI 0 "push_operand" "=X") 1291 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))] 1292 "TARGET_64BIT" 1293 "push{q}\t%q1" 1294 [(set_attr "type" "push") 1295 (set_attr "mode" "DI")]) 1296 1297(define_insn "*movhi_1" 1298 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") 1299 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))] 1300 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 1301{ 1302 switch (get_attr_type (insn)) 1303 { 1304 case TYPE_IMOVX: 1305 /* movzwl is faster than movw on p2 due to partial word stalls, 1306 though not as fast as an aligned movl. */ 1307 return "movz{wl|x}\t{%1, %k0|%k0, %1}"; 1308 default: 1309 if (get_attr_mode (insn) == MODE_SI) 1310 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 1311 else 1312 return "mov{w}\t{%1, %0|%0, %1}"; 1313 } 1314} 1315 [(set (attr "type") 1316 (cond [(ne (symbol_ref "optimize_size") (const_int 0)) 1317 (const_string "imov") 1318 (and (eq_attr "alternative" "0") 1319 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1320 (const_int 0)) 1321 (eq (symbol_ref "TARGET_HIMODE_MATH") 1322 (const_int 0)))) 1323 (const_string "imov") 1324 (and (eq_attr "alternative" "1,2") 1325 (match_operand:HI 1 "aligned_operand" "")) 1326 (const_string "imov") 1327 (and (ne (symbol_ref "TARGET_MOVX") 1328 (const_int 0)) 1329 (eq_attr "alternative" "0,2")) 1330 (const_string "imovx") 1331 ] 1332 (const_string "imov"))) 1333 (set (attr "mode") 1334 (cond [(eq_attr "type" "imovx") 1335 (const_string "SI") 1336 (and (eq_attr "alternative" "1,2") 1337 (match_operand:HI 1 "aligned_operand" "")) 1338 (const_string "SI") 1339 (and (eq_attr "alternative" "0") 1340 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1341 (const_int 0)) 1342 (eq (symbol_ref "TARGET_HIMODE_MATH") 1343 (const_int 0)))) 1344 (const_string "SI") 1345 ] 1346 (const_string "HI")))]) 1347 1348;; Stores and loads of ax to arbitrary constant address. 1349;; We fake an second form of instruction to force reload to load address 1350;; into register when rax is not available 1351(define_insn "*movabshi_1_rex64" 1352 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 1353 (match_operand:HI 1 "nonmemory_operand" "a,er"))] 1354 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 1355 "@ 1356 movabs{w}\t{%1, %P0|%P0, %1} 1357 mov{w}\t{%1, %a0|%a0, %1}" 1358 [(set_attr "type" "imov") 1359 (set_attr "modrm" "0,*") 1360 (set_attr "length_address" "8,0") 1361 (set_attr "length_immediate" "0,*") 1362 (set_attr "memory" "store") 1363 (set_attr "mode" "HI")]) 1364 1365(define_insn "*movabshi_2_rex64" 1366 [(set (match_operand:HI 0 "register_operand" "=a,r") 1367 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 1368 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 1369 "@ 1370 movabs{w}\t{%P1, %0|%0, %P1} 1371 mov{w}\t{%a1, %0|%0, %a1}" 1372 [(set_attr "type" "imov") 1373 (set_attr "modrm" "0,*") 1374 (set_attr "length_address" "8,0") 1375 (set_attr "length_immediate" "0") 1376 (set_attr "memory" "load") 1377 (set_attr "mode" "HI")]) 1378 1379(define_insn "*swaphi_1" 1380 [(set (match_operand:HI 0 "register_operand" "+r") 1381 (match_operand:HI 1 "register_operand" "+r")) 1382 (set (match_dup 1) 1383 (match_dup 0))] 1384 "!TARGET_PARTIAL_REG_STALL || optimize_size" 1385 "xchg{l}\t%k1, %k0" 1386 [(set_attr "type" "imov") 1387 (set_attr "mode" "SI") 1388 (set_attr "pent_pair" "np") 1389 (set_attr "athlon_decode" "vector")]) 1390 1391(define_insn "*swaphi_2" 1392 [(set (match_operand:HI 0 "register_operand" "+r") 1393 (match_operand:HI 1 "register_operand" "+r")) 1394 (set (match_dup 1) 1395 (match_dup 0))] 1396 "TARGET_PARTIAL_REG_STALL" 1397 "xchg{w}\t%1, %0" 1398 [(set_attr "type" "imov") 1399 (set_attr "mode" "HI") 1400 (set_attr "pent_pair" "np") 1401 (set_attr "athlon_decode" "vector")]) 1402 1403(define_expand "movstricthi" 1404 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "")) 1405 (match_operand:HI 1 "general_operand" ""))] 1406 "! TARGET_PARTIAL_REG_STALL || optimize_size" 1407{ 1408 /* Don't generate memory->memory moves, go through a register */ 1409 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 1410 operands[1] = force_reg (HImode, operands[1]); 1411}) 1412 1413(define_insn "*movstricthi_1" 1414 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r")) 1415 (match_operand:HI 1 "general_operand" "rn,m"))] 1416 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 1417 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 1418 "mov{w}\t{%1, %0|%0, %1}" 1419 [(set_attr "type" "imov") 1420 (set_attr "mode" "HI")]) 1421 1422(define_insn "*movstricthi_xor" 1423 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) 1424 (match_operand:HI 1 "const0_operand" "i")) 1425 (clobber (reg:CC FLAGS_REG))] 1426 "reload_completed 1427 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)" 1428 "xor{w}\t{%0, %0|%0, %0}" 1429 [(set_attr "type" "alu1") 1430 (set_attr "mode" "HI") 1431 (set_attr "length_immediate" "0")]) 1432 1433(define_expand "movqi" 1434 [(set (match_operand:QI 0 "nonimmediate_operand" "") 1435 (match_operand:QI 1 "general_operand" ""))] 1436 "" 1437 "ix86_expand_move (QImode, operands); DONE;") 1438 1439;; emit_push_insn when it calls move_by_pieces requires an insn to 1440;; "push a byte". But actually we use pushl, which has the effect 1441;; of rounding the amount pushed up to a word. 1442 1443(define_insn "*pushqi2" 1444 [(set (match_operand:QI 0 "push_operand" "=X") 1445 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))] 1446 "!TARGET_64BIT" 1447 "push{l}\t%k1" 1448 [(set_attr "type" "push") 1449 (set_attr "mode" "SI")]) 1450 1451;; For 64BIT abi we always round up to 8 bytes. 1452(define_insn "*pushqi2_rex64" 1453 [(set (match_operand:QI 0 "push_operand" "=X") 1454 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))] 1455 "TARGET_64BIT" 1456 "push{q}\t%q1" 1457 [(set_attr "type" "push") 1458 (set_attr "mode" "DI")]) 1459 1460;; Situation is quite tricky about when to choose full sized (SImode) move 1461;; over QImode moves. For Q_REG -> Q_REG move we use full size only for 1462;; partial register dependency machines (such as AMD Athlon), where QImode 1463;; moves issue extra dependency and for partial register stalls machines 1464;; that don't use QImode patterns (and QImode move cause stall on the next 1465;; instruction). 1466;; 1467;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial 1468;; register stall machines with, where we use QImode instructions, since 1469;; partial register stall can be caused there. Then we use movzx. 1470(define_insn "*movqi_1" 1471 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m") 1472 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))] 1473 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 1474{ 1475 switch (get_attr_type (insn)) 1476 { 1477 case TYPE_IMOVX: 1478 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM); 1479 return "movz{bl|x}\t{%1, %k0|%k0, %1}"; 1480 default: 1481 if (get_attr_mode (insn) == MODE_SI) 1482 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 1483 else 1484 return "mov{b}\t{%1, %0|%0, %1}"; 1485 } 1486} 1487 [(set (attr "type") 1488 (cond [(and (eq_attr "alternative" "5") 1489 (not (match_operand:QI 1 "aligned_operand" ""))) 1490 (const_string "imovx") 1491 (ne (symbol_ref "optimize_size") (const_int 0)) 1492 (const_string "imov") 1493 (and (eq_attr "alternative" "3") 1494 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1495 (const_int 0)) 1496 (eq (symbol_ref "TARGET_QIMODE_MATH") 1497 (const_int 0)))) 1498 (const_string "imov") 1499 (eq_attr "alternative" "3,5") 1500 (const_string "imovx") 1501 (and (ne (symbol_ref "TARGET_MOVX") 1502 (const_int 0)) 1503 (eq_attr "alternative" "2")) 1504 (const_string "imovx") 1505 ] 1506 (const_string "imov"))) 1507 (set (attr "mode") 1508 (cond [(eq_attr "alternative" "3,4,5") 1509 (const_string "SI") 1510 (eq_attr "alternative" "6") 1511 (const_string "QI") 1512 (eq_attr "type" "imovx") 1513 (const_string "SI") 1514 (and (eq_attr "type" "imov") 1515 (and (eq_attr "alternative" "0,1") 1516 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY") 1517 (const_int 0)) 1518 (and (eq (symbol_ref "optimize_size") 1519 (const_int 0)) 1520 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1521 (const_int 0)))))) 1522 (const_string "SI") 1523 ;; Avoid partial register stalls when not using QImode arithmetic 1524 (and (eq_attr "type" "imov") 1525 (and (eq_attr "alternative" "0,1") 1526 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL") 1527 (const_int 0)) 1528 (eq (symbol_ref "TARGET_QIMODE_MATH") 1529 (const_int 0))))) 1530 (const_string "SI") 1531 ] 1532 (const_string "QI")))]) 1533 1534(define_expand "reload_outqi" 1535 [(parallel [(match_operand:QI 0 "" "=m") 1536 (match_operand:QI 1 "register_operand" "r") 1537 (match_operand:QI 2 "register_operand" "=&q")])] 1538 "" 1539{ 1540 rtx op0, op1, op2; 1541 op0 = operands[0]; op1 = operands[1]; op2 = operands[2]; 1542 1543 gcc_assert (!reg_overlap_mentioned_p (op2, op0)); 1544 if (! q_regs_operand (op1, QImode)) 1545 { 1546 emit_insn (gen_movqi (op2, op1)); 1547 op1 = op2; 1548 } 1549 emit_insn (gen_movqi (op0, op1)); 1550 DONE; 1551}) 1552 1553(define_insn "*swapqi_1" 1554 [(set (match_operand:QI 0 "register_operand" "+r") 1555 (match_operand:QI 1 "register_operand" "+r")) 1556 (set (match_dup 1) 1557 (match_dup 0))] 1558 "!TARGET_PARTIAL_REG_STALL || optimize_size" 1559 "xchg{l}\t%k1, %k0" 1560 [(set_attr "type" "imov") 1561 (set_attr "mode" "SI") 1562 (set_attr "pent_pair" "np") 1563 (set_attr "athlon_decode" "vector")]) 1564 1565(define_insn "*swapqi_2" 1566 [(set (match_operand:QI 0 "register_operand" "+q") 1567 (match_operand:QI 1 "register_operand" "+q")) 1568 (set (match_dup 1) 1569 (match_dup 0))] 1570 "TARGET_PARTIAL_REG_STALL" 1571 "xchg{b}\t%1, %0" 1572 [(set_attr "type" "imov") 1573 (set_attr "mode" "QI") 1574 (set_attr "pent_pair" "np") 1575 (set_attr "athlon_decode" "vector")]) 1576 1577(define_expand "movstrictqi" 1578 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 1579 (match_operand:QI 1 "general_operand" ""))] 1580 "! TARGET_PARTIAL_REG_STALL || optimize_size" 1581{ 1582 /* Don't generate memory->memory moves, go through a register. */ 1583 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 1584 operands[1] = force_reg (QImode, operands[1]); 1585}) 1586 1587(define_insn "*movstrictqi_1" 1588 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 1589 (match_operand:QI 1 "general_operand" "*qn,m"))] 1590 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 1591 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 1592 "mov{b}\t{%1, %0|%0, %1}" 1593 [(set_attr "type" "imov") 1594 (set_attr "mode" "QI")]) 1595 1596(define_insn "*movstrictqi_xor" 1597 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q")) 1598 (match_operand:QI 1 "const0_operand" "i")) 1599 (clobber (reg:CC FLAGS_REG))] 1600 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)" 1601 "xor{b}\t{%0, %0|%0, %0}" 1602 [(set_attr "type" "alu1") 1603 (set_attr "mode" "QI") 1604 (set_attr "length_immediate" "0")]) 1605 1606(define_insn "*movsi_extv_1" 1607 [(set (match_operand:SI 0 "register_operand" "=R") 1608 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q") 1609 (const_int 8) 1610 (const_int 8)))] 1611 "" 1612 "movs{bl|x}\t{%h1, %0|%0, %h1}" 1613 [(set_attr "type" "imovx") 1614 (set_attr "mode" "SI")]) 1615 1616(define_insn "*movhi_extv_1" 1617 [(set (match_operand:HI 0 "register_operand" "=R") 1618 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q") 1619 (const_int 8) 1620 (const_int 8)))] 1621 "" 1622 "movs{bl|x}\t{%h1, %k0|%k0, %h1}" 1623 [(set_attr "type" "imovx") 1624 (set_attr "mode" "SI")]) 1625 1626(define_insn "*movqi_extv_1" 1627 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r") 1628 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") 1629 (const_int 8) 1630 (const_int 8)))] 1631 "!TARGET_64BIT" 1632{ 1633 switch (get_attr_type (insn)) 1634 { 1635 case TYPE_IMOVX: 1636 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; 1637 default: 1638 return "mov{b}\t{%h1, %0|%0, %h1}"; 1639 } 1640} 1641 [(set (attr "type") 1642 (if_then_else (and (match_operand:QI 0 "register_operand" "") 1643 (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1644 (ne (symbol_ref "TARGET_MOVX") 1645 (const_int 0)))) 1646 (const_string "imovx") 1647 (const_string "imov"))) 1648 (set (attr "mode") 1649 (if_then_else (eq_attr "type" "imovx") 1650 (const_string "SI") 1651 (const_string "QI")))]) 1652 1653(define_insn "*movqi_extv_1_rex64" 1654 [(set (match_operand:QI 0 "register_operand" "=Q,?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;; Stores and loads of ax to arbitrary constant address. 1681;; We fake an second form of instruction to force reload to load address 1682;; into register when rax is not available 1683(define_insn "*movabsqi_1_rex64" 1684 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 1685 (match_operand:QI 1 "nonmemory_operand" "a,er"))] 1686 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 1687 "@ 1688 movabs{b}\t{%1, %P0|%P0, %1} 1689 mov{b}\t{%1, %a0|%a0, %1}" 1690 [(set_attr "type" "imov") 1691 (set_attr "modrm" "0,*") 1692 (set_attr "length_address" "8,0") 1693 (set_attr "length_immediate" "0,*") 1694 (set_attr "memory" "store") 1695 (set_attr "mode" "QI")]) 1696 1697(define_insn "*movabsqi_2_rex64" 1698 [(set (match_operand:QI 0 "register_operand" "=a,r") 1699 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 1700 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 1701 "@ 1702 movabs{b}\t{%P1, %0|%0, %P1} 1703 mov{b}\t{%a1, %0|%0, %a1}" 1704 [(set_attr "type" "imov") 1705 (set_attr "modrm" "0,*") 1706 (set_attr "length_address" "8,0") 1707 (set_attr "length_immediate" "0") 1708 (set_attr "memory" "load") 1709 (set_attr "mode" "QI")]) 1710 1711(define_insn "*movdi_extzv_1" 1712 [(set (match_operand:DI 0 "register_operand" "=R") 1713 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q") 1714 (const_int 8) 1715 (const_int 8)))] 1716 "TARGET_64BIT" 1717 "movz{bl|x}\t{%h1, %k0|%k0, %h1}" 1718 [(set_attr "type" "imovx") 1719 (set_attr "mode" "DI")]) 1720 1721(define_insn "*movsi_extzv_1" 1722 [(set (match_operand:SI 0 "register_operand" "=R") 1723 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q") 1724 (const_int 8) 1725 (const_int 8)))] 1726 "" 1727 "movz{bl|x}\t{%h1, %0|%0, %h1}" 1728 [(set_attr "type" "imovx") 1729 (set_attr "mode" "SI")]) 1730 1731(define_insn "*movqi_extzv_2" 1732 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R") 1733 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") 1734 (const_int 8) 1735 (const_int 8)) 0))] 1736 "!TARGET_64BIT" 1737{ 1738 switch (get_attr_type (insn)) 1739 { 1740 case TYPE_IMOVX: 1741 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 1742 default: 1743 return "mov{b}\t{%h1, %0|%0, %h1}"; 1744 } 1745} 1746 [(set (attr "type") 1747 (if_then_else (and (match_operand:QI 0 "register_operand" "") 1748 (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1749 (ne (symbol_ref "TARGET_MOVX") 1750 (const_int 0)))) 1751 (const_string "imovx") 1752 (const_string "imov"))) 1753 (set (attr "mode") 1754 (if_then_else (eq_attr "type" "imovx") 1755 (const_string "SI") 1756 (const_string "QI")))]) 1757 1758(define_insn "*movqi_extzv_2_rex64" 1759 [(set (match_operand:QI 0 "register_operand" "=Q,?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 (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1775 (ne (symbol_ref "TARGET_MOVX") 1776 (const_int 0))) 1777 (const_string "imovx") 1778 (const_string "imov"))) 1779 (set (attr "mode") 1780 (if_then_else (eq_attr "type" "imovx") 1781 (const_string "SI") 1782 (const_string "QI")))]) 1783 1784(define_insn "movsi_insv_1" 1785 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 1786 (const_int 8) 1787 (const_int 8)) 1788 (match_operand:SI 1 "general_operand" "Qmn"))] 1789 "!TARGET_64BIT" 1790 "mov{b}\t{%b1, %h0|%h0, %b1}" 1791 [(set_attr "type" "imov") 1792 (set_attr "mode" "QI")]) 1793 1794(define_insn "movdi_insv_1_rex64" 1795 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q") 1796 (const_int 8) 1797 (const_int 8)) 1798 (match_operand:DI 1 "nonmemory_operand" "Qn"))] 1799 "TARGET_64BIT" 1800 "mov{b}\t{%b1, %h0|%h0, %b1}" 1801 [(set_attr "type" "imov") 1802 (set_attr "mode" "QI")]) 1803 1804(define_insn "*movqi_insv_2" 1805 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 1806 (const_int 8) 1807 (const_int 8)) 1808 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q") 1809 (const_int 8)))] 1810 "" 1811 "mov{b}\t{%h1, %h0|%h0, %h1}" 1812 [(set_attr "type" "imov") 1813 (set_attr "mode" "QI")]) 1814 1815(define_expand "movdi" 1816 [(set (match_operand:DI 0 "nonimmediate_operand" "") 1817 (match_operand:DI 1 "general_operand" ""))] 1818 "" 1819 "ix86_expand_move (DImode, operands); DONE;") 1820 1821(define_insn "*pushdi" 1822 [(set (match_operand:DI 0 "push_operand" "=<") 1823 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))] 1824 "!TARGET_64BIT" 1825 "#") 1826 1827(define_insn "*pushdi2_rex64" 1828 [(set (match_operand:DI 0 "push_operand" "=<,!<") 1829 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))] 1830 "TARGET_64BIT" 1831 "@ 1832 push{q}\t%1 1833 #" 1834 [(set_attr "type" "push,multi") 1835 (set_attr "mode" "DI")]) 1836 1837;; Convert impossible pushes of immediate to existing instructions. 1838;; First try to get scratch register and go through it. In case this 1839;; fails, push sign extended lower part first and then overwrite 1840;; upper part by 32bit move. 1841(define_peephole2 1842 [(match_scratch:DI 2 "r") 1843 (set (match_operand:DI 0 "push_operand" "") 1844 (match_operand:DI 1 "immediate_operand" ""))] 1845 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1846 && !x86_64_immediate_operand (operands[1], DImode)" 1847 [(set (match_dup 2) (match_dup 1)) 1848 (set (match_dup 0) (match_dup 2))] 1849 "") 1850 1851;; We need to define this as both peepholer and splitter for case 1852;; peephole2 pass is not run. 1853;; "&& 1" is needed to keep it from matching the previous pattern. 1854(define_peephole2 1855 [(set (match_operand:DI 0 "push_operand" "") 1856 (match_operand:DI 1 "immediate_operand" ""))] 1857 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1858 && !x86_64_immediate_operand (operands[1], DImode) && 1" 1859 [(set (match_dup 0) (match_dup 1)) 1860 (set (match_dup 2) (match_dup 3))] 1861 "split_di (operands + 1, 1, operands + 2, operands + 3); 1862 operands[1] = gen_lowpart (DImode, operands[2]); 1863 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, 1864 GEN_INT (4))); 1865 ") 1866 1867(define_split 1868 [(set (match_operand:DI 0 "push_operand" "") 1869 (match_operand:DI 1 "immediate_operand" ""))] 1870 "TARGET_64BIT && ((optimize > 0 && flag_peephole2) 1871 ? flow2_completed : reload_completed) 1872 && !symbolic_operand (operands[1], DImode) 1873 && !x86_64_immediate_operand (operands[1], DImode)" 1874 [(set (match_dup 0) (match_dup 1)) 1875 (set (match_dup 2) (match_dup 3))] 1876 "split_di (operands + 1, 1, operands + 2, operands + 3); 1877 operands[1] = gen_lowpart (DImode, operands[2]); 1878 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, 1879 GEN_INT (4))); 1880 ") 1881 1882(define_insn "*pushdi2_prologue_rex64" 1883 [(set (match_operand:DI 0 "push_operand" "=<") 1884 (match_operand:DI 1 "general_no_elim_operand" "re*m")) 1885 (clobber (mem:BLK (scratch)))] 1886 "TARGET_64BIT" 1887 "push{q}\t%1" 1888 [(set_attr "type" "push") 1889 (set_attr "mode" "DI")]) 1890 1891(define_insn "*popdi1_epilogue_rex64" 1892 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m") 1893 (mem:DI (reg:DI SP_REG))) 1894 (set (reg:DI SP_REG) 1895 (plus:DI (reg:DI SP_REG) (const_int 8))) 1896 (clobber (mem:BLK (scratch)))] 1897 "TARGET_64BIT" 1898 "pop{q}\t%0" 1899 [(set_attr "type" "pop") 1900 (set_attr "mode" "DI")]) 1901 1902(define_insn "popdi1" 1903 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m") 1904 (mem:DI (reg:DI SP_REG))) 1905 (set (reg:DI SP_REG) 1906 (plus:DI (reg:DI SP_REG) (const_int 8)))] 1907 "TARGET_64BIT" 1908 "pop{q}\t%0" 1909 [(set_attr "type" "pop") 1910 (set_attr "mode" "DI")]) 1911 1912(define_insn "*movdi_xor_rex64" 1913 [(set (match_operand:DI 0 "register_operand" "=r") 1914 (match_operand:DI 1 "const0_operand" "i")) 1915 (clobber (reg:CC FLAGS_REG))] 1916 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size) 1917 && reload_completed" 1918 "xor{l}\t{%k0, %k0|%k0, %k0}" 1919 [(set_attr "type" "alu1") 1920 (set_attr "mode" "SI") 1921 (set_attr "length_immediate" "0")]) 1922 1923(define_insn "*movdi_or_rex64" 1924 [(set (match_operand:DI 0 "register_operand" "=r") 1925 (match_operand:DI 1 "const_int_operand" "i")) 1926 (clobber (reg:CC FLAGS_REG))] 1927 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size) 1928 && reload_completed 1929 && operands[1] == constm1_rtx" 1930{ 1931 operands[1] = constm1_rtx; 1932 return "or{q}\t{%1, %0|%0, %1}"; 1933} 1934 [(set_attr "type" "alu1") 1935 (set_attr "mode" "DI") 1936 (set_attr "length_immediate" "1")]) 1937 1938(define_insn "*movdi_2" 1939 [(set (match_operand:DI 0 "nonimmediate_operand" 1940 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x") 1941 (match_operand:DI 1 "general_operand" 1942 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))] 1943 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1944 "@ 1945 # 1946 # 1947 pxor\t%0, %0 1948 movq\t{%1, %0|%0, %1} 1949 movq\t{%1, %0|%0, %1} 1950 pxor\t%0, %0 1951 movq\t{%1, %0|%0, %1} 1952 movdqa\t{%1, %0|%0, %1} 1953 movq\t{%1, %0|%0, %1} 1954 xorps\t%0, %0 1955 movlps\t{%1, %0|%0, %1} 1956 movaps\t{%1, %0|%0, %1} 1957 movlps\t{%1, %0|%0, %1}" 1958 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov") 1959 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")]) 1960 1961(define_split 1962 [(set (match_operand:DI 0 "push_operand" "") 1963 (match_operand:DI 1 "general_operand" ""))] 1964 "!TARGET_64BIT && reload_completed 1965 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))" 1966 [(const_int 0)] 1967 "ix86_split_long_move (operands); DONE;") 1968 1969;; %%% This multiword shite has got to go. 1970(define_split 1971 [(set (match_operand:DI 0 "nonimmediate_operand" "") 1972 (match_operand:DI 1 "general_operand" ""))] 1973 "!TARGET_64BIT && reload_completed 1974 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0])) 1975 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))" 1976 [(const_int 0)] 1977 "ix86_split_long_move (operands); DONE;") 1978 1979(define_insn "*movdi_1_rex64" 1980 [(set (match_operand:DI 0 "nonimmediate_operand" 1981 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y") 1982 (match_operand:DI 1 "general_operand" 1983 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))] 1984 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1985{ 1986 switch (get_attr_type (insn)) 1987 { 1988 case TYPE_SSECVT: 1989 if (which_alternative == 13) 1990 return "movq2dq\t{%1, %0|%0, %1}"; 1991 else 1992 return "movdq2q\t{%1, %0|%0, %1}"; 1993 case TYPE_SSEMOV: 1994 if (get_attr_mode (insn) == MODE_TI) 1995 return "movdqa\t{%1, %0|%0, %1}"; 1996 /* FALLTHRU */ 1997 case TYPE_MMXMOV: 1998 /* Moves from and into integer register is done using movd opcode with 1999 REX prefix. */ 2000 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])) 2001 return "movd\t{%1, %0|%0, %1}"; 2002 return "movq\t{%1, %0|%0, %1}"; 2003 case TYPE_SSELOG1: 2004 case TYPE_MMXADD: 2005 return "pxor\t%0, %0"; 2006 case TYPE_MULTI: 2007 return "#"; 2008 case TYPE_LEA: 2009 return "lea{q}\t{%a1, %0|%0, %a1}"; 2010 default: 2011 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 2012 if (get_attr_mode (insn) == MODE_SI) 2013 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2014 else if (which_alternative == 2) 2015 return "movabs{q}\t{%1, %0|%0, %1}"; 2016 else 2017 return "mov{q}\t{%1, %0|%0, %1}"; 2018 } 2019} 2020 [(set (attr "type") 2021 (cond [(eq_attr "alternative" "5") 2022 (const_string "mmxadd") 2023 (eq_attr "alternative" "6,7,8") 2024 (const_string "mmxmov") 2025 (eq_attr "alternative" "9") 2026 (const_string "sselog1") 2027 (eq_attr "alternative" "10,11,12") 2028 (const_string "ssemov") 2029 (eq_attr "alternative" "13,14") 2030 (const_string "ssecvt") 2031 (eq_attr "alternative" "4") 2032 (const_string "multi") 2033 (match_operand:DI 1 "pic_32bit_operand" "") 2034 (const_string "lea") 2035 ] 2036 (const_string "imov"))) 2037 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*") 2038 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*") 2039 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")]) 2040 2041;; Stores and loads of ax to arbitrary constant address. 2042;; We fake an second form of instruction to force reload to load address 2043;; into register when rax is not available 2044(define_insn "*movabsdi_1_rex64" 2045 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 2046 (match_operand:DI 1 "nonmemory_operand" "a,er"))] 2047 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 2048 "@ 2049 movabs{q}\t{%1, %P0|%P0, %1} 2050 mov{q}\t{%1, %a0|%a0, %1}" 2051 [(set_attr "type" "imov") 2052 (set_attr "modrm" "0,*") 2053 (set_attr "length_address" "8,0") 2054 (set_attr "length_immediate" "0,*") 2055 (set_attr "memory" "store") 2056 (set_attr "mode" "DI")]) 2057 2058(define_insn "*movabsdi_2_rex64" 2059 [(set (match_operand:DI 0 "register_operand" "=a,r") 2060 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 2061 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 2062 "@ 2063 movabs{q}\t{%P1, %0|%0, %P1} 2064 mov{q}\t{%a1, %0|%0, %a1}" 2065 [(set_attr "type" "imov") 2066 (set_attr "modrm" "0,*") 2067 (set_attr "length_address" "8,0") 2068 (set_attr "length_immediate" "0") 2069 (set_attr "memory" "load") 2070 (set_attr "mode" "DI")]) 2071 2072;; Convert impossible stores of immediate to existing instructions. 2073;; First try to get scratch register and go through it. In case this 2074;; fails, move by 32bit parts. 2075(define_peephole2 2076 [(match_scratch:DI 2 "r") 2077 (set (match_operand:DI 0 "memory_operand" "") 2078 (match_operand:DI 1 "immediate_operand" ""))] 2079 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 2080 && !x86_64_immediate_operand (operands[1], DImode)" 2081 [(set (match_dup 2) (match_dup 1)) 2082 (set (match_dup 0) (match_dup 2))] 2083 "") 2084 2085;; We need to define this as both peepholer and splitter for case 2086;; peephole2 pass is not run. 2087;; "&& 1" is needed to keep it from matching the previous pattern. 2088(define_peephole2 2089 [(set (match_operand:DI 0 "memory_operand" "") 2090 (match_operand:DI 1 "immediate_operand" ""))] 2091 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 2092 && !x86_64_immediate_operand (operands[1], DImode) && 1" 2093 [(set (match_dup 2) (match_dup 3)) 2094 (set (match_dup 4) (match_dup 5))] 2095 "split_di (operands, 2, operands + 2, operands + 4);") 2096 2097(define_split 2098 [(set (match_operand:DI 0 "memory_operand" "") 2099 (match_operand:DI 1 "immediate_operand" ""))] 2100 "TARGET_64BIT && ((optimize > 0 && flag_peephole2) 2101 ? flow2_completed : reload_completed) 2102 && !symbolic_operand (operands[1], DImode) 2103 && !x86_64_immediate_operand (operands[1], DImode)" 2104 [(set (match_dup 2) (match_dup 3)) 2105 (set (match_dup 4) (match_dup 5))] 2106 "split_di (operands, 2, operands + 2, operands + 4);") 2107 2108(define_insn "*swapdi_rex64" 2109 [(set (match_operand:DI 0 "register_operand" "+r") 2110 (match_operand:DI 1 "register_operand" "+r")) 2111 (set (match_dup 1) 2112 (match_dup 0))] 2113 "TARGET_64BIT" 2114 "xchg{q}\t%1, %0" 2115 [(set_attr "type" "imov") 2116 (set_attr "mode" "DI") 2117 (set_attr "pent_pair" "np") 2118 (set_attr "athlon_decode" "vector")]) 2119 2120(define_expand "movti" 2121 [(set (match_operand:TI 0 "nonimmediate_operand" "") 2122 (match_operand:TI 1 "nonimmediate_operand" ""))] 2123 "TARGET_SSE || TARGET_64BIT" 2124{ 2125 if (TARGET_64BIT) 2126 ix86_expand_move (TImode, operands); 2127 else 2128 ix86_expand_vector_move (TImode, operands); 2129 DONE; 2130}) 2131 2132(define_insn "*movti_internal" 2133 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m") 2134 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))] 2135 "TARGET_SSE && !TARGET_64BIT 2136 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 2137{ 2138 switch (which_alternative) 2139 { 2140 case 0: 2141 if (get_attr_mode (insn) == MODE_V4SF) 2142 return "xorps\t%0, %0"; 2143 else 2144 return "pxor\t%0, %0"; 2145 case 1: 2146 case 2: 2147 if (get_attr_mode (insn) == MODE_V4SF) 2148 return "movaps\t{%1, %0|%0, %1}"; 2149 else 2150 return "movdqa\t{%1, %0|%0, %1}"; 2151 default: 2152 gcc_unreachable (); 2153 } 2154} 2155 [(set_attr "type" "sselog1,ssemov,ssemov") 2156 (set (attr "mode") 2157 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 2158 (ne (symbol_ref "optimize_size") (const_int 0))) 2159 (const_string "V4SF") 2160 (and (eq_attr "alternative" "2") 2161 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") 2162 (const_int 0))) 2163 (const_string "V4SF")] 2164 (const_string "TI")))]) 2165 2166(define_insn "*movti_rex64" 2167 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm") 2168 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))] 2169 "TARGET_64BIT 2170 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 2171{ 2172 switch (which_alternative) 2173 { 2174 case 0: 2175 case 1: 2176 return "#"; 2177 case 2: 2178 if (get_attr_mode (insn) == MODE_V4SF) 2179 return "xorps\t%0, %0"; 2180 else 2181 return "pxor\t%0, %0"; 2182 case 3: 2183 case 4: 2184 if (get_attr_mode (insn) == MODE_V4SF) 2185 return "movaps\t{%1, %0|%0, %1}"; 2186 else 2187 return "movdqa\t{%1, %0|%0, %1}"; 2188 default: 2189 gcc_unreachable (); 2190 } 2191} 2192 [(set_attr "type" "*,*,sselog1,ssemov,ssemov") 2193 (set (attr "mode") 2194 (cond [(eq_attr "alternative" "2,3") 2195 (if_then_else 2196 (ne (symbol_ref "optimize_size") 2197 (const_int 0)) 2198 (const_string "V4SF") 2199 (const_string "TI")) 2200 (eq_attr "alternative" "4") 2201 (if_then_else 2202 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") 2203 (const_int 0)) 2204 (ne (symbol_ref "optimize_size") 2205 (const_int 0))) 2206 (const_string "V4SF") 2207 (const_string "TI"))] 2208 (const_string "DI")))]) 2209 2210(define_split 2211 [(set (match_operand:TI 0 "nonimmediate_operand" "") 2212 (match_operand:TI 1 "general_operand" ""))] 2213 "reload_completed && !SSE_REG_P (operands[0]) 2214 && !SSE_REG_P (operands[1])" 2215 [(const_int 0)] 2216 "ix86_split_long_move (operands); DONE;") 2217 2218(define_expand "movsf" 2219 [(set (match_operand:SF 0 "nonimmediate_operand" "") 2220 (match_operand:SF 1 "general_operand" ""))] 2221 "" 2222 "ix86_expand_move (SFmode, operands); DONE;") 2223 2224(define_insn "*pushsf" 2225 [(set (match_operand:SF 0 "push_operand" "=<,<,<") 2226 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))] 2227 "!TARGET_64BIT" 2228{ 2229 /* Anything else should be already split before reg-stack. */ 2230 gcc_assert (which_alternative == 1); 2231 return "push{l}\t%1"; 2232} 2233 [(set_attr "type" "multi,push,multi") 2234 (set_attr "unit" "i387,*,*") 2235 (set_attr "mode" "SF,SI,SF")]) 2236 2237(define_insn "*pushsf_rex64" 2238 [(set (match_operand:SF 0 "push_operand" "=X,X,X") 2239 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))] 2240 "TARGET_64BIT" 2241{ 2242 /* Anything else should be already split before reg-stack. */ 2243 gcc_assert (which_alternative == 1); 2244 return "push{q}\t%q1"; 2245} 2246 [(set_attr "type" "multi,push,multi") 2247 (set_attr "unit" "i387,*,*") 2248 (set_attr "mode" "SF,DI,SF")]) 2249 2250(define_split 2251 [(set (match_operand:SF 0 "push_operand" "") 2252 (match_operand:SF 1 "memory_operand" ""))] 2253 "reload_completed 2254 && GET_CODE (operands[1]) == MEM 2255 && constant_pool_reference_p (operands[1])" 2256 [(set (match_dup 0) 2257 (match_dup 1))] 2258 "operands[1] = avoid_constant_pool_reference (operands[1]);") 2259 2260 2261;; %%% Kill this when call knows how to work this out. 2262(define_split 2263 [(set (match_operand:SF 0 "push_operand" "") 2264 (match_operand:SF 1 "any_fp_register_operand" ""))] 2265 "!TARGET_64BIT" 2266 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) 2267 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))]) 2268 2269(define_split 2270 [(set (match_operand:SF 0 "push_operand" "") 2271 (match_operand:SF 1 "any_fp_register_operand" ""))] 2272 "TARGET_64BIT" 2273 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 2274 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))]) 2275 2276(define_insn "*movsf_1" 2277 [(set (match_operand:SF 0 "nonimmediate_operand" 2278 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y") 2279 (match_operand:SF 1 "general_operand" 2280 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))] 2281 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 2282 && (reload_in_progress || reload_completed 2283 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2284 || GET_CODE (operands[1]) != CONST_DOUBLE 2285 || memory_operand (operands[0], SFmode))" 2286{ 2287 switch (which_alternative) 2288 { 2289 case 0: 2290 return output_387_reg_move (insn, operands); 2291 2292 case 1: 2293 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2294 return "fstp%z0\t%y0"; 2295 else 2296 return "fst%z0\t%y0"; 2297 2298 case 2: 2299 return standard_80387_constant_opcode (operands[1]); 2300 2301 case 3: 2302 case 4: 2303 return "mov{l}\t{%1, %0|%0, %1}"; 2304 case 5: 2305 if (get_attr_mode (insn) == MODE_TI) 2306 return "pxor\t%0, %0"; 2307 else 2308 return "xorps\t%0, %0"; 2309 case 6: 2310 if (get_attr_mode (insn) == MODE_V4SF) 2311 return "movaps\t{%1, %0|%0, %1}"; 2312 else 2313 return "movss\t{%1, %0|%0, %1}"; 2314 case 7: 2315 case 8: 2316 return "movss\t{%1, %0|%0, %1}"; 2317 2318 case 9: 2319 case 10: 2320 return "movd\t{%1, %0|%0, %1}"; 2321 2322 case 11: 2323 return "movq\t{%1, %0|%0, %1}"; 2324 2325 default: 2326 gcc_unreachable (); 2327 } 2328} 2329 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov") 2330 (set (attr "mode") 2331 (cond [(eq_attr "alternative" "3,4,9,10") 2332 (const_string "SI") 2333 (eq_attr "alternative" "5") 2334 (if_then_else 2335 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") 2336 (const_int 0)) 2337 (ne (symbol_ref "TARGET_SSE2") 2338 (const_int 0))) 2339 (eq (symbol_ref "optimize_size") 2340 (const_int 0))) 2341 (const_string "TI") 2342 (const_string "V4SF")) 2343 /* For architectures resolving dependencies on 2344 whole SSE registers use APS move to break dependency 2345 chains, otherwise use short move to avoid extra work. 2346 2347 Do the same for architectures resolving dependencies on 2348 the parts. While in DF mode it is better to always handle 2349 just register parts, the SF mode is different due to lack 2350 of instructions to load just part of the register. It is 2351 better to maintain the whole registers in single format 2352 to avoid problems on using packed logical operations. */ 2353 (eq_attr "alternative" "6") 2354 (if_then_else 2355 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 2356 (const_int 0)) 2357 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") 2358 (const_int 0))) 2359 (const_string "V4SF") 2360 (const_string "SF")) 2361 (eq_attr "alternative" "11") 2362 (const_string "DI")] 2363 (const_string "SF")))]) 2364 2365(define_insn "*swapsf" 2366 [(set (match_operand:SF 0 "fp_register_operand" "+f") 2367 (match_operand:SF 1 "fp_register_operand" "+f")) 2368 (set (match_dup 1) 2369 (match_dup 0))] 2370 "reload_completed || TARGET_80387" 2371{ 2372 if (STACK_TOP_P (operands[0])) 2373 return "fxch\t%1"; 2374 else 2375 return "fxch\t%0"; 2376} 2377 [(set_attr "type" "fxch") 2378 (set_attr "mode" "SF")]) 2379 2380(define_expand "movdf" 2381 [(set (match_operand:DF 0 "nonimmediate_operand" "") 2382 (match_operand:DF 1 "general_operand" ""))] 2383 "" 2384 "ix86_expand_move (DFmode, operands); DONE;") 2385 2386;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. 2387;; Size of pushdf using integer instructions is 2+2*memory operand size 2388;; On the average, pushdf using integers can be still shorter. Allow this 2389;; pattern for optimize_size too. 2390 2391(define_insn "*pushdf_nointeger" 2392 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<") 2393 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))] 2394 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES" 2395{ 2396 /* This insn should be already split before reg-stack. */ 2397 gcc_unreachable (); 2398} 2399 [(set_attr "type" "multi") 2400 (set_attr "unit" "i387,*,*,*") 2401 (set_attr "mode" "DF,SI,SI,DF")]) 2402 2403(define_insn "*pushdf_integer" 2404 [(set (match_operand:DF 0 "push_operand" "=<,<,<") 2405 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))] 2406 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES" 2407{ 2408 /* This insn should be already split before reg-stack. */ 2409 gcc_unreachable (); 2410} 2411 [(set_attr "type" "multi") 2412 (set_attr "unit" "i387,*,*") 2413 (set_attr "mode" "DF,SI,DF")]) 2414 2415;; %%% Kill this when call knows how to work this out. 2416(define_split 2417 [(set (match_operand:DF 0 "push_operand" "") 2418 (match_operand:DF 1 "any_fp_register_operand" ""))] 2419 "!TARGET_64BIT && reload_completed" 2420 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 2421 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))] 2422 "") 2423 2424(define_split 2425 [(set (match_operand:DF 0 "push_operand" "") 2426 (match_operand:DF 1 "any_fp_register_operand" ""))] 2427 "TARGET_64BIT && reload_completed" 2428 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 2429 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))] 2430 "") 2431 2432(define_split 2433 [(set (match_operand:DF 0 "push_operand" "") 2434 (match_operand:DF 1 "general_operand" ""))] 2435 "reload_completed" 2436 [(const_int 0)] 2437 "ix86_split_long_move (operands); DONE;") 2438 2439;; Moving is usually shorter when only FP registers are used. This separate 2440;; movdf pattern avoids the use of integer registers for FP operations 2441;; when optimizing for size. 2442 2443(define_insn "*movdf_nointeger" 2444 [(set (match_operand:DF 0 "nonimmediate_operand" 2445 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ") 2446 (match_operand:DF 1 "general_operand" 2447 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))] 2448 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2449 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT) 2450 && (reload_in_progress || reload_completed 2451 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2452 || GET_CODE (operands[1]) != CONST_DOUBLE 2453 || memory_operand (operands[0], DFmode))" 2454{ 2455 switch (which_alternative) 2456 { 2457 case 0: 2458 return output_387_reg_move (insn, operands); 2459 2460 case 1: 2461 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2462 return "fstp%z0\t%y0"; 2463 else 2464 return "fst%z0\t%y0"; 2465 2466 case 2: 2467 return standard_80387_constant_opcode (operands[1]); 2468 2469 case 3: 2470 case 4: 2471 return "#"; 2472 case 5: 2473 switch (get_attr_mode (insn)) 2474 { 2475 case MODE_V4SF: 2476 return "xorps\t%0, %0"; 2477 case MODE_V2DF: 2478 return "xorpd\t%0, %0"; 2479 case MODE_TI: 2480 return "pxor\t%0, %0"; 2481 default: 2482 gcc_unreachable (); 2483 } 2484 case 6: 2485 case 7: 2486 case 8: 2487 switch (get_attr_mode (insn)) 2488 { 2489 case MODE_V4SF: 2490 return "movaps\t{%1, %0|%0, %1}"; 2491 case MODE_V2DF: 2492 return "movapd\t{%1, %0|%0, %1}"; 2493 case MODE_TI: 2494 return "movdqa\t{%1, %0|%0, %1}"; 2495 case MODE_DI: 2496 return "movq\t{%1, %0|%0, %1}"; 2497 case MODE_DF: 2498 return "movsd\t{%1, %0|%0, %1}"; 2499 case MODE_V1DF: 2500 return "movlpd\t{%1, %0|%0, %1}"; 2501 case MODE_V2SF: 2502 return "movlps\t{%1, %0|%0, %1}"; 2503 default: 2504 gcc_unreachable (); 2505 } 2506 2507 default: 2508 gcc_unreachable (); 2509 } 2510} 2511 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov") 2512 (set (attr "mode") 2513 (cond [(eq_attr "alternative" "0,1,2") 2514 (const_string "DF") 2515 (eq_attr "alternative" "3,4") 2516 (const_string "SI") 2517 2518 /* For SSE1, we have many fewer alternatives. */ 2519 (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 2520 (cond [(eq_attr "alternative" "5,6") 2521 (const_string "V4SF") 2522 ] 2523 (const_string "V2SF")) 2524 2525 /* xorps is one byte shorter. */ 2526 (eq_attr "alternative" "5") 2527 (cond [(ne (symbol_ref "optimize_size") 2528 (const_int 0)) 2529 (const_string "V4SF") 2530 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") 2531 (const_int 0)) 2532 (const_string "TI") 2533 ] 2534 (const_string "V2DF")) 2535 2536 /* For architectures resolving dependencies on 2537 whole SSE registers use APD move to break dependency 2538 chains, otherwise use short move to avoid extra work. 2539 2540 movaps encodes one byte shorter. */ 2541 (eq_attr "alternative" "6") 2542 (cond 2543 [(ne (symbol_ref "optimize_size") 2544 (const_int 0)) 2545 (const_string "V4SF") 2546 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 2547 (const_int 0)) 2548 (const_string "V2DF") 2549 ] 2550 (const_string "DF")) 2551 /* For architectures resolving dependencies on register 2552 parts we may avoid extra work to zero out upper part 2553 of register. */ 2554 (eq_attr "alternative" "7") 2555 (if_then_else 2556 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") 2557 (const_int 0)) 2558 (const_string "V1DF") 2559 (const_string "DF")) 2560 ] 2561 (const_string "DF")))]) 2562 2563(define_insn "*movdf_integer" 2564 [(set (match_operand:DF 0 "nonimmediate_operand" 2565 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ") 2566 (match_operand:DF 1 "general_operand" 2567 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))] 2568 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2569 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT) 2570 && (reload_in_progress || reload_completed 2571 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2572 || GET_CODE (operands[1]) != CONST_DOUBLE 2573 || memory_operand (operands[0], DFmode))" 2574{ 2575 switch (which_alternative) 2576 { 2577 case 0: 2578 return output_387_reg_move (insn, operands); 2579 2580 case 1: 2581 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2582 return "fstp%z0\t%y0"; 2583 else 2584 return "fst%z0\t%y0"; 2585 2586 case 2: 2587 return standard_80387_constant_opcode (operands[1]); 2588 2589 case 3: 2590 case 4: 2591 return "#"; 2592 2593 case 5: 2594 switch (get_attr_mode (insn)) 2595 { 2596 case MODE_V4SF: 2597 return "xorps\t%0, %0"; 2598 case MODE_V2DF: 2599 return "xorpd\t%0, %0"; 2600 case MODE_TI: 2601 return "pxor\t%0, %0"; 2602 default: 2603 gcc_unreachable (); 2604 } 2605 case 6: 2606 case 7: 2607 case 8: 2608 switch (get_attr_mode (insn)) 2609 { 2610 case MODE_V4SF: 2611 return "movaps\t{%1, %0|%0, %1}"; 2612 case MODE_V2DF: 2613 return "movapd\t{%1, %0|%0, %1}"; 2614 case MODE_TI: 2615 return "movdqa\t{%1, %0|%0, %1}"; 2616 case MODE_DI: 2617 return "movq\t{%1, %0|%0, %1}"; 2618 case MODE_DF: 2619 return "movsd\t{%1, %0|%0, %1}"; 2620 case MODE_V1DF: 2621 return "movlpd\t{%1, %0|%0, %1}"; 2622 case MODE_V2SF: 2623 return "movlps\t{%1, %0|%0, %1}"; 2624 default: 2625 gcc_unreachable (); 2626 } 2627 2628 default: 2629 gcc_unreachable(); 2630 } 2631} 2632 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov") 2633 (set (attr "mode") 2634 (cond [(eq_attr "alternative" "0,1,2") 2635 (const_string "DF") 2636 (eq_attr "alternative" "3,4") 2637 (const_string "SI") 2638 2639 /* For SSE1, we have many fewer alternatives. */ 2640 (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 2641 (cond [(eq_attr "alternative" "5,6") 2642 (const_string "V4SF") 2643 ] 2644 (const_string "V2SF")) 2645 2646 /* xorps is one byte shorter. */ 2647 (eq_attr "alternative" "5") 2648 (cond [(ne (symbol_ref "optimize_size") 2649 (const_int 0)) 2650 (const_string "V4SF") 2651 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") 2652 (const_int 0)) 2653 (const_string "TI") 2654 ] 2655 (const_string "V2DF")) 2656 2657 /* For architectures resolving dependencies on 2658 whole SSE registers use APD move to break dependency 2659 chains, otherwise use short move to avoid extra work. 2660 2661 movaps encodes one byte shorter. */ 2662 (eq_attr "alternative" "6") 2663 (cond 2664 [(ne (symbol_ref "optimize_size") 2665 (const_int 0)) 2666 (const_string "V4SF") 2667 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 2668 (const_int 0)) 2669 (const_string "V2DF") 2670 ] 2671 (const_string "DF")) 2672 /* For architectures resolving dependencies on register 2673 parts we may avoid extra work to zero out upper part 2674 of register. */ 2675 (eq_attr "alternative" "7") 2676 (if_then_else 2677 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") 2678 (const_int 0)) 2679 (const_string "V1DF") 2680 (const_string "DF")) 2681 ] 2682 (const_string "DF")))]) 2683 2684(define_split 2685 [(set (match_operand:DF 0 "nonimmediate_operand" "") 2686 (match_operand:DF 1 "general_operand" ""))] 2687 "reload_completed 2688 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2689 && ! (ANY_FP_REG_P (operands[0]) || 2690 (GET_CODE (operands[0]) == SUBREG 2691 && ANY_FP_REG_P (SUBREG_REG (operands[0])))) 2692 && ! (ANY_FP_REG_P (operands[1]) || 2693 (GET_CODE (operands[1]) == SUBREG 2694 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))" 2695 [(const_int 0)] 2696 "ix86_split_long_move (operands); DONE;") 2697 2698(define_insn "*swapdf" 2699 [(set (match_operand:DF 0 "fp_register_operand" "+f") 2700 (match_operand:DF 1 "fp_register_operand" "+f")) 2701 (set (match_dup 1) 2702 (match_dup 0))] 2703 "reload_completed || TARGET_80387" 2704{ 2705 if (STACK_TOP_P (operands[0])) 2706 return "fxch\t%1"; 2707 else 2708 return "fxch\t%0"; 2709} 2710 [(set_attr "type" "fxch") 2711 (set_attr "mode" "DF")]) 2712 2713(define_expand "movxf" 2714 [(set (match_operand:XF 0 "nonimmediate_operand" "") 2715 (match_operand:XF 1 "general_operand" ""))] 2716 "" 2717 "ix86_expand_move (XFmode, operands); DONE;") 2718 2719;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. 2720;; Size of pushdf using integer instructions is 3+3*memory operand size 2721;; Pushing using integer instructions is longer except for constants 2722;; and direct memory references. 2723;; (assuming that any given constant is pushed only once, but this ought to be 2724;; handled elsewhere). 2725 2726(define_insn "*pushxf_nointeger" 2727 [(set (match_operand:XF 0 "push_operand" "=X,X,X") 2728 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))] 2729 "optimize_size" 2730{ 2731 /* This insn should be already split before reg-stack. */ 2732 gcc_unreachable (); 2733} 2734 [(set_attr "type" "multi") 2735 (set_attr "unit" "i387,*,*") 2736 (set_attr "mode" "XF,SI,SI")]) 2737 2738(define_insn "*pushxf_integer" 2739 [(set (match_operand:XF 0 "push_operand" "=<,<") 2740 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))] 2741 "!optimize_size" 2742{ 2743 /* This insn should be already split before reg-stack. */ 2744 gcc_unreachable (); 2745} 2746 [(set_attr "type" "multi") 2747 (set_attr "unit" "i387,*") 2748 (set_attr "mode" "XF,SI")]) 2749 2750(define_split 2751 [(set (match_operand 0 "push_operand" "") 2752 (match_operand 1 "general_operand" ""))] 2753 "reload_completed 2754 && (GET_MODE (operands[0]) == XFmode 2755 || GET_MODE (operands[0]) == DFmode) 2756 && !ANY_FP_REG_P (operands[1])" 2757 [(const_int 0)] 2758 "ix86_split_long_move (operands); DONE;") 2759 2760(define_split 2761 [(set (match_operand:XF 0 "push_operand" "") 2762 (match_operand:XF 1 "any_fp_register_operand" ""))] 2763 "!TARGET_64BIT" 2764 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2))) 2765 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))] 2766 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 2767 2768(define_split 2769 [(set (match_operand:XF 0 "push_operand" "") 2770 (match_operand:XF 1 "any_fp_register_operand" ""))] 2771 "TARGET_64BIT" 2772 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2))) 2773 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))] 2774 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 2775 2776;; Do not use integer registers when optimizing for size 2777(define_insn "*movxf_nointeger" 2778 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o") 2779 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))] 2780 "optimize_size 2781 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2782 && (reload_in_progress || reload_completed 2783 || GET_CODE (operands[1]) != CONST_DOUBLE 2784 || memory_operand (operands[0], XFmode))" 2785{ 2786 switch (which_alternative) 2787 { 2788 case 0: 2789 return output_387_reg_move (insn, operands); 2790 2791 case 1: 2792 /* There is no non-popping store to memory for XFmode. So if 2793 we need one, follow the store with a load. */ 2794 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2795 return "fstp%z0\t%y0\;fld%z0\t%y0"; 2796 else 2797 return "fstp%z0\t%y0"; 2798 2799 case 2: 2800 return standard_80387_constant_opcode (operands[1]); 2801 2802 case 3: case 4: 2803 return "#"; 2804 default: 2805 gcc_unreachable (); 2806 } 2807} 2808 [(set_attr "type" "fmov,fmov,fmov,multi,multi") 2809 (set_attr "mode" "XF,XF,XF,SI,SI")]) 2810 2811(define_insn "*movxf_integer" 2812 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o") 2813 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))] 2814 "!optimize_size 2815 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2816 && (reload_in_progress || reload_completed 2817 || GET_CODE (operands[1]) != CONST_DOUBLE 2818 || memory_operand (operands[0], XFmode))" 2819{ 2820 switch (which_alternative) 2821 { 2822 case 0: 2823 return output_387_reg_move (insn, operands); 2824 2825 case 1: 2826 /* There is no non-popping store to memory for XFmode. So if 2827 we need one, follow the store with a load. */ 2828 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2829 return "fstp%z0\t%y0\;fld%z0\t%y0"; 2830 else 2831 return "fstp%z0\t%y0"; 2832 2833 case 2: 2834 return standard_80387_constant_opcode (operands[1]); 2835 2836 case 3: case 4: 2837 return "#"; 2838 2839 default: 2840 gcc_unreachable (); 2841 } 2842} 2843 [(set_attr "type" "fmov,fmov,fmov,multi,multi") 2844 (set_attr "mode" "XF,XF,XF,SI,SI")]) 2845 2846(define_split 2847 [(set (match_operand 0 "nonimmediate_operand" "") 2848 (match_operand 1 "general_operand" ""))] 2849 "reload_completed 2850 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2851 && GET_MODE (operands[0]) == XFmode 2852 && ! (ANY_FP_REG_P (operands[0]) || 2853 (GET_CODE (operands[0]) == SUBREG 2854 && ANY_FP_REG_P (SUBREG_REG (operands[0])))) 2855 && ! (ANY_FP_REG_P (operands[1]) || 2856 (GET_CODE (operands[1]) == SUBREG 2857 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))" 2858 [(const_int 0)] 2859 "ix86_split_long_move (operands); DONE;") 2860 2861(define_split 2862 [(set (match_operand 0 "register_operand" "") 2863 (match_operand 1 "memory_operand" ""))] 2864 "reload_completed 2865 && GET_CODE (operands[1]) == MEM 2866 && (GET_MODE (operands[0]) == XFmode 2867 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode) 2868 && constant_pool_reference_p (operands[1])" 2869 [(set (match_dup 0) (match_dup 1))] 2870{ 2871 rtx c = avoid_constant_pool_reference (operands[1]); 2872 rtx r = operands[0]; 2873 2874 if (GET_CODE (r) == SUBREG) 2875 r = SUBREG_REG (r); 2876 2877 if (SSE_REG_P (r)) 2878 { 2879 if (!standard_sse_constant_p (c)) 2880 FAIL; 2881 } 2882 else if (FP_REG_P (r)) 2883 { 2884 if (!standard_80387_constant_p (c)) 2885 FAIL; 2886 } 2887 else if (MMX_REG_P (r)) 2888 FAIL; 2889 2890 operands[1] = c; 2891}) 2892 2893(define_insn "swapxf" 2894 [(set (match_operand:XF 0 "register_operand" "+f") 2895 (match_operand:XF 1 "register_operand" "+f")) 2896 (set (match_dup 1) 2897 (match_dup 0))] 2898 "TARGET_80387" 2899{ 2900 if (STACK_TOP_P (operands[0])) 2901 return "fxch\t%1"; 2902 else 2903 return "fxch\t%0"; 2904} 2905 [(set_attr "type" "fxch") 2906 (set_attr "mode" "XF")]) 2907 2908(define_expand "movtf" 2909 [(set (match_operand:TF 0 "nonimmediate_operand" "") 2910 (match_operand:TF 1 "nonimmediate_operand" ""))] 2911 "TARGET_64BIT" 2912{ 2913 ix86_expand_move (TFmode, operands); 2914 DONE; 2915}) 2916 2917(define_insn "*movtf_internal" 2918 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm") 2919 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))] 2920 "TARGET_64BIT 2921 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 2922{ 2923 switch (which_alternative) 2924 { 2925 case 0: 2926 case 1: 2927 return "#"; 2928 case 2: 2929 if (get_attr_mode (insn) == MODE_V4SF) 2930 return "xorps\t%0, %0"; 2931 else 2932 return "pxor\t%0, %0"; 2933 case 3: 2934 case 4: 2935 if (get_attr_mode (insn) == MODE_V4SF) 2936 return "movaps\t{%1, %0|%0, %1}"; 2937 else 2938 return "movdqa\t{%1, %0|%0, %1}"; 2939 default: 2940 gcc_unreachable (); 2941 } 2942} 2943 [(set_attr "type" "*,*,sselog1,ssemov,ssemov") 2944 (set (attr "mode") 2945 (cond [(eq_attr "alternative" "2,3") 2946 (if_then_else 2947 (ne (symbol_ref "optimize_size") 2948 (const_int 0)) 2949 (const_string "V4SF") 2950 (const_string "TI")) 2951 (eq_attr "alternative" "4") 2952 (if_then_else 2953 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") 2954 (const_int 0)) 2955 (ne (symbol_ref "optimize_size") 2956 (const_int 0))) 2957 (const_string "V4SF") 2958 (const_string "TI"))] 2959 (const_string "DI")))]) 2960 2961(define_split 2962 [(set (match_operand:TF 0 "nonimmediate_operand" "") 2963 (match_operand:TF 1 "general_operand" ""))] 2964 "reload_completed && !SSE_REG_P (operands[0]) 2965 && !SSE_REG_P (operands[1])" 2966 [(const_int 0)] 2967 "ix86_split_long_move (operands); DONE;") 2968 2969;; Zero extension instructions 2970 2971(define_expand "zero_extendhisi2" 2972 [(set (match_operand:SI 0 "register_operand" "") 2973 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 2974 "" 2975{ 2976 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) 2977 { 2978 operands[1] = force_reg (HImode, operands[1]); 2979 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1])); 2980 DONE; 2981 } 2982}) 2983 2984(define_insn "zero_extendhisi2_and" 2985 [(set (match_operand:SI 0 "register_operand" "=r") 2986 (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))) 2987 (clobber (reg:CC FLAGS_REG))] 2988 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 2989 "#" 2990 [(set_attr "type" "alu1") 2991 (set_attr "mode" "SI")]) 2992 2993(define_split 2994 [(set (match_operand:SI 0 "register_operand" "") 2995 (zero_extend:SI (match_operand:HI 1 "register_operand" ""))) 2996 (clobber (reg:CC FLAGS_REG))] 2997 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 2998 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535))) 2999 (clobber (reg:CC FLAGS_REG))])] 3000 "") 3001 3002(define_insn "*zero_extendhisi2_movzwl" 3003 [(set (match_operand:SI 0 "register_operand" "=r") 3004 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3005 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" 3006 "movz{wl|x}\t{%1, %0|%0, %1}" 3007 [(set_attr "type" "imovx") 3008 (set_attr "mode" "SI")]) 3009 3010(define_expand "zero_extendqihi2" 3011 [(parallel 3012 [(set (match_operand:HI 0 "register_operand" "") 3013 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) 3014 (clobber (reg:CC FLAGS_REG))])] 3015 "" 3016 "") 3017 3018(define_insn "*zero_extendqihi2_and" 3019 [(set (match_operand:HI 0 "register_operand" "=r,?&q") 3020 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) 3021 (clobber (reg:CC FLAGS_REG))] 3022 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 3023 "#" 3024 [(set_attr "type" "alu1") 3025 (set_attr "mode" "HI")]) 3026 3027(define_insn "*zero_extendqihi2_movzbw_and" 3028 [(set (match_operand:HI 0 "register_operand" "=r,r") 3029 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) 3030 (clobber (reg:CC FLAGS_REG))] 3031 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" 3032 "#" 3033 [(set_attr "type" "imovx,alu1") 3034 (set_attr "mode" "HI")]) 3035 3036; zero extend to SImode here to avoid partial register stalls 3037(define_insn "*zero_extendqihi2_movzbl" 3038 [(set (match_operand:HI 0 "register_operand" "=r") 3039 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3040 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed" 3041 "movz{bl|x}\t{%1, %k0|%k0, %k1}" 3042 [(set_attr "type" "imovx") 3043 (set_attr "mode" "SI")]) 3044 3045;; For the movzbw case strip only the clobber 3046(define_split 3047 [(set (match_operand:HI 0 "register_operand" "") 3048 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) 3049 (clobber (reg:CC FLAGS_REG))] 3050 "reload_completed 3051 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) 3052 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" 3053 [(set (match_operand:HI 0 "register_operand" "") 3054 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]) 3055 3056;; When source and destination does not overlap, clear destination 3057;; first and then do the movb 3058(define_split 3059 [(set (match_operand:HI 0 "register_operand" "") 3060 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) 3061 (clobber (reg:CC FLAGS_REG))] 3062 "reload_completed 3063 && ANY_QI_REG_P (operands[0]) 3064 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) 3065 && !reg_overlap_mentioned_p (operands[0], operands[1])" 3066 [(set (match_dup 0) (const_int 0)) 3067 (set (strict_low_part (match_dup 2)) (match_dup 1))] 3068 "operands[2] = gen_lowpart (QImode, operands[0]);") 3069 3070;; Rest is handled by single and. 3071(define_split 3072 [(set (match_operand:HI 0 "register_operand" "") 3073 (zero_extend:HI (match_operand:QI 1 "register_operand" ""))) 3074 (clobber (reg:CC FLAGS_REG))] 3075 "reload_completed 3076 && true_regnum (operands[0]) == true_regnum (operands[1])" 3077 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255))) 3078 (clobber (reg:CC FLAGS_REG))])] 3079 "") 3080 3081(define_expand "zero_extendqisi2" 3082 [(parallel 3083 [(set (match_operand:SI 0 "register_operand" "") 3084 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) 3085 (clobber (reg:CC FLAGS_REG))])] 3086 "" 3087 "") 3088 3089(define_insn "*zero_extendqisi2_and" 3090 [(set (match_operand:SI 0 "register_operand" "=r,?&q") 3091 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) 3092 (clobber (reg:CC FLAGS_REG))] 3093 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 3094 "#" 3095 [(set_attr "type" "alu1") 3096 (set_attr "mode" "SI")]) 3097 3098(define_insn "*zero_extendqisi2_movzbw_and" 3099 [(set (match_operand:SI 0 "register_operand" "=r,r") 3100 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) 3101 (clobber (reg:CC FLAGS_REG))] 3102 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" 3103 "#" 3104 [(set_attr "type" "imovx,alu1") 3105 (set_attr "mode" "SI")]) 3106 3107(define_insn "*zero_extendqisi2_movzbw" 3108 [(set (match_operand:SI 0 "register_operand" "=r") 3109 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3110 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed" 3111 "movz{bl|x}\t{%1, %0|%0, %1}" 3112 [(set_attr "type" "imovx") 3113 (set_attr "mode" "SI")]) 3114 3115;; For the movzbl case strip only the clobber 3116(define_split 3117 [(set (match_operand:SI 0 "register_operand" "") 3118 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) 3119 (clobber (reg:CC FLAGS_REG))] 3120 "reload_completed 3121 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) 3122 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" 3123 [(set (match_dup 0) 3124 (zero_extend:SI (match_dup 1)))]) 3125 3126;; When source and destination does not overlap, clear destination 3127;; first and then do the movb 3128(define_split 3129 [(set (match_operand:SI 0 "register_operand" "") 3130 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) 3131 (clobber (reg:CC FLAGS_REG))] 3132 "reload_completed 3133 && ANY_QI_REG_P (operands[0]) 3134 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM) 3135 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) 3136 && !reg_overlap_mentioned_p (operands[0], operands[1])" 3137 [(set (match_dup 0) (const_int 0)) 3138 (set (strict_low_part (match_dup 2)) (match_dup 1))] 3139 "operands[2] = gen_lowpart (QImode, operands[0]);") 3140 3141;; Rest is handled by single and. 3142(define_split 3143 [(set (match_operand:SI 0 "register_operand" "") 3144 (zero_extend:SI (match_operand:QI 1 "register_operand" ""))) 3145 (clobber (reg:CC FLAGS_REG))] 3146 "reload_completed 3147 && true_regnum (operands[0]) == true_regnum (operands[1])" 3148 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255))) 3149 (clobber (reg:CC FLAGS_REG))])] 3150 "") 3151 3152;; %%% Kill me once multi-word ops are sane. 3153(define_expand "zero_extendsidi2" 3154 [(set (match_operand:DI 0 "register_operand" "=r") 3155 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))] 3156 "" 3157 "if (!TARGET_64BIT) 3158 { 3159 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1])); 3160 DONE; 3161 } 3162 ") 3163 3164(define_insn "zero_extendsidi2_32" 3165 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y") 3166 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm"))) 3167 (clobber (reg:CC FLAGS_REG))] 3168 "!TARGET_64BIT" 3169 "@ 3170 # 3171 # 3172 # 3173 movd\t{%1, %0|%0, %1} 3174 movd\t{%1, %0|%0, %1}" 3175 [(set_attr "mode" "SI,SI,SI,DI,TI") 3176 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")]) 3177 3178(define_insn "zero_extendsidi2_rex64" 3179 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y") 3180 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))] 3181 "TARGET_64BIT" 3182 "@ 3183 mov\t{%k1, %k0|%k0, %k1} 3184 # 3185 movd\t{%1, %0|%0, %1} 3186 movd\t{%1, %0|%0, %1}" 3187 [(set_attr "type" "imovx,imov,mmxmov,ssemov") 3188 (set_attr "mode" "SI,DI,SI,SI")]) 3189 3190(define_split 3191 [(set (match_operand:DI 0 "memory_operand" "") 3192 (zero_extend:DI (match_dup 0)))] 3193 "TARGET_64BIT" 3194 [(set (match_dup 4) (const_int 0))] 3195 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3196 3197(define_split 3198 [(set (match_operand:DI 0 "register_operand" "") 3199 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) 3200 (clobber (reg:CC FLAGS_REG))] 3201 "!TARGET_64BIT && reload_completed 3202 && true_regnum (operands[0]) == true_regnum (operands[1])" 3203 [(set (match_dup 4) (const_int 0))] 3204 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3205 3206(define_split 3207 [(set (match_operand:DI 0 "nonimmediate_operand" "") 3208 (zero_extend:DI (match_operand:SI 1 "general_operand" ""))) 3209 (clobber (reg:CC FLAGS_REG))] 3210 "!TARGET_64BIT && reload_completed 3211 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])" 3212 [(set (match_dup 3) (match_dup 1)) 3213 (set (match_dup 4) (const_int 0))] 3214 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3215 3216(define_insn "zero_extendhidi2" 3217 [(set (match_operand:DI 0 "register_operand" "=r") 3218 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3219 "TARGET_64BIT" 3220 "movz{wl|x}\t{%1, %k0|%k0, %1}" 3221 [(set_attr "type" "imovx") 3222 (set_attr "mode" "DI")]) 3223 3224(define_insn "zero_extendqidi2" 3225 [(set (match_operand:DI 0 "register_operand" "=r") 3226 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))] 3227 "TARGET_64BIT" 3228 "movz{bl|x}\t{%1, %k0|%k0, %1}" 3229 [(set_attr "type" "imovx") 3230 (set_attr "mode" "DI")]) 3231 3232;; Sign extension instructions 3233 3234(define_expand "extendsidi2" 3235 [(parallel [(set (match_operand:DI 0 "register_operand" "") 3236 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3237 (clobber (reg:CC FLAGS_REG)) 3238 (clobber (match_scratch:SI 2 ""))])] 3239 "" 3240{ 3241 if (TARGET_64BIT) 3242 { 3243 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1])); 3244 DONE; 3245 } 3246}) 3247 3248(define_insn "*extendsidi2_1" 3249 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o") 3250 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r"))) 3251 (clobber (reg:CC FLAGS_REG)) 3252 (clobber (match_scratch:SI 2 "=X,X,X,&r"))] 3253 "!TARGET_64BIT" 3254 "#") 3255 3256(define_insn "extendsidi2_rex64" 3257 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3258 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))] 3259 "TARGET_64BIT" 3260 "@ 3261 {cltq|cdqe} 3262 movs{lq|x}\t{%1,%0|%0, %1}" 3263 [(set_attr "type" "imovx") 3264 (set_attr "mode" "DI") 3265 (set_attr "prefix_0f" "0") 3266 (set_attr "modrm" "0,1")]) 3267 3268(define_insn "extendhidi2" 3269 [(set (match_operand:DI 0 "register_operand" "=r") 3270 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3271 "TARGET_64BIT" 3272 "movs{wq|x}\t{%1,%0|%0, %1}" 3273 [(set_attr "type" "imovx") 3274 (set_attr "mode" "DI")]) 3275 3276(define_insn "extendqidi2" 3277 [(set (match_operand:DI 0 "register_operand" "=r") 3278 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3279 "TARGET_64BIT" 3280 "movs{bq|x}\t{%1,%0|%0, %1}" 3281 [(set_attr "type" "imovx") 3282 (set_attr "mode" "DI")]) 3283 3284;; Extend to memory case when source register does die. 3285(define_split 3286 [(set (match_operand:DI 0 "memory_operand" "") 3287 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3288 (clobber (reg:CC FLAGS_REG)) 3289 (clobber (match_operand:SI 2 "register_operand" ""))] 3290 "(reload_completed 3291 && dead_or_set_p (insn, operands[1]) 3292 && !reg_mentioned_p (operands[1], operands[0]))" 3293 [(set (match_dup 3) (match_dup 1)) 3294 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) 3295 (clobber (reg:CC FLAGS_REG))]) 3296 (set (match_dup 4) (match_dup 1))] 3297 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3298 3299;; Extend to memory case when source register does not die. 3300(define_split 3301 [(set (match_operand:DI 0 "memory_operand" "") 3302 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3303 (clobber (reg:CC FLAGS_REG)) 3304 (clobber (match_operand:SI 2 "register_operand" ""))] 3305 "reload_completed" 3306 [(const_int 0)] 3307{ 3308 split_di (&operands[0], 1, &operands[3], &operands[4]); 3309 3310 emit_move_insn (operands[3], operands[1]); 3311 3312 /* Generate a cltd if possible and doing so it profitable. */ 3313 if (true_regnum (operands[1]) == 0 3314 && true_regnum (operands[2]) == 1 3315 && (optimize_size || TARGET_USE_CLTD)) 3316 { 3317 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31))); 3318 } 3319 else 3320 { 3321 emit_move_insn (operands[2], operands[1]); 3322 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31))); 3323 } 3324 emit_move_insn (operands[4], operands[2]); 3325 DONE; 3326}) 3327 3328;; Extend to register case. Optimize case where source and destination 3329;; registers match and cases where we can use cltd. 3330(define_split 3331 [(set (match_operand:DI 0 "register_operand" "") 3332 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3333 (clobber (reg:CC FLAGS_REG)) 3334 (clobber (match_scratch:SI 2 ""))] 3335 "reload_completed" 3336 [(const_int 0)] 3337{ 3338 split_di (&operands[0], 1, &operands[3], &operands[4]); 3339 3340 if (true_regnum (operands[3]) != true_regnum (operands[1])) 3341 emit_move_insn (operands[3], operands[1]); 3342 3343 /* Generate a cltd if possible and doing so it profitable. */ 3344 if (true_regnum (operands[3]) == 0 3345 && (optimize_size || TARGET_USE_CLTD)) 3346 { 3347 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31))); 3348 DONE; 3349 } 3350 3351 if (true_regnum (operands[4]) != true_regnum (operands[1])) 3352 emit_move_insn (operands[4], operands[1]); 3353 3354 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31))); 3355 DONE; 3356}) 3357 3358(define_insn "extendhisi2" 3359 [(set (match_operand:SI 0 "register_operand" "=*a,r") 3360 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))] 3361 "" 3362{ 3363 switch (get_attr_prefix_0f (insn)) 3364 { 3365 case 0: 3366 return "{cwtl|cwde}"; 3367 default: 3368 return "movs{wl|x}\t{%1,%0|%0, %1}"; 3369 } 3370} 3371 [(set_attr "type" "imovx") 3372 (set_attr "mode" "SI") 3373 (set (attr "prefix_0f") 3374 ;; movsx is short decodable while cwtl is vector decoded. 3375 (if_then_else (and (eq_attr "cpu" "!k6") 3376 (eq_attr "alternative" "0")) 3377 (const_string "0") 3378 (const_string "1"))) 3379 (set (attr "modrm") 3380 (if_then_else (eq_attr "prefix_0f" "0") 3381 (const_string "0") 3382 (const_string "1")))]) 3383 3384(define_insn "*extendhisi2_zext" 3385 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3386 (zero_extend:DI 3387 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))] 3388 "TARGET_64BIT" 3389{ 3390 switch (get_attr_prefix_0f (insn)) 3391 { 3392 case 0: 3393 return "{cwtl|cwde}"; 3394 default: 3395 return "movs{wl|x}\t{%1,%k0|%k0, %1}"; 3396 } 3397} 3398 [(set_attr "type" "imovx") 3399 (set_attr "mode" "SI") 3400 (set (attr "prefix_0f") 3401 ;; movsx is short decodable while cwtl is vector decoded. 3402 (if_then_else (and (eq_attr "cpu" "!k6") 3403 (eq_attr "alternative" "0")) 3404 (const_string "0") 3405 (const_string "1"))) 3406 (set (attr "modrm") 3407 (if_then_else (eq_attr "prefix_0f" "0") 3408 (const_string "0") 3409 (const_string "1")))]) 3410 3411(define_insn "extendqihi2" 3412 [(set (match_operand:HI 0 "register_operand" "=*a,r") 3413 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))] 3414 "" 3415{ 3416 switch (get_attr_prefix_0f (insn)) 3417 { 3418 case 0: 3419 return "{cbtw|cbw}"; 3420 default: 3421 return "movs{bw|x}\t{%1,%0|%0, %1}"; 3422 } 3423} 3424 [(set_attr "type" "imovx") 3425 (set_attr "mode" "HI") 3426 (set (attr "prefix_0f") 3427 ;; movsx is short decodable while cwtl is vector decoded. 3428 (if_then_else (and (eq_attr "cpu" "!k6") 3429 (eq_attr "alternative" "0")) 3430 (const_string "0") 3431 (const_string "1"))) 3432 (set (attr "modrm") 3433 (if_then_else (eq_attr "prefix_0f" "0") 3434 (const_string "0") 3435 (const_string "1")))]) 3436 3437(define_insn "extendqisi2" 3438 [(set (match_operand:SI 0 "register_operand" "=r") 3439 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3440 "" 3441 "movs{bl|x}\t{%1,%0|%0, %1}" 3442 [(set_attr "type" "imovx") 3443 (set_attr "mode" "SI")]) 3444 3445(define_insn "*extendqisi2_zext" 3446 [(set (match_operand:DI 0 "register_operand" "=r") 3447 (zero_extend:DI 3448 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))] 3449 "TARGET_64BIT" 3450 "movs{bl|x}\t{%1,%k0|%k0, %1}" 3451 [(set_attr "type" "imovx") 3452 (set_attr "mode" "SI")]) 3453 3454;; Conversions between float and double. 3455 3456;; These are all no-ops in the model used for the 80387. So just 3457;; emit moves. 3458 3459;; %%% Kill these when call knows how to work out a DFmode push earlier. 3460(define_insn "*dummy_extendsfdf2" 3461 [(set (match_operand:DF 0 "push_operand" "=<") 3462 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))] 3463 "0" 3464 "#") 3465 3466(define_split 3467 [(set (match_operand:DF 0 "push_operand" "") 3468 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))] 3469 "!TARGET_64BIT" 3470 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 3471 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))]) 3472 3473(define_split 3474 [(set (match_operand:DF 0 "push_operand" "") 3475 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))] 3476 "TARGET_64BIT" 3477 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 3478 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))]) 3479 3480(define_insn "*dummy_extendsfxf2" 3481 [(set (match_operand:XF 0 "push_operand" "=<") 3482 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))] 3483 "0" 3484 "#") 3485 3486(define_split 3487 [(set (match_operand:XF 0 "push_operand" "") 3488 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))] 3489 "" 3490 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2))) 3491 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))] 3492 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3493 3494(define_split 3495 [(set (match_operand:XF 0 "push_operand" "") 3496 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))] 3497 "TARGET_64BIT" 3498 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2))) 3499 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))] 3500 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3501 3502(define_split 3503 [(set (match_operand:XF 0 "push_operand" "") 3504 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))] 3505 "" 3506 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2))) 3507 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))] 3508 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3509 3510(define_split 3511 [(set (match_operand:XF 0 "push_operand" "") 3512 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))] 3513 "TARGET_64BIT" 3514 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2))) 3515 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))] 3516 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3517 3518(define_expand "extendsfdf2" 3519 [(set (match_operand:DF 0 "nonimmediate_operand" "") 3520 (float_extend:DF (match_operand:SF 1 "general_operand" "")))] 3521 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 3522{ 3523 /* ??? Needed for compress_float_constant since all fp constants 3524 are LEGITIMATE_CONSTANT_P. */ 3525 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3526 { 3527 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387) 3528 && standard_80387_constant_p (operands[1]) > 0) 3529 { 3530 operands[1] = simplify_const_unary_operation 3531 (FLOAT_EXTEND, DFmode, operands[1], SFmode); 3532 emit_move_insn_1 (operands[0], operands[1]); 3533 DONE; 3534 } 3535 operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 3536 } 3537 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 3538 operands[1] = force_reg (SFmode, operands[1]); 3539}) 3540 3541(define_insn "*extendsfdf2_mixed" 3542 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y") 3543 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))] 3544 "TARGET_SSE2 && TARGET_MIX_SSE_I387 3545 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3546{ 3547 switch (which_alternative) 3548 { 3549 case 0: 3550 return output_387_reg_move (insn, operands); 3551 3552 case 1: 3553 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3554 return "fstp%z0\t%y0"; 3555 else 3556 return "fst%z0\t%y0"; 3557 3558 case 2: 3559 return "cvtss2sd\t{%1, %0|%0, %1}"; 3560 3561 default: 3562 gcc_unreachable (); 3563 } 3564} 3565 [(set_attr "type" "fmov,fmov,ssecvt") 3566 (set_attr "mode" "SF,XF,DF")]) 3567 3568(define_insn "*extendsfdf2_sse" 3569 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y") 3570 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))] 3571 "TARGET_SSE2 && TARGET_SSE_MATH 3572 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3573 "cvtss2sd\t{%1, %0|%0, %1}" 3574 [(set_attr "type" "ssecvt") 3575 (set_attr "mode" "DF")]) 3576 3577(define_insn "*extendsfdf2_i387" 3578 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m") 3579 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 3580 "TARGET_80387 3581 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3582{ 3583 switch (which_alternative) 3584 { 3585 case 0: 3586 return output_387_reg_move (insn, operands); 3587 3588 case 1: 3589 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3590 return "fstp%z0\t%y0"; 3591 else 3592 return "fst%z0\t%y0"; 3593 3594 default: 3595 gcc_unreachable (); 3596 } 3597} 3598 [(set_attr "type" "fmov") 3599 (set_attr "mode" "SF,XF")]) 3600 3601(define_expand "extendsfxf2" 3602 [(set (match_operand:XF 0 "nonimmediate_operand" "") 3603 (float_extend:XF (match_operand:SF 1 "general_operand" "")))] 3604 "TARGET_80387" 3605{ 3606 /* ??? Needed for compress_float_constant since all fp constants 3607 are LEGITIMATE_CONSTANT_P. */ 3608 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3609 { 3610 if (standard_80387_constant_p (operands[1]) > 0) 3611 { 3612 operands[1] = simplify_const_unary_operation 3613 (FLOAT_EXTEND, XFmode, operands[1], SFmode); 3614 emit_move_insn_1 (operands[0], operands[1]); 3615 DONE; 3616 } 3617 operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 3618 } 3619 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 3620 operands[1] = force_reg (SFmode, operands[1]); 3621}) 3622 3623(define_insn "*extendsfxf2_i387" 3624 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 3625 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 3626 "TARGET_80387 3627 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3628{ 3629 switch (which_alternative) 3630 { 3631 case 0: 3632 return output_387_reg_move (insn, operands); 3633 3634 case 1: 3635 /* There is no non-popping store to memory for XFmode. So if 3636 we need one, follow the store with a load. */ 3637 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3638 return "fstp%z0\t%y0"; 3639 else 3640 return "fstp%z0\t%y0\n\tfld%z0\t%y0"; 3641 3642 default: 3643 gcc_unreachable (); 3644 } 3645} 3646 [(set_attr "type" "fmov") 3647 (set_attr "mode" "SF,XF")]) 3648 3649(define_expand "extenddfxf2" 3650 [(set (match_operand:XF 0 "nonimmediate_operand" "") 3651 (float_extend:XF (match_operand:DF 1 "general_operand" "")))] 3652 "TARGET_80387" 3653{ 3654 /* ??? Needed for compress_float_constant since all fp constants 3655 are LEGITIMATE_CONSTANT_P. */ 3656 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3657 { 3658 if (standard_80387_constant_p (operands[1]) > 0) 3659 { 3660 operands[1] = simplify_const_unary_operation 3661 (FLOAT_EXTEND, XFmode, operands[1], DFmode); 3662 emit_move_insn_1 (operands[0], operands[1]); 3663 DONE; 3664 } 3665 operands[1] = validize_mem (force_const_mem (DFmode, operands[1])); 3666 } 3667 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 3668 operands[1] = force_reg (DFmode, operands[1]); 3669}) 3670 3671(define_insn "*extenddfxf2_i387" 3672 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 3673 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))] 3674 "TARGET_80387 3675 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3676{ 3677 switch (which_alternative) 3678 { 3679 case 0: 3680 return output_387_reg_move (insn, operands); 3681 3682 case 1: 3683 /* There is no non-popping store to memory for XFmode. So if 3684 we need one, follow the store with a load. */ 3685 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3686 return "fstp%z0\t%y0\n\tfld%z0\t%y0"; 3687 else 3688 return "fstp%z0\t%y0"; 3689 3690 default: 3691 gcc_unreachable (); 3692 } 3693} 3694 [(set_attr "type" "fmov") 3695 (set_attr "mode" "DF,XF")]) 3696 3697;; %%% This seems bad bad news. 3698;; This cannot output into an f-reg because there is no way to be sure 3699;; of truncating in that case. Otherwise this is just like a simple move 3700;; insn. So we pretend we can output to a reg in order to get better 3701;; register preferencing, but we really use a stack slot. 3702 3703;; Conversion from DFmode to SFmode. 3704 3705(define_expand "truncdfsf2" 3706 [(set (match_operand:SF 0 "nonimmediate_operand" "") 3707 (float_truncate:SF 3708 (match_operand:DF 1 "nonimmediate_operand" "")))] 3709 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 3710{ 3711 if (MEM_P (operands[0]) && MEM_P (operands[1])) 3712 operands[1] = force_reg (DFmode, operands[1]); 3713 3714 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387) 3715 ; 3716 else if (flag_unsafe_math_optimizations) 3717 ; 3718 else 3719 { 3720 rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL); 3721 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp)); 3722 DONE; 3723 } 3724}) 3725 3726(define_expand "truncdfsf2_with_temp" 3727 [(parallel [(set (match_operand:SF 0 "" "") 3728 (float_truncate:SF (match_operand:DF 1 "" ""))) 3729 (clobber (match_operand:SF 2 "" ""))])] 3730 "") 3731 3732(define_insn "*truncdfsf_fast_mixed" 3733 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y") 3734 (float_truncate:SF 3735 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))] 3736 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations" 3737{ 3738 switch (which_alternative) 3739 { 3740 case 0: 3741 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3742 return "fstp%z0\t%y0"; 3743 else 3744 return "fst%z0\t%y0"; 3745 case 1: 3746 return output_387_reg_move (insn, operands); 3747 case 2: 3748 return "cvtsd2ss\t{%1, %0|%0, %1}"; 3749 default: 3750 gcc_unreachable (); 3751 } 3752} 3753 [(set_attr "type" "fmov,fmov,ssecvt") 3754 (set_attr "mode" "SF")]) 3755 3756;; Yes, this one doesn't depend on flag_unsafe_math_optimizations, 3757;; because nothing we do here is unsafe. 3758(define_insn "*truncdfsf_fast_sse" 3759 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y") 3760 (float_truncate:SF 3761 (match_operand:DF 1 "nonimmediate_operand" "Ym")))] 3762 "TARGET_SSE2 && TARGET_SSE_MATH" 3763 "cvtsd2ss\t{%1, %0|%0, %1}" 3764 [(set_attr "type" "ssecvt") 3765 (set_attr "mode" "SF")]) 3766 3767(define_insn "*truncdfsf_fast_i387" 3768 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm") 3769 (float_truncate:SF 3770 (match_operand:DF 1 "nonimmediate_operand" "f")))] 3771 "TARGET_80387 && flag_unsafe_math_optimizations" 3772 "* return output_387_reg_move (insn, operands);" 3773 [(set_attr "type" "fmov") 3774 (set_attr "mode" "SF")]) 3775 3776(define_insn "*truncdfsf_mixed" 3777 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y") 3778 (float_truncate:SF 3779 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym"))) 3780 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))] 3781 "TARGET_MIX_SSE_I387" 3782{ 3783 switch (which_alternative) 3784 { 3785 case 0: 3786 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3787 return "fstp%z0\t%y0"; 3788 else 3789 return "fst%z0\t%y0"; 3790 case 1: 3791 return "#"; 3792 case 2: 3793 return "cvtsd2ss\t{%1, %0|%0, %1}"; 3794 default: 3795 gcc_unreachable (); 3796 } 3797} 3798 [(set_attr "type" "fmov,multi,ssecvt") 3799 (set_attr "unit" "*,i387,*") 3800 (set_attr "mode" "SF")]) 3801 3802(define_insn "*truncdfsf_i387" 3803 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r") 3804 (float_truncate:SF 3805 (match_operand:DF 1 "nonimmediate_operand" "f,f"))) 3806 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))] 3807 "TARGET_80387" 3808{ 3809 switch (which_alternative) 3810 { 3811 case 0: 3812 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3813 return "fstp%z0\t%y0"; 3814 else 3815 return "fst%z0\t%y0"; 3816 case 1: 3817 return "#"; 3818 default: 3819 gcc_unreachable (); 3820 } 3821} 3822 [(set_attr "type" "fmov,multi") 3823 (set_attr "unit" "*,i387") 3824 (set_attr "mode" "SF")]) 3825 3826(define_insn "*truncdfsf2_i387_1" 3827 [(set (match_operand:SF 0 "memory_operand" "=m") 3828 (float_truncate:SF 3829 (match_operand:DF 1 "register_operand" "f")))] 3830 "TARGET_80387 3831 && !(TARGET_SSE2 && TARGET_SSE_MATH) 3832 && !TARGET_MIX_SSE_I387" 3833{ 3834 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3835 return "fstp%z0\t%y0"; 3836 else 3837 return "fst%z0\t%y0"; 3838} 3839 [(set_attr "type" "fmov") 3840 (set_attr "mode" "SF")]) 3841 3842(define_split 3843 [(set (match_operand:SF 0 "register_operand" "") 3844 (float_truncate:SF 3845 (match_operand:DF 1 "fp_register_operand" ""))) 3846 (clobber (match_operand 2 "" ""))] 3847 "reload_completed" 3848 [(set (match_dup 2) (match_dup 1)) 3849 (set (match_dup 0) (match_dup 2))] 3850{ 3851 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1])); 3852}) 3853 3854;; Conversion from XFmode to SFmode. 3855 3856(define_expand "truncxfsf2" 3857 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") 3858 (float_truncate:SF 3859 (match_operand:XF 1 "register_operand" ""))) 3860 (clobber (match_dup 2))])] 3861 "TARGET_80387" 3862{ 3863 if (flag_unsafe_math_optimizations) 3864 { 3865 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode); 3866 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1])); 3867 if (reg != operands[0]) 3868 emit_move_insn (operands[0], reg); 3869 DONE; 3870 } 3871 else 3872 operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL); 3873}) 3874 3875(define_insn "*truncxfsf2_mixed" 3876 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x") 3877 (float_truncate:SF 3878 (match_operand:XF 1 "register_operand" "f,f,f,f"))) 3879 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))] 3880 "TARGET_MIX_SSE_I387" 3881{ 3882 gcc_assert (!which_alternative); 3883 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3884 return "fstp%z0\t%y0"; 3885 else 3886 return "fst%z0\t%y0"; 3887} 3888 [(set_attr "type" "fmov,multi,multi,multi") 3889 (set_attr "unit" "*,i387,i387,i387") 3890 (set_attr "mode" "SF")]) 3891 3892(define_insn "truncxfsf2_i387_noop" 3893 [(set (match_operand:SF 0 "register_operand" "=f") 3894 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))] 3895 "TARGET_80387 && flag_unsafe_math_optimizations" 3896{ 3897 return output_387_reg_move (insn, operands); 3898} 3899 [(set_attr "type" "fmov") 3900 (set_attr "mode" "SF")]) 3901 3902(define_insn "*truncxfsf2_i387" 3903 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r") 3904 (float_truncate:SF 3905 (match_operand:XF 1 "register_operand" "f,f,f"))) 3906 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))] 3907 "TARGET_80387" 3908{ 3909 gcc_assert (!which_alternative); 3910 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3911 return "fstp%z0\t%y0"; 3912 else 3913 return "fst%z0\t%y0"; 3914} 3915 [(set_attr "type" "fmov,multi,multi") 3916 (set_attr "unit" "*,i387,i387") 3917 (set_attr "mode" "SF")]) 3918 3919(define_insn "*truncxfsf2_i387_1" 3920 [(set (match_operand:SF 0 "memory_operand" "=m") 3921 (float_truncate:SF 3922 (match_operand:XF 1 "register_operand" "f")))] 3923 "TARGET_80387" 3924{ 3925 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3926 return "fstp%z0\t%y0"; 3927 else 3928 return "fst%z0\t%y0"; 3929} 3930 [(set_attr "type" "fmov") 3931 (set_attr "mode" "SF")]) 3932 3933(define_split 3934 [(set (match_operand:SF 0 "register_operand" "") 3935 (float_truncate:SF 3936 (match_operand:XF 1 "register_operand" ""))) 3937 (clobber (match_operand:SF 2 "memory_operand" ""))] 3938 "TARGET_80387 && reload_completed" 3939 [(set (match_dup 2) (float_truncate:SF (match_dup 1))) 3940 (set (match_dup 0) (match_dup 2))] 3941 "") 3942 3943(define_split 3944 [(set (match_operand:SF 0 "memory_operand" "") 3945 (float_truncate:SF 3946 (match_operand:XF 1 "register_operand" ""))) 3947 (clobber (match_operand:SF 2 "memory_operand" ""))] 3948 "TARGET_80387" 3949 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))] 3950 "") 3951 3952;; Conversion from XFmode to DFmode. 3953 3954(define_expand "truncxfdf2" 3955 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "") 3956 (float_truncate:DF 3957 (match_operand:XF 1 "register_operand" ""))) 3958 (clobber (match_dup 2))])] 3959 "TARGET_80387" 3960{ 3961 if (flag_unsafe_math_optimizations) 3962 { 3963 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode); 3964 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1])); 3965 if (reg != operands[0]) 3966 emit_move_insn (operands[0], reg); 3967 DONE; 3968 } 3969 else 3970 operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL); 3971}) 3972 3973(define_insn "*truncxfdf2_mixed" 3974 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y") 3975 (float_truncate:DF 3976 (match_operand:XF 1 "register_operand" "f,f,f,f"))) 3977 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))] 3978 "TARGET_SSE2 && TARGET_MIX_SSE_I387" 3979{ 3980 gcc_assert (!which_alternative); 3981 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3982 return "fstp%z0\t%y0"; 3983 else 3984 return "fst%z0\t%y0"; 3985} 3986 [(set_attr "type" "fmov,multi,multi,multi") 3987 (set_attr "unit" "*,i387,i387,i387") 3988 (set_attr "mode" "DF")]) 3989 3990(define_insn "truncxfdf2_i387_noop" 3991 [(set (match_operand:DF 0 "register_operand" "=f") 3992 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))] 3993 "TARGET_80387 && flag_unsafe_math_optimizations" 3994{ 3995 return output_387_reg_move (insn, operands); 3996} 3997 [(set_attr "type" "fmov") 3998 (set_attr "mode" "DF")]) 3999 4000(define_insn "*truncxfdf2_i387" 4001 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r") 4002 (float_truncate:DF 4003 (match_operand:XF 1 "register_operand" "f,f,f"))) 4004 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))] 4005 "TARGET_80387" 4006{ 4007 gcc_assert (!which_alternative); 4008 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 4009 return "fstp%z0\t%y0"; 4010 else 4011 return "fst%z0\t%y0"; 4012} 4013 [(set_attr "type" "fmov,multi,multi") 4014 (set_attr "unit" "*,i387,i387") 4015 (set_attr "mode" "DF")]) 4016 4017(define_insn "*truncxfdf2_i387_1" 4018 [(set (match_operand:DF 0 "memory_operand" "=m") 4019 (float_truncate:DF 4020 (match_operand:XF 1 "register_operand" "f")))] 4021 "TARGET_80387" 4022{ 4023 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 4024 return "fstp%z0\t%y0"; 4025 else 4026 return "fst%z0\t%y0"; 4027} 4028 [(set_attr "type" "fmov") 4029 (set_attr "mode" "DF")]) 4030 4031(define_split 4032 [(set (match_operand:DF 0 "register_operand" "") 4033 (float_truncate:DF 4034 (match_operand:XF 1 "register_operand" ""))) 4035 (clobber (match_operand:DF 2 "memory_operand" ""))] 4036 "TARGET_80387 && reload_completed" 4037 [(set (match_dup 2) (float_truncate:DF (match_dup 1))) 4038 (set (match_dup 0) (match_dup 2))] 4039 "") 4040 4041(define_split 4042 [(set (match_operand:DF 0 "memory_operand" "") 4043 (float_truncate:DF 4044 (match_operand:XF 1 "register_operand" ""))) 4045 (clobber (match_operand:DF 2 "memory_operand" ""))] 4046 "TARGET_80387" 4047 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))] 4048 "") 4049 4050;; Signed conversion to DImode. 4051 4052(define_expand "fix_truncxfdi2" 4053 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 4054 (fix:DI (match_operand:XF 1 "register_operand" ""))) 4055 (clobber (reg:CC FLAGS_REG))])] 4056 "TARGET_80387" 4057{ 4058 if (TARGET_FISTTP) 4059 { 4060 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4061 DONE; 4062 } 4063}) 4064 4065(define_expand "fix_trunc<mode>di2" 4066 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 4067 (fix:DI (match_operand:SSEMODEF 1 "register_operand" ""))) 4068 (clobber (reg:CC FLAGS_REG))])] 4069 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))" 4070{ 4071 if (TARGET_FISTTP 4072 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4073 { 4074 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4075 DONE; 4076 } 4077 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)) 4078 { 4079 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode); 4080 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1])); 4081 if (out != operands[0]) 4082 emit_move_insn (operands[0], out); 4083 DONE; 4084 } 4085}) 4086 4087;; Signed conversion to SImode. 4088 4089(define_expand "fix_truncxfsi2" 4090 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4091 (fix:SI (match_operand:XF 1 "register_operand" ""))) 4092 (clobber (reg:CC FLAGS_REG))])] 4093 "TARGET_80387" 4094{ 4095 if (TARGET_FISTTP) 4096 { 4097 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4098 DONE; 4099 } 4100}) 4101 4102(define_expand "fix_trunc<mode>si2" 4103 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4104 (fix:SI (match_operand:SSEMODEF 1 "register_operand" ""))) 4105 (clobber (reg:CC FLAGS_REG))])] 4106 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)" 4107{ 4108 if (TARGET_FISTTP 4109 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4110 { 4111 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4112 DONE; 4113 } 4114 if (SSE_FLOAT_MODE_P (<MODE>mode)) 4115 { 4116 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode); 4117 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1])); 4118 if (out != operands[0]) 4119 emit_move_insn (operands[0], out); 4120 DONE; 4121 } 4122}) 4123 4124;; Signed conversion to HImode. 4125 4126(define_expand "fix_trunc<mode>hi2" 4127 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 4128 (fix:HI (match_operand:X87MODEF 1 "register_operand" ""))) 4129 (clobber (reg:CC FLAGS_REG))])] 4130 "TARGET_80387 4131 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))" 4132{ 4133 if (TARGET_FISTTP) 4134 { 4135 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1])); 4136 DONE; 4137 } 4138}) 4139 4140;; When SSE is available, it is always faster to use it! 4141(define_insn "fix_truncsfdi_sse" 4142 [(set (match_operand:DI 0 "register_operand" "=r,r") 4143 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))] 4144 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4145 "cvttss2si{q}\t{%1, %0|%0, %1}" 4146 [(set_attr "type" "sseicvt") 4147 (set_attr "mode" "SF") 4148 (set_attr "athlon_decode" "double,vector")]) 4149 4150(define_insn "fix_truncdfdi_sse" 4151 [(set (match_operand:DI 0 "register_operand" "=r,r") 4152 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))] 4153 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4154 "cvttsd2si{q}\t{%1, %0|%0, %1}" 4155 [(set_attr "type" "sseicvt") 4156 (set_attr "mode" "DF") 4157 (set_attr "athlon_decode" "double,vector")]) 4158 4159(define_insn "fix_truncsfsi_sse" 4160 [(set (match_operand:SI 0 "register_operand" "=r,r") 4161 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))] 4162 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4163 "cvttss2si\t{%1, %0|%0, %1}" 4164 [(set_attr "type" "sseicvt") 4165 (set_attr "mode" "DF") 4166 (set_attr "athlon_decode" "double,vector")]) 4167 4168(define_insn "fix_truncdfsi_sse" 4169 [(set (match_operand:SI 0 "register_operand" "=r,r") 4170 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))] 4171 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4172 "cvttsd2si\t{%1, %0|%0, %1}" 4173 [(set_attr "type" "sseicvt") 4174 (set_attr "mode" "DF") 4175 (set_attr "athlon_decode" "double,vector")]) 4176 4177;; Avoid vector decoded forms of the instruction. 4178(define_peephole2 4179 [(match_scratch:DF 2 "Y") 4180 (set (match_operand:SSEMODEI24 0 "register_operand" "") 4181 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))] 4182 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size" 4183 [(set (match_dup 2) (match_dup 1)) 4184 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))] 4185 "") 4186 4187(define_peephole2 4188 [(match_scratch:SF 2 "x") 4189 (set (match_operand:SSEMODEI24 0 "register_operand" "") 4190 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))] 4191 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size" 4192 [(set (match_dup 2) (match_dup 1)) 4193 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))] 4194 "") 4195 4196(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1" 4197 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 4198 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))] 4199 "TARGET_FISTTP 4200 && FLOAT_MODE_P (GET_MODE (operands[1])) 4201 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4202 && (TARGET_64BIT || <MODE>mode != DImode)) 4203 && TARGET_SSE_MATH) 4204 && !(reload_completed || reload_in_progress)" 4205 "#" 4206 "&& 1" 4207 [(const_int 0)] 4208{ 4209 if (memory_operand (operands[0], VOIDmode)) 4210 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1])); 4211 else 4212 { 4213 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4214 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0], 4215 operands[1], 4216 operands[2])); 4217 } 4218 DONE; 4219} 4220 [(set_attr "type" "fisttp") 4221 (set_attr "mode" "<MODE>")]) 4222 4223(define_insn "fix_trunc<mode>_i387_fisttp" 4224 [(set (match_operand:X87MODEI 0 "memory_operand" "=m") 4225 (fix:X87MODEI (match_operand 1 "register_operand" "f"))) 4226 (clobber (match_scratch:XF 2 "=&1f"))] 4227 "TARGET_FISTTP 4228 && FLOAT_MODE_P (GET_MODE (operands[1])) 4229 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4230 && (TARGET_64BIT || <MODE>mode != DImode)) 4231 && TARGET_SSE_MATH)" 4232 "* return output_fix_trunc (insn, operands, 1);" 4233 [(set_attr "type" "fisttp") 4234 (set_attr "mode" "<MODE>")]) 4235 4236(define_insn "fix_trunc<mode>_i387_fisttp_with_temp" 4237 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 4238 (fix:X87MODEI (match_operand 1 "register_operand" "f,f"))) 4239 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m")) 4240 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 4241 "TARGET_FISTTP 4242 && FLOAT_MODE_P (GET_MODE (operands[1])) 4243 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4244 && (TARGET_64BIT || <MODE>mode != DImode)) 4245 && TARGET_SSE_MATH)" 4246 "#" 4247 [(set_attr "type" "fisttp") 4248 (set_attr "mode" "<MODE>")]) 4249 4250(define_split 4251 [(set (match_operand:X87MODEI 0 "register_operand" "") 4252 (fix:X87MODEI (match_operand 1 "register_operand" ""))) 4253 (clobber (match_operand:X87MODEI 2 "memory_operand" "")) 4254 (clobber (match_scratch 3 ""))] 4255 "reload_completed" 4256 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1))) 4257 (clobber (match_dup 3))]) 4258 (set (match_dup 0) (match_dup 2))] 4259 "") 4260 4261(define_split 4262 [(set (match_operand:X87MODEI 0 "memory_operand" "") 4263 (fix:X87MODEI (match_operand 1 "register_operand" ""))) 4264 (clobber (match_operand:X87MODEI 2 "memory_operand" "")) 4265 (clobber (match_scratch 3 ""))] 4266 "reload_completed" 4267 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1))) 4268 (clobber (match_dup 3))])] 4269 "") 4270 4271;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description 4272;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control 4273;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG 4274;; clobbering insns can be used. Look at emit_i387_cw_initialization () 4275;; function in i386.c. 4276(define_insn_and_split "*fix_trunc<mode>_i387_1" 4277 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 4278 (fix:X87MODEI (match_operand 1 "register_operand" "f,f"))) 4279 (clobber (reg:CC FLAGS_REG))] 4280 "TARGET_80387 && !TARGET_FISTTP 4281 && FLOAT_MODE_P (GET_MODE (operands[1])) 4282 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4283 && (TARGET_64BIT || <MODE>mode != DImode)) 4284 && !(reload_completed || reload_in_progress)" 4285 "#" 4286 "&& 1" 4287 [(const_int 0)] 4288{ 4289 ix86_optimize_mode_switching[I387_TRUNC] = 1; 4290 4291 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 4292 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 4293 if (memory_operand (operands[0], VOIDmode)) 4294 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1], 4295 operands[2], operands[3])); 4296 else 4297 { 4298 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4299 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1], 4300 operands[2], operands[3], 4301 operands[4])); 4302 } 4303 DONE; 4304} 4305 [(set_attr "type" "fistp") 4306 (set_attr "i387_cw" "trunc") 4307 (set_attr "mode" "<MODE>")]) 4308 4309(define_insn "fix_truncdi_i387" 4310 [(set (match_operand:DI 0 "memory_operand" "=m") 4311 (fix:DI (match_operand 1 "register_operand" "f"))) 4312 (use (match_operand:HI 2 "memory_operand" "m")) 4313 (use (match_operand:HI 3 "memory_operand" "m")) 4314 (clobber (match_scratch:XF 4 "=&1f"))] 4315 "TARGET_80387 && !TARGET_FISTTP 4316 && FLOAT_MODE_P (GET_MODE (operands[1])) 4317 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4318 "* return output_fix_trunc (insn, operands, 0);" 4319 [(set_attr "type" "fistp") 4320 (set_attr "i387_cw" "trunc") 4321 (set_attr "mode" "DI")]) 4322 4323(define_insn "fix_truncdi_i387_with_temp" 4324 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 4325 (fix:DI (match_operand 1 "register_operand" "f,f"))) 4326 (use (match_operand:HI 2 "memory_operand" "m,m")) 4327 (use (match_operand:HI 3 "memory_operand" "m,m")) 4328 (clobber (match_operand:DI 4 "memory_operand" "=m,m")) 4329 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 4330 "TARGET_80387 && !TARGET_FISTTP 4331 && FLOAT_MODE_P (GET_MODE (operands[1])) 4332 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4333 "#" 4334 [(set_attr "type" "fistp") 4335 (set_attr "i387_cw" "trunc") 4336 (set_attr "mode" "DI")]) 4337 4338(define_split 4339 [(set (match_operand:DI 0 "register_operand" "") 4340 (fix:DI (match_operand 1 "register_operand" ""))) 4341 (use (match_operand:HI 2 "memory_operand" "")) 4342 (use (match_operand:HI 3 "memory_operand" "")) 4343 (clobber (match_operand:DI 4 "memory_operand" "")) 4344 (clobber (match_scratch 5 ""))] 4345 "reload_completed" 4346 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1))) 4347 (use (match_dup 2)) 4348 (use (match_dup 3)) 4349 (clobber (match_dup 5))]) 4350 (set (match_dup 0) (match_dup 4))] 4351 "") 4352 4353(define_split 4354 [(set (match_operand:DI 0 "memory_operand" "") 4355 (fix:DI (match_operand 1 "register_operand" ""))) 4356 (use (match_operand:HI 2 "memory_operand" "")) 4357 (use (match_operand:HI 3 "memory_operand" "")) 4358 (clobber (match_operand:DI 4 "memory_operand" "")) 4359 (clobber (match_scratch 5 ""))] 4360 "reload_completed" 4361 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1))) 4362 (use (match_dup 2)) 4363 (use (match_dup 3)) 4364 (clobber (match_dup 5))])] 4365 "") 4366 4367(define_insn "fix_trunc<mode>_i387" 4368 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 4369 (fix:X87MODEI12 (match_operand 1 "register_operand" "f"))) 4370 (use (match_operand:HI 2 "memory_operand" "m")) 4371 (use (match_operand:HI 3 "memory_operand" "m"))] 4372 "TARGET_80387 && !TARGET_FISTTP 4373 && FLOAT_MODE_P (GET_MODE (operands[1])) 4374 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4375 "* return output_fix_trunc (insn, operands, 0);" 4376 [(set_attr "type" "fistp") 4377 (set_attr "i387_cw" "trunc") 4378 (set_attr "mode" "<MODE>")]) 4379 4380(define_insn "fix_trunc<mode>_i387_with_temp" 4381 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") 4382 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f"))) 4383 (use (match_operand:HI 2 "memory_operand" "m,m")) 4384 (use (match_operand:HI 3 "memory_operand" "m,m")) 4385 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))] 4386 "TARGET_80387 && !TARGET_FISTTP 4387 && FLOAT_MODE_P (GET_MODE (operands[1])) 4388 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4389 "#" 4390 [(set_attr "type" "fistp") 4391 (set_attr "i387_cw" "trunc") 4392 (set_attr "mode" "<MODE>")]) 4393 4394(define_split 4395 [(set (match_operand:X87MODEI12 0 "register_operand" "") 4396 (fix:X87MODEI12 (match_operand 1 "register_operand" ""))) 4397 (use (match_operand:HI 2 "memory_operand" "")) 4398 (use (match_operand:HI 3 "memory_operand" "")) 4399 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 4400 "reload_completed" 4401 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1))) 4402 (use (match_dup 2)) 4403 (use (match_dup 3))]) 4404 (set (match_dup 0) (match_dup 4))] 4405 "") 4406 4407(define_split 4408 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 4409 (fix:X87MODEI12 (match_operand 1 "register_operand" ""))) 4410 (use (match_operand:HI 2 "memory_operand" "")) 4411 (use (match_operand:HI 3 "memory_operand" "")) 4412 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 4413 "reload_completed" 4414 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1))) 4415 (use (match_dup 2)) 4416 (use (match_dup 3))])] 4417 "") 4418 4419(define_insn "x86_fnstcw_1" 4420 [(set (match_operand:HI 0 "memory_operand" "=m") 4421 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))] 4422 "TARGET_80387" 4423 "fnstcw\t%0" 4424 [(set_attr "length" "2") 4425 (set_attr "mode" "HI") 4426 (set_attr "unit" "i387")]) 4427 4428(define_insn "x86_fldcw_1" 4429 [(set (reg:HI FPSR_REG) 4430 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))] 4431 "TARGET_80387" 4432 "fldcw\t%0" 4433 [(set_attr "length" "2") 4434 (set_attr "mode" "HI") 4435 (set_attr "unit" "i387") 4436 (set_attr "athlon_decode" "vector")]) 4437 4438;; Conversion between fixed point and floating point. 4439 4440;; Even though we only accept memory inputs, the backend _really_ 4441;; wants to be able to do this between registers. 4442 4443(define_expand "floathisf2" 4444 [(set (match_operand:SF 0 "register_operand" "") 4445 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))] 4446 "TARGET_80387 || TARGET_SSE_MATH" 4447{ 4448 if (TARGET_SSE_MATH) 4449 { 4450 emit_insn (gen_floatsisf2 (operands[0], 4451 convert_to_mode (SImode, operands[1], 0))); 4452 DONE; 4453 } 4454}) 4455 4456(define_insn "*floathisf2_i387" 4457 [(set (match_operand:SF 0 "register_operand" "=f,f") 4458 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))] 4459 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 4460 "@ 4461 fild%z1\t%1 4462 #" 4463 [(set_attr "type" "fmov,multi") 4464 (set_attr "mode" "SF") 4465 (set_attr "unit" "*,i387") 4466 (set_attr "fp_int_src" "true")]) 4467 4468(define_expand "floatsisf2" 4469 [(set (match_operand:SF 0 "register_operand" "") 4470 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))] 4471 "TARGET_80387 || TARGET_SSE_MATH" 4472 "") 4473 4474(define_insn "*floatsisf2_mixed" 4475 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x") 4476 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))] 4477 "TARGET_MIX_SSE_I387" 4478 "@ 4479 fild%z1\t%1 4480 # 4481 cvtsi2ss\t{%1, %0|%0, %1} 4482 cvtsi2ss\t{%1, %0|%0, %1}" 4483 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4484 (set_attr "mode" "SF") 4485 (set_attr "unit" "*,i387,*,*") 4486 (set_attr "athlon_decode" "*,*,vector,double") 4487 (set_attr "fp_int_src" "true")]) 4488 4489(define_insn "*floatsisf2_sse" 4490 [(set (match_operand:SF 0 "register_operand" "=x,x") 4491 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))] 4492 "TARGET_SSE_MATH" 4493 "cvtsi2ss\t{%1, %0|%0, %1}" 4494 [(set_attr "type" "sseicvt") 4495 (set_attr "mode" "SF") 4496 (set_attr "athlon_decode" "vector,double") 4497 (set_attr "fp_int_src" "true")]) 4498 4499(define_insn "*floatsisf2_i387" 4500 [(set (match_operand:SF 0 "register_operand" "=f,f") 4501 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))] 4502 "TARGET_80387" 4503 "@ 4504 fild%z1\t%1 4505 #" 4506 [(set_attr "type" "fmov,multi") 4507 (set_attr "mode" "SF") 4508 (set_attr "unit" "*,i387") 4509 (set_attr "fp_int_src" "true")]) 4510 4511(define_expand "floatdisf2" 4512 [(set (match_operand:SF 0 "register_operand" "") 4513 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))] 4514 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)" 4515 "") 4516 4517(define_insn "*floatdisf2_mixed" 4518 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x") 4519 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))] 4520 "TARGET_64BIT && TARGET_MIX_SSE_I387" 4521 "@ 4522 fild%z1\t%1 4523 # 4524 cvtsi2ss{q}\t{%1, %0|%0, %1} 4525 cvtsi2ss{q}\t{%1, %0|%0, %1}" 4526 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4527 (set_attr "mode" "SF") 4528 (set_attr "unit" "*,i387,*,*") 4529 (set_attr "athlon_decode" "*,*,vector,double") 4530 (set_attr "fp_int_src" "true")]) 4531 4532(define_insn "*floatdisf2_sse" 4533 [(set (match_operand:SF 0 "register_operand" "=x,x") 4534 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))] 4535 "TARGET_64BIT && TARGET_SSE_MATH" 4536 "cvtsi2ss{q}\t{%1, %0|%0, %1}" 4537 [(set_attr "type" "sseicvt") 4538 (set_attr "mode" "SF") 4539 (set_attr "athlon_decode" "vector,double") 4540 (set_attr "fp_int_src" "true")]) 4541 4542(define_insn "*floatdisf2_i387" 4543 [(set (match_operand:SF 0 "register_operand" "=f,f") 4544 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))] 4545 "TARGET_80387" 4546 "@ 4547 fild%z1\t%1 4548 #" 4549 [(set_attr "type" "fmov,multi") 4550 (set_attr "mode" "SF") 4551 (set_attr "unit" "*,i387") 4552 (set_attr "fp_int_src" "true")]) 4553 4554(define_expand "floathidf2" 4555 [(set (match_operand:DF 0 "register_operand" "") 4556 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))] 4557 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4558{ 4559 if (TARGET_SSE2 && TARGET_SSE_MATH) 4560 { 4561 emit_insn (gen_floatsidf2 (operands[0], 4562 convert_to_mode (SImode, operands[1], 0))); 4563 DONE; 4564 } 4565}) 4566 4567(define_insn "*floathidf2_i387" 4568 [(set (match_operand:DF 0 "register_operand" "=f,f") 4569 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))] 4570 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)" 4571 "@ 4572 fild%z1\t%1 4573 #" 4574 [(set_attr "type" "fmov,multi") 4575 (set_attr "mode" "DF") 4576 (set_attr "unit" "*,i387") 4577 (set_attr "fp_int_src" "true")]) 4578 4579(define_expand "floatsidf2" 4580 [(set (match_operand:DF 0 "register_operand" "") 4581 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))] 4582 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4583 "") 4584 4585(define_insn "*floatsidf2_mixed" 4586 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y") 4587 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))] 4588 "TARGET_SSE2 && TARGET_MIX_SSE_I387" 4589 "@ 4590 fild%z1\t%1 4591 # 4592 cvtsi2sd\t{%1, %0|%0, %1} 4593 cvtsi2sd\t{%1, %0|%0, %1}" 4594 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4595 (set_attr "mode" "DF") 4596 (set_attr "unit" "*,i387,*,*") 4597 (set_attr "athlon_decode" "*,*,double,direct") 4598 (set_attr "fp_int_src" "true")]) 4599 4600(define_insn "*floatsidf2_sse" 4601 [(set (match_operand:DF 0 "register_operand" "=Y,Y") 4602 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))] 4603 "TARGET_SSE2 && TARGET_SSE_MATH" 4604 "cvtsi2sd\t{%1, %0|%0, %1}" 4605 [(set_attr "type" "sseicvt") 4606 (set_attr "mode" "DF") 4607 (set_attr "athlon_decode" "double,direct") 4608 (set_attr "fp_int_src" "true")]) 4609 4610(define_insn "*floatsidf2_i387" 4611 [(set (match_operand:DF 0 "register_operand" "=f,f") 4612 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))] 4613 "TARGET_80387" 4614 "@ 4615 fild%z1\t%1 4616 #" 4617 [(set_attr "type" "fmov,multi") 4618 (set_attr "mode" "DF") 4619 (set_attr "unit" "*,i387") 4620 (set_attr "fp_int_src" "true")]) 4621 4622(define_expand "floatdidf2" 4623 [(set (match_operand:DF 0 "register_operand" "") 4624 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))] 4625 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)" 4626 "") 4627 4628(define_insn "*floatdidf2_mixed" 4629 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y") 4630 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))] 4631 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387" 4632 "@ 4633 fild%z1\t%1 4634 # 4635 cvtsi2sd{q}\t{%1, %0|%0, %1} 4636 cvtsi2sd{q}\t{%1, %0|%0, %1}" 4637 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4638 (set_attr "mode" "DF") 4639 (set_attr "unit" "*,i387,*,*") 4640 (set_attr "athlon_decode" "*,*,double,direct") 4641 (set_attr "fp_int_src" "true")]) 4642 4643(define_insn "*floatdidf2_sse" 4644 [(set (match_operand:DF 0 "register_operand" "=Y,Y") 4645 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))] 4646 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH" 4647 "cvtsi2sd{q}\t{%1, %0|%0, %1}" 4648 [(set_attr "type" "sseicvt") 4649 (set_attr "mode" "DF") 4650 (set_attr "athlon_decode" "double,direct") 4651 (set_attr "fp_int_src" "true")]) 4652 4653(define_insn "*floatdidf2_i387" 4654 [(set (match_operand:DF 0 "register_operand" "=f,f") 4655 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))] 4656 "TARGET_80387" 4657 "@ 4658 fild%z1\t%1 4659 #" 4660 [(set_attr "type" "fmov,multi") 4661 (set_attr "mode" "DF") 4662 (set_attr "unit" "*,i387") 4663 (set_attr "fp_int_src" "true")]) 4664 4665(define_insn "floathixf2" 4666 [(set (match_operand:XF 0 "register_operand" "=f,f") 4667 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))] 4668 "TARGET_80387" 4669 "@ 4670 fild%z1\t%1 4671 #" 4672 [(set_attr "type" "fmov,multi") 4673 (set_attr "mode" "XF") 4674 (set_attr "unit" "*,i387") 4675 (set_attr "fp_int_src" "true")]) 4676 4677(define_insn "floatsixf2" 4678 [(set (match_operand:XF 0 "register_operand" "=f,f") 4679 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))] 4680 "TARGET_80387" 4681 "@ 4682 fild%z1\t%1 4683 #" 4684 [(set_attr "type" "fmov,multi") 4685 (set_attr "mode" "XF") 4686 (set_attr "unit" "*,i387") 4687 (set_attr "fp_int_src" "true")]) 4688 4689(define_insn "floatdixf2" 4690 [(set (match_operand:XF 0 "register_operand" "=f,f") 4691 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))] 4692 "TARGET_80387" 4693 "@ 4694 fild%z1\t%1 4695 #" 4696 [(set_attr "type" "fmov,multi") 4697 (set_attr "mode" "XF") 4698 (set_attr "unit" "*,i387") 4699 (set_attr "fp_int_src" "true")]) 4700 4701;; %%% Kill these when reload knows how to do it. 4702(define_split 4703 [(set (match_operand 0 "fp_register_operand" "") 4704 (float (match_operand 1 "register_operand" "")))] 4705 "reload_completed 4706 && TARGET_80387 4707 && FLOAT_MODE_P (GET_MODE (operands[0]))" 4708 [(const_int 0)] 4709{ 4710 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]); 4711 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]); 4712 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2])); 4713 ix86_free_from_memory (GET_MODE (operands[1])); 4714 DONE; 4715}) 4716 4717(define_expand "floatunssisf2" 4718 [(use (match_operand:SF 0 "register_operand" "")) 4719 (use (match_operand:SI 1 "register_operand" ""))] 4720 "!TARGET_64BIT && TARGET_SSE_MATH" 4721 "x86_emit_floatuns (operands); DONE;") 4722 4723(define_expand "floatunsdisf2" 4724 [(use (match_operand:SF 0 "register_operand" "")) 4725 (use (match_operand:DI 1 "register_operand" ""))] 4726 "TARGET_64BIT && TARGET_SSE_MATH" 4727 "x86_emit_floatuns (operands); DONE;") 4728 4729(define_expand "floatunsdidf2" 4730 [(use (match_operand:DF 0 "register_operand" "")) 4731 (use (match_operand:DI 1 "register_operand" ""))] 4732 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH" 4733 "x86_emit_floatuns (operands); DONE;") 4734 4735;; SSE extract/set expanders 4736 4737 4738;; Add instructions 4739 4740;; %%% splits for addditi3 4741 4742(define_expand "addti3" 4743 [(set (match_operand:TI 0 "nonimmediate_operand" "") 4744 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "") 4745 (match_operand:TI 2 "x86_64_general_operand" ""))) 4746 (clobber (reg:CC FLAGS_REG))] 4747 "TARGET_64BIT" 4748 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;") 4749 4750(define_insn "*addti3_1" 4751 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o") 4752 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0") 4753 (match_operand:TI 2 "x86_64_general_operand" "roe,re"))) 4754 (clobber (reg:CC FLAGS_REG))] 4755 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)" 4756 "#") 4757 4758(define_split 4759 [(set (match_operand:TI 0 "nonimmediate_operand" "") 4760 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "") 4761 (match_operand:TI 2 "x86_64_general_operand" ""))) 4762 (clobber (reg:CC FLAGS_REG))] 4763 "TARGET_64BIT && reload_completed" 4764 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)] 4765 UNSPEC_ADD_CARRY)) 4766 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]) 4767 (parallel [(set (match_dup 3) 4768 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) 4769 (match_dup 4)) 4770 (match_dup 5))) 4771 (clobber (reg:CC FLAGS_REG))])] 4772 "split_ti (operands+0, 1, operands+0, operands+3); 4773 split_ti (operands+1, 1, operands+1, operands+4); 4774 split_ti (operands+2, 1, operands+2, operands+5);") 4775 4776;; %%% splits for addsidi3 4777; [(set (match_operand:DI 0 "nonimmediate_operand" "") 4778; (plus:DI (match_operand:DI 1 "general_operand" "") 4779; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))] 4780 4781(define_expand "adddi3" 4782 [(set (match_operand:DI 0 "nonimmediate_operand" "") 4783 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") 4784 (match_operand:DI 2 "x86_64_general_operand" ""))) 4785 (clobber (reg:CC FLAGS_REG))] 4786 "" 4787 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;") 4788 4789(define_insn "*adddi3_1" 4790 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") 4791 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 4792 (match_operand:DI 2 "general_operand" "roiF,riF"))) 4793 (clobber (reg:CC FLAGS_REG))] 4794 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 4795 "#") 4796 4797(define_split 4798 [(set (match_operand:DI 0 "nonimmediate_operand" "") 4799 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") 4800 (match_operand:DI 2 "general_operand" ""))) 4801 (clobber (reg:CC FLAGS_REG))] 4802 "!TARGET_64BIT && reload_completed" 4803 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)] 4804 UNSPEC_ADD_CARRY)) 4805 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) 4806 (parallel [(set (match_dup 3) 4807 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) 4808 (match_dup 4)) 4809 (match_dup 5))) 4810 (clobber (reg:CC FLAGS_REG))])] 4811 "split_di (operands+0, 1, operands+0, operands+3); 4812 split_di (operands+1, 1, operands+1, operands+4); 4813 split_di (operands+2, 1, operands+2, operands+5);") 4814 4815(define_insn "adddi3_carry_rex64" 4816 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 4817 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "") 4818 (match_operand:DI 1 "nonimmediate_operand" "%0,0")) 4819 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 4820 (clobber (reg:CC FLAGS_REG))] 4821 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 4822 "adc{q}\t{%2, %0|%0, %2}" 4823 [(set_attr "type" "alu") 4824 (set_attr "pent_pair" "pu") 4825 (set_attr "mode" "DI")]) 4826 4827(define_insn "*adddi3_cc_rex64" 4828 [(set (reg:CC FLAGS_REG) 4829 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0") 4830 (match_operand:DI 2 "x86_64_general_operand" "re,rm")] 4831 UNSPEC_ADD_CARRY)) 4832 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 4833 (plus:DI (match_dup 1) (match_dup 2)))] 4834 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 4835 "add{q}\t{%2, %0|%0, %2}" 4836 [(set_attr "type" "alu") 4837 (set_attr "mode" "DI")]) 4838 4839(define_insn "addqi3_carry" 4840 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 4841 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "") 4842 (match_operand:QI 1 "nonimmediate_operand" "%0,0")) 4843 (match_operand:QI 2 "general_operand" "qi,qm"))) 4844 (clobber (reg:CC FLAGS_REG))] 4845 "ix86_binary_operator_ok (PLUS, QImode, operands)" 4846 "adc{b}\t{%2, %0|%0, %2}" 4847 [(set_attr "type" "alu") 4848 (set_attr "pent_pair" "pu") 4849 (set_attr "mode" "QI")]) 4850 4851(define_insn "addhi3_carry" 4852 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 4853 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "") 4854 (match_operand:HI 1 "nonimmediate_operand" "%0,0")) 4855 (match_operand:HI 2 "general_operand" "ri,rm"))) 4856 (clobber (reg:CC FLAGS_REG))] 4857 "ix86_binary_operator_ok (PLUS, HImode, operands)" 4858 "adc{w}\t{%2, %0|%0, %2}" 4859 [(set_attr "type" "alu") 4860 (set_attr "pent_pair" "pu") 4861 (set_attr "mode" "HI")]) 4862 4863(define_insn "addsi3_carry" 4864 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 4865 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 4866 (match_operand:SI 1 "nonimmediate_operand" "%0,0")) 4867 (match_operand:SI 2 "general_operand" "ri,rm"))) 4868 (clobber (reg:CC FLAGS_REG))] 4869 "ix86_binary_operator_ok (PLUS, SImode, operands)" 4870 "adc{l}\t{%2, %0|%0, %2}" 4871 [(set_attr "type" "alu") 4872 (set_attr "pent_pair" "pu") 4873 (set_attr "mode" "SI")]) 4874 4875(define_insn "*addsi3_carry_zext" 4876 [(set (match_operand:DI 0 "register_operand" "=r") 4877 (zero_extend:DI 4878 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 4879 (match_operand:SI 1 "nonimmediate_operand" "%0")) 4880 (match_operand:SI 2 "general_operand" "rim")))) 4881 (clobber (reg:CC FLAGS_REG))] 4882 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 4883 "adc{l}\t{%2, %k0|%k0, %2}" 4884 [(set_attr "type" "alu") 4885 (set_attr "pent_pair" "pu") 4886 (set_attr "mode" "SI")]) 4887 4888(define_insn "*addsi3_cc" 4889 [(set (reg:CC FLAGS_REG) 4890 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0") 4891 (match_operand:SI 2 "general_operand" "ri,rm")] 4892 UNSPEC_ADD_CARRY)) 4893 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 4894 (plus:SI (match_dup 1) (match_dup 2)))] 4895 "ix86_binary_operator_ok (PLUS, SImode, operands)" 4896 "add{l}\t{%2, %0|%0, %2}" 4897 [(set_attr "type" "alu") 4898 (set_attr "mode" "SI")]) 4899 4900(define_insn "addqi3_cc" 4901 [(set (reg:CC FLAGS_REG) 4902 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0") 4903 (match_operand:QI 2 "general_operand" "qi,qm")] 4904 UNSPEC_ADD_CARRY)) 4905 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 4906 (plus:QI (match_dup 1) (match_dup 2)))] 4907 "ix86_binary_operator_ok (PLUS, QImode, operands)" 4908 "add{b}\t{%2, %0|%0, %2}" 4909 [(set_attr "type" "alu") 4910 (set_attr "mode" "QI")]) 4911 4912(define_expand "addsi3" 4913 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4914 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "") 4915 (match_operand:SI 2 "general_operand" ""))) 4916 (clobber (reg:CC FLAGS_REG))])] 4917 "" 4918 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;") 4919 4920(define_insn "*lea_1" 4921 [(set (match_operand:SI 0 "register_operand" "=r") 4922 (match_operand:SI 1 "no_seg_address_operand" "p"))] 4923 "!TARGET_64BIT" 4924 "lea{l}\t{%a1, %0|%0, %a1}" 4925 [(set_attr "type" "lea") 4926 (set_attr "mode" "SI")]) 4927 4928(define_insn "*lea_1_rex64" 4929 [(set (match_operand:SI 0 "register_operand" "=r") 4930 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))] 4931 "TARGET_64BIT" 4932 "lea{l}\t{%a1, %0|%0, %a1}" 4933 [(set_attr "type" "lea") 4934 (set_attr "mode" "SI")]) 4935 4936(define_insn "*lea_1_zext" 4937 [(set (match_operand:DI 0 "register_operand" "=r") 4938 (zero_extend:DI 4939 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))] 4940 "TARGET_64BIT" 4941 "lea{l}\t{%a1, %k0|%k0, %a1}" 4942 [(set_attr "type" "lea") 4943 (set_attr "mode" "SI")]) 4944 4945(define_insn "*lea_2_rex64" 4946 [(set (match_operand:DI 0 "register_operand" "=r") 4947 (match_operand:DI 1 "no_seg_address_operand" "p"))] 4948 "TARGET_64BIT" 4949 "lea{q}\t{%a1, %0|%0, %a1}" 4950 [(set_attr "type" "lea") 4951 (set_attr "mode" "DI")]) 4952 4953;; The lea patterns for non-Pmodes needs to be matched by several 4954;; insns converted to real lea by splitters. 4955 4956(define_insn_and_split "*lea_general_1" 4957 [(set (match_operand 0 "register_operand" "=r") 4958 (plus (plus (match_operand 1 "index_register_operand" "l") 4959 (match_operand 2 "register_operand" "r")) 4960 (match_operand 3 "immediate_operand" "i")))] 4961 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode 4962 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) 4963 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 4964 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 4965 && GET_MODE (operands[0]) == GET_MODE (operands[2]) 4966 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 4967 || GET_MODE (operands[3]) == VOIDmode)" 4968 "#" 4969 "&& reload_completed" 4970 [(const_int 0)] 4971{ 4972 rtx pat; 4973 operands[0] = gen_lowpart (SImode, operands[0]); 4974 operands[1] = gen_lowpart (Pmode, operands[1]); 4975 operands[2] = gen_lowpart (Pmode, operands[2]); 4976 operands[3] = gen_lowpart (Pmode, operands[3]); 4977 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]), 4978 operands[3]); 4979 if (Pmode != SImode) 4980 pat = gen_rtx_SUBREG (SImode, pat, 0); 4981 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 4982 DONE; 4983} 4984 [(set_attr "type" "lea") 4985 (set_attr "mode" "SI")]) 4986 4987(define_insn_and_split "*lea_general_1_zext" 4988 [(set (match_operand:DI 0 "register_operand" "=r") 4989 (zero_extend:DI 4990 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l") 4991 (match_operand:SI 2 "register_operand" "r")) 4992 (match_operand:SI 3 "immediate_operand" "i"))))] 4993 "TARGET_64BIT" 4994 "#" 4995 "&& reload_completed" 4996 [(set (match_dup 0) 4997 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1) 4998 (match_dup 2)) 4999 (match_dup 3)) 0)))] 5000{ 5001 operands[1] = gen_lowpart (Pmode, operands[1]); 5002 operands[2] = gen_lowpart (Pmode, operands[2]); 5003 operands[3] = gen_lowpart (Pmode, operands[3]); 5004} 5005 [(set_attr "type" "lea") 5006 (set_attr "mode" "SI")]) 5007 5008(define_insn_and_split "*lea_general_2" 5009 [(set (match_operand 0 "register_operand" "=r") 5010 (plus (mult (match_operand 1 "index_register_operand" "l") 5011 (match_operand 2 "const248_operand" "i")) 5012 (match_operand 3 "nonmemory_operand" "ri")))] 5013 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode 5014 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) 5015 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 5016 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 5017 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 5018 || GET_MODE (operands[3]) == VOIDmode)" 5019 "#" 5020 "&& reload_completed" 5021 [(const_int 0)] 5022{ 5023 rtx pat; 5024 operands[0] = gen_lowpart (SImode, operands[0]); 5025 operands[1] = gen_lowpart (Pmode, operands[1]); 5026 operands[3] = gen_lowpart (Pmode, operands[3]); 5027 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]), 5028 operands[3]); 5029 if (Pmode != SImode) 5030 pat = gen_rtx_SUBREG (SImode, pat, 0); 5031 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5032 DONE; 5033} 5034 [(set_attr "type" "lea") 5035 (set_attr "mode" "SI")]) 5036 5037(define_insn_and_split "*lea_general_2_zext" 5038 [(set (match_operand:DI 0 "register_operand" "=r") 5039 (zero_extend:DI 5040 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l") 5041 (match_operand:SI 2 "const248_operand" "n")) 5042 (match_operand:SI 3 "nonmemory_operand" "ri"))))] 5043 "TARGET_64BIT" 5044 "#" 5045 "&& reload_completed" 5046 [(set (match_dup 0) 5047 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1) 5048 (match_dup 2)) 5049 (match_dup 3)) 0)))] 5050{ 5051 operands[1] = gen_lowpart (Pmode, operands[1]); 5052 operands[3] = gen_lowpart (Pmode, operands[3]); 5053} 5054 [(set_attr "type" "lea") 5055 (set_attr "mode" "SI")]) 5056 5057(define_insn_and_split "*lea_general_3" 5058 [(set (match_operand 0 "register_operand" "=r") 5059 (plus (plus (mult (match_operand 1 "index_register_operand" "l") 5060 (match_operand 2 "const248_operand" "i")) 5061 (match_operand 3 "register_operand" "r")) 5062 (match_operand 4 "immediate_operand" "i")))] 5063 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode 5064 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) 5065 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 5066 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 5067 && GET_MODE (operands[0]) == GET_MODE (operands[3])" 5068 "#" 5069 "&& reload_completed" 5070 [(const_int 0)] 5071{ 5072 rtx pat; 5073 operands[0] = gen_lowpart (SImode, operands[0]); 5074 operands[1] = gen_lowpart (Pmode, operands[1]); 5075 operands[3] = gen_lowpart (Pmode, operands[3]); 5076 operands[4] = gen_lowpart (Pmode, operands[4]); 5077 pat = gen_rtx_PLUS (Pmode, 5078 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], 5079 operands[2]), 5080 operands[3]), 5081 operands[4]); 5082 if (Pmode != SImode) 5083 pat = gen_rtx_SUBREG (SImode, pat, 0); 5084 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5085 DONE; 5086} 5087 [(set_attr "type" "lea") 5088 (set_attr "mode" "SI")]) 5089 5090(define_insn_and_split "*lea_general_3_zext" 5091 [(set (match_operand:DI 0 "register_operand" "=r") 5092 (zero_extend:DI 5093 (plus:SI (plus:SI (mult:SI 5094 (match_operand:SI 1 "index_register_operand" "l") 5095 (match_operand:SI 2 "const248_operand" "n")) 5096 (match_operand:SI 3 "register_operand" "r")) 5097 (match_operand:SI 4 "immediate_operand" "i"))))] 5098 "TARGET_64BIT" 5099 "#" 5100 "&& reload_completed" 5101 [(set (match_dup 0) 5102 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1) 5103 (match_dup 2)) 5104 (match_dup 3)) 5105 (match_dup 4)) 0)))] 5106{ 5107 operands[1] = gen_lowpart (Pmode, operands[1]); 5108 operands[3] = gen_lowpart (Pmode, operands[3]); 5109 operands[4] = gen_lowpart (Pmode, operands[4]); 5110} 5111 [(set_attr "type" "lea") 5112 (set_attr "mode" "SI")]) 5113 5114(define_insn "*adddi_1_rex64" 5115 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r") 5116 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r") 5117 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le"))) 5118 (clobber (reg:CC FLAGS_REG))] 5119 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 5120{ 5121 switch (get_attr_type (insn)) 5122 { 5123 case TYPE_LEA: 5124 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 5125 return "lea{q}\t{%a2, %0|%0, %a2}"; 5126 5127 case TYPE_INCDEC: 5128 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5129 if (operands[2] == const1_rtx) 5130 return "inc{q}\t%0"; 5131 else 5132 { 5133 gcc_assert (operands[2] == constm1_rtx); 5134 return "dec{q}\t%0"; 5135 } 5136 5137 default: 5138 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5139 5140 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5141 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5142 if (GET_CODE (operands[2]) == CONST_INT 5143 /* Avoid overflows. */ 5144 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5145 && (INTVAL (operands[2]) == 128 5146 || (INTVAL (operands[2]) < 0 5147 && INTVAL (operands[2]) != -128))) 5148 { 5149 operands[2] = GEN_INT (-INTVAL (operands[2])); 5150 return "sub{q}\t{%2, %0|%0, %2}"; 5151 } 5152 return "add{q}\t{%2, %0|%0, %2}"; 5153 } 5154} 5155 [(set (attr "type") 5156 (cond [(eq_attr "alternative" "2") 5157 (const_string "lea") 5158 ; Current assemblers are broken and do not allow @GOTOFF in 5159 ; ought but a memory context. 5160 (match_operand:DI 2 "pic_symbolic_operand" "") 5161 (const_string "lea") 5162 (match_operand:DI 2 "incdec_operand" "") 5163 (const_string "incdec") 5164 ] 5165 (const_string "alu"))) 5166 (set_attr "mode" "DI")]) 5167 5168;; Convert lea to the lea pattern to avoid flags dependency. 5169(define_split 5170 [(set (match_operand:DI 0 "register_operand" "") 5171 (plus:DI (match_operand:DI 1 "register_operand" "") 5172 (match_operand:DI 2 "x86_64_nonmemory_operand" ""))) 5173 (clobber (reg:CC FLAGS_REG))] 5174 "TARGET_64BIT && reload_completed 5175 && true_regnum (operands[0]) != true_regnum (operands[1])" 5176 [(set (match_dup 0) 5177 (plus:DI (match_dup 1) 5178 (match_dup 2)))] 5179 "") 5180 5181(define_insn "*adddi_2_rex64" 5182 [(set (reg FLAGS_REG) 5183 (compare 5184 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 5185 (match_operand:DI 2 "x86_64_general_operand" "rme,re")) 5186 (const_int 0))) 5187 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") 5188 (plus:DI (match_dup 1) (match_dup 2)))] 5189 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 5190 && ix86_binary_operator_ok (PLUS, DImode, operands) 5191 /* Current assemblers are broken and do not allow @GOTOFF in 5192 ought but a memory context. */ 5193 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5194{ 5195 switch (get_attr_type (insn)) 5196 { 5197 case TYPE_INCDEC: 5198 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5199 if (operands[2] == const1_rtx) 5200 return "inc{q}\t%0"; 5201 else 5202 { 5203 gcc_assert (operands[2] == constm1_rtx); 5204 return "dec{q}\t%0"; 5205 } 5206 5207 default: 5208 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5209 /* ???? We ought to handle there the 32bit case too 5210 - do we need new constraint? */ 5211 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5212 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5213 if (GET_CODE (operands[2]) == CONST_INT 5214 /* Avoid overflows. */ 5215 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5216 && (INTVAL (operands[2]) == 128 5217 || (INTVAL (operands[2]) < 0 5218 && INTVAL (operands[2]) != -128))) 5219 { 5220 operands[2] = GEN_INT (-INTVAL (operands[2])); 5221 return "sub{q}\t{%2, %0|%0, %2}"; 5222 } 5223 return "add{q}\t{%2, %0|%0, %2}"; 5224 } 5225} 5226 [(set (attr "type") 5227 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5228 (const_string "incdec") 5229 (const_string "alu"))) 5230 (set_attr "mode" "DI")]) 5231 5232(define_insn "*adddi_3_rex64" 5233 [(set (reg FLAGS_REG) 5234 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme")) 5235 (match_operand:DI 1 "x86_64_general_operand" "%0"))) 5236 (clobber (match_scratch:DI 0 "=r"))] 5237 "TARGET_64BIT 5238 && ix86_match_ccmode (insn, CCZmode) 5239 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5240 /* Current assemblers are broken and do not allow @GOTOFF in 5241 ought but a memory context. */ 5242 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5243{ 5244 switch (get_attr_type (insn)) 5245 { 5246 case TYPE_INCDEC: 5247 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5248 if (operands[2] == const1_rtx) 5249 return "inc{q}\t%0"; 5250 else 5251 { 5252 gcc_assert (operands[2] == constm1_rtx); 5253 return "dec{q}\t%0"; 5254 } 5255 5256 default: 5257 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5258 /* ???? We ought to handle there the 32bit case too 5259 - do we need new constraint? */ 5260 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5261 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5262 if (GET_CODE (operands[2]) == CONST_INT 5263 /* Avoid overflows. */ 5264 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5265 && (INTVAL (operands[2]) == 128 5266 || (INTVAL (operands[2]) < 0 5267 && INTVAL (operands[2]) != -128))) 5268 { 5269 operands[2] = GEN_INT (-INTVAL (operands[2])); 5270 return "sub{q}\t{%2, %0|%0, %2}"; 5271 } 5272 return "add{q}\t{%2, %0|%0, %2}"; 5273 } 5274} 5275 [(set (attr "type") 5276 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5277 (const_string "incdec") 5278 (const_string "alu"))) 5279 (set_attr "mode" "DI")]) 5280 5281; For comparisons against 1, -1 and 128, we may generate better code 5282; by converting cmp to add, inc or dec as done by peephole2. This pattern 5283; is matched then. We can't accept general immediate, because for 5284; case of overflows, the result is messed up. 5285; This pattern also don't hold of 0x8000000000000000, since the value overflows 5286; when negated. 5287; Also carry flag is reversed compared to cmp, so this conversion is valid 5288; only for comparisons not depending on it. 5289(define_insn "*adddi_4_rex64" 5290 [(set (reg FLAGS_REG) 5291 (compare (match_operand:DI 1 "nonimmediate_operand" "0") 5292 (match_operand:DI 2 "x86_64_immediate_operand" "e"))) 5293 (clobber (match_scratch:DI 0 "=rm"))] 5294 "TARGET_64BIT 5295 && ix86_match_ccmode (insn, CCGCmode)" 5296{ 5297 switch (get_attr_type (insn)) 5298 { 5299 case TYPE_INCDEC: 5300 if (operands[2] == constm1_rtx) 5301 return "inc{q}\t%0"; 5302 else 5303 { 5304 gcc_assert (operands[2] == const1_rtx); 5305 return "dec{q}\t%0"; 5306 } 5307 5308 default: 5309 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5310 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5311 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5312 if ((INTVAL (operands[2]) == -128 5313 || (INTVAL (operands[2]) > 0 5314 && INTVAL (operands[2]) != 128)) 5315 /* Avoid overflows. */ 5316 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))) 5317 return "sub{q}\t{%2, %0|%0, %2}"; 5318 operands[2] = GEN_INT (-INTVAL (operands[2])); 5319 return "add{q}\t{%2, %0|%0, %2}"; 5320 } 5321} 5322 [(set (attr "type") 5323 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5324 (const_string "incdec") 5325 (const_string "alu"))) 5326 (set_attr "mode" "DI")]) 5327 5328(define_insn "*adddi_5_rex64" 5329 [(set (reg FLAGS_REG) 5330 (compare 5331 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0") 5332 (match_operand:DI 2 "x86_64_general_operand" "rme")) 5333 (const_int 0))) 5334 (clobber (match_scratch:DI 0 "=r"))] 5335 "TARGET_64BIT 5336 && ix86_match_ccmode (insn, CCGOCmode) 5337 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5338 /* Current assemblers are broken and do not allow @GOTOFF in 5339 ought but a memory context. */ 5340 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5341{ 5342 switch (get_attr_type (insn)) 5343 { 5344 case TYPE_INCDEC: 5345 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5346 if (operands[2] == const1_rtx) 5347 return "inc{q}\t%0"; 5348 else 5349 { 5350 gcc_assert (operands[2] == constm1_rtx); 5351 return "dec{q}\t%0"; 5352 } 5353 5354 default: 5355 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5356 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5357 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5358 if (GET_CODE (operands[2]) == CONST_INT 5359 /* Avoid overflows. */ 5360 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5361 && (INTVAL (operands[2]) == 128 5362 || (INTVAL (operands[2]) < 0 5363 && INTVAL (operands[2]) != -128))) 5364 { 5365 operands[2] = GEN_INT (-INTVAL (operands[2])); 5366 return "sub{q}\t{%2, %0|%0, %2}"; 5367 } 5368 return "add{q}\t{%2, %0|%0, %2}"; 5369 } 5370} 5371 [(set (attr "type") 5372 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5373 (const_string "incdec") 5374 (const_string "alu"))) 5375 (set_attr "mode" "DI")]) 5376 5377 5378(define_insn "*addsi_1" 5379 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r") 5380 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r") 5381 (match_operand:SI 2 "general_operand" "rmni,rni,lni"))) 5382 (clobber (reg:CC FLAGS_REG))] 5383 "ix86_binary_operator_ok (PLUS, SImode, operands)" 5384{ 5385 switch (get_attr_type (insn)) 5386 { 5387 case TYPE_LEA: 5388 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 5389 return "lea{l}\t{%a2, %0|%0, %a2}"; 5390 5391 case TYPE_INCDEC: 5392 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5393 if (operands[2] == const1_rtx) 5394 return "inc{l}\t%0"; 5395 else 5396 { 5397 gcc_assert (operands[2] == constm1_rtx); 5398 return "dec{l}\t%0"; 5399 } 5400 5401 default: 5402 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5403 5404 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5405 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5406 if (GET_CODE (operands[2]) == CONST_INT 5407 && (INTVAL (operands[2]) == 128 5408 || (INTVAL (operands[2]) < 0 5409 && INTVAL (operands[2]) != -128))) 5410 { 5411 operands[2] = GEN_INT (-INTVAL (operands[2])); 5412 return "sub{l}\t{%2, %0|%0, %2}"; 5413 } 5414 return "add{l}\t{%2, %0|%0, %2}"; 5415 } 5416} 5417 [(set (attr "type") 5418 (cond [(eq_attr "alternative" "2") 5419 (const_string "lea") 5420 ; Current assemblers are broken and do not allow @GOTOFF in 5421 ; ought but a memory context. 5422 (match_operand:SI 2 "pic_symbolic_operand" "") 5423 (const_string "lea") 5424 (match_operand:SI 2 "incdec_operand" "") 5425 (const_string "incdec") 5426 ] 5427 (const_string "alu"))) 5428 (set_attr "mode" "SI")]) 5429 5430;; Convert lea to the lea pattern to avoid flags dependency. 5431(define_split 5432 [(set (match_operand 0 "register_operand" "") 5433 (plus (match_operand 1 "register_operand" "") 5434 (match_operand 2 "nonmemory_operand" ""))) 5435 (clobber (reg:CC FLAGS_REG))] 5436 "reload_completed 5437 && true_regnum (operands[0]) != true_regnum (operands[1])" 5438 [(const_int 0)] 5439{ 5440 rtx pat; 5441 /* In -fPIC mode the constructs like (const (unspec [symbol_ref])) 5442 may confuse gen_lowpart. */ 5443 if (GET_MODE (operands[0]) != Pmode) 5444 { 5445 operands[1] = gen_lowpart (Pmode, operands[1]); 5446 operands[2] = gen_lowpart (Pmode, operands[2]); 5447 } 5448 operands[0] = gen_lowpart (SImode, operands[0]); 5449 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]); 5450 if (Pmode != SImode) 5451 pat = gen_rtx_SUBREG (SImode, pat, 0); 5452 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5453 DONE; 5454}) 5455 5456;; It may seem that nonimmediate operand is proper one for operand 1. 5457;; The addsi_1 pattern allows nonimmediate operand at that place and 5458;; we take care in ix86_binary_operator_ok to not allow two memory 5459;; operands so proper swapping will be done in reload. This allow 5460;; patterns constructed from addsi_1 to match. 5461(define_insn "addsi_1_zext" 5462 [(set (match_operand:DI 0 "register_operand" "=r,r") 5463 (zero_extend:DI 5464 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") 5465 (match_operand:SI 2 "general_operand" "rmni,lni")))) 5466 (clobber (reg:CC FLAGS_REG))] 5467 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 5468{ 5469 switch (get_attr_type (insn)) 5470 { 5471 case TYPE_LEA: 5472 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 5473 return "lea{l}\t{%a2, %k0|%k0, %a2}"; 5474 5475 case TYPE_INCDEC: 5476 if (operands[2] == const1_rtx) 5477 return "inc{l}\t%k0"; 5478 else 5479 { 5480 gcc_assert (operands[2] == constm1_rtx); 5481 return "dec{l}\t%k0"; 5482 } 5483 5484 default: 5485 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5486 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5487 if (GET_CODE (operands[2]) == CONST_INT 5488 && (INTVAL (operands[2]) == 128 5489 || (INTVAL (operands[2]) < 0 5490 && INTVAL (operands[2]) != -128))) 5491 { 5492 operands[2] = GEN_INT (-INTVAL (operands[2])); 5493 return "sub{l}\t{%2, %k0|%k0, %2}"; 5494 } 5495 return "add{l}\t{%2, %k0|%k0, %2}"; 5496 } 5497} 5498 [(set (attr "type") 5499 (cond [(eq_attr "alternative" "1") 5500 (const_string "lea") 5501 ; Current assemblers are broken and do not allow @GOTOFF in 5502 ; ought but a memory context. 5503 (match_operand:SI 2 "pic_symbolic_operand" "") 5504 (const_string "lea") 5505 (match_operand:SI 2 "incdec_operand" "") 5506 (const_string "incdec") 5507 ] 5508 (const_string "alu"))) 5509 (set_attr "mode" "SI")]) 5510 5511;; Convert lea to the lea pattern to avoid flags dependency. 5512(define_split 5513 [(set (match_operand:DI 0 "register_operand" "") 5514 (zero_extend:DI 5515 (plus:SI (match_operand:SI 1 "register_operand" "") 5516 (match_operand:SI 2 "nonmemory_operand" "")))) 5517 (clobber (reg:CC FLAGS_REG))] 5518 "TARGET_64BIT && reload_completed 5519 && true_regnum (operands[0]) != true_regnum (operands[1])" 5520 [(set (match_dup 0) 5521 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))] 5522{ 5523 operands[1] = gen_lowpart (Pmode, operands[1]); 5524 operands[2] = gen_lowpart (Pmode, operands[2]); 5525}) 5526 5527(define_insn "*addsi_2" 5528 [(set (reg FLAGS_REG) 5529 (compare 5530 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 5531 (match_operand:SI 2 "general_operand" "rmni,rni")) 5532 (const_int 0))) 5533 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 5534 (plus:SI (match_dup 1) (match_dup 2)))] 5535 "ix86_match_ccmode (insn, CCGOCmode) 5536 && ix86_binary_operator_ok (PLUS, SImode, operands) 5537 /* Current assemblers are broken and do not allow @GOTOFF in 5538 ought but a memory context. */ 5539 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5540{ 5541 switch (get_attr_type (insn)) 5542 { 5543 case TYPE_INCDEC: 5544 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5545 if (operands[2] == const1_rtx) 5546 return "inc{l}\t%0"; 5547 else 5548 { 5549 gcc_assert (operands[2] == constm1_rtx); 5550 return "dec{l}\t%0"; 5551 } 5552 5553 default: 5554 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5555 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5556 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5557 if (GET_CODE (operands[2]) == CONST_INT 5558 && (INTVAL (operands[2]) == 128 5559 || (INTVAL (operands[2]) < 0 5560 && INTVAL (operands[2]) != -128))) 5561 { 5562 operands[2] = GEN_INT (-INTVAL (operands[2])); 5563 return "sub{l}\t{%2, %0|%0, %2}"; 5564 } 5565 return "add{l}\t{%2, %0|%0, %2}"; 5566 } 5567} 5568 [(set (attr "type") 5569 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5570 (const_string "incdec") 5571 (const_string "alu"))) 5572 (set_attr "mode" "SI")]) 5573 5574;; See comment for addsi_1_zext why we do use nonimmediate_operand 5575(define_insn "*addsi_2_zext" 5576 [(set (reg FLAGS_REG) 5577 (compare 5578 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 5579 (match_operand:SI 2 "general_operand" "rmni")) 5580 (const_int 0))) 5581 (set (match_operand:DI 0 "register_operand" "=r") 5582 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5583 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 5584 && ix86_binary_operator_ok (PLUS, SImode, operands) 5585 /* Current assemblers are broken and do not allow @GOTOFF in 5586 ought but a memory context. */ 5587 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5588{ 5589 switch (get_attr_type (insn)) 5590 { 5591 case TYPE_INCDEC: 5592 if (operands[2] == const1_rtx) 5593 return "inc{l}\t%k0"; 5594 else 5595 { 5596 gcc_assert (operands[2] == constm1_rtx); 5597 return "dec{l}\t%k0"; 5598 } 5599 5600 default: 5601 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5602 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5603 if (GET_CODE (operands[2]) == CONST_INT 5604 && (INTVAL (operands[2]) == 128 5605 || (INTVAL (operands[2]) < 0 5606 && INTVAL (operands[2]) != -128))) 5607 { 5608 operands[2] = GEN_INT (-INTVAL (operands[2])); 5609 return "sub{l}\t{%2, %k0|%k0, %2}"; 5610 } 5611 return "add{l}\t{%2, %k0|%k0, %2}"; 5612 } 5613} 5614 [(set (attr "type") 5615 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5616 (const_string "incdec") 5617 (const_string "alu"))) 5618 (set_attr "mode" "SI")]) 5619 5620(define_insn "*addsi_3" 5621 [(set (reg FLAGS_REG) 5622 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni")) 5623 (match_operand:SI 1 "nonimmediate_operand" "%0"))) 5624 (clobber (match_scratch:SI 0 "=r"))] 5625 "ix86_match_ccmode (insn, CCZmode) 5626 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5627 /* Current assemblers are broken and do not allow @GOTOFF in 5628 ought but a memory context. */ 5629 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5630{ 5631 switch (get_attr_type (insn)) 5632 { 5633 case TYPE_INCDEC: 5634 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5635 if (operands[2] == const1_rtx) 5636 return "inc{l}\t%0"; 5637 else 5638 { 5639 gcc_assert (operands[2] == constm1_rtx); 5640 return "dec{l}\t%0"; 5641 } 5642 5643 default: 5644 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5645 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5646 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5647 if (GET_CODE (operands[2]) == CONST_INT 5648 && (INTVAL (operands[2]) == 128 5649 || (INTVAL (operands[2]) < 0 5650 && INTVAL (operands[2]) != -128))) 5651 { 5652 operands[2] = GEN_INT (-INTVAL (operands[2])); 5653 return "sub{l}\t{%2, %0|%0, %2}"; 5654 } 5655 return "add{l}\t{%2, %0|%0, %2}"; 5656 } 5657} 5658 [(set (attr "type") 5659 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5660 (const_string "incdec") 5661 (const_string "alu"))) 5662 (set_attr "mode" "SI")]) 5663 5664;; See comment for addsi_1_zext why we do use nonimmediate_operand 5665(define_insn "*addsi_3_zext" 5666 [(set (reg FLAGS_REG) 5667 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni")) 5668 (match_operand:SI 1 "nonimmediate_operand" "%0"))) 5669 (set (match_operand:DI 0 "register_operand" "=r") 5670 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5671 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode) 5672 && ix86_binary_operator_ok (PLUS, SImode, operands) 5673 /* Current assemblers are broken and do not allow @GOTOFF in 5674 ought but a memory context. */ 5675 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5676{ 5677 switch (get_attr_type (insn)) 5678 { 5679 case TYPE_INCDEC: 5680 if (operands[2] == const1_rtx) 5681 return "inc{l}\t%k0"; 5682 else 5683 { 5684 gcc_assert (operands[2] == constm1_rtx); 5685 return "dec{l}\t%k0"; 5686 } 5687 5688 default: 5689 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5690 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5691 if (GET_CODE (operands[2]) == CONST_INT 5692 && (INTVAL (operands[2]) == 128 5693 || (INTVAL (operands[2]) < 0 5694 && INTVAL (operands[2]) != -128))) 5695 { 5696 operands[2] = GEN_INT (-INTVAL (operands[2])); 5697 return "sub{l}\t{%2, %k0|%k0, %2}"; 5698 } 5699 return "add{l}\t{%2, %k0|%k0, %2}"; 5700 } 5701} 5702 [(set (attr "type") 5703 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5704 (const_string "incdec") 5705 (const_string "alu"))) 5706 (set_attr "mode" "SI")]) 5707 5708; For comparisons against 1, -1 and 128, we may generate better code 5709; by converting cmp to add, inc or dec as done by peephole2. This pattern 5710; is matched then. We can't accept general immediate, because for 5711; case of overflows, the result is messed up. 5712; This pattern also don't hold of 0x80000000, since the value overflows 5713; when negated. 5714; Also carry flag is reversed compared to cmp, so this conversion is valid 5715; only for comparisons not depending on it. 5716(define_insn "*addsi_4" 5717 [(set (reg FLAGS_REG) 5718 (compare (match_operand:SI 1 "nonimmediate_operand" "0") 5719 (match_operand:SI 2 "const_int_operand" "n"))) 5720 (clobber (match_scratch:SI 0 "=rm"))] 5721 "ix86_match_ccmode (insn, CCGCmode) 5722 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000" 5723{ 5724 switch (get_attr_type (insn)) 5725 { 5726 case TYPE_INCDEC: 5727 if (operands[2] == constm1_rtx) 5728 return "inc{l}\t%0"; 5729 else 5730 { 5731 gcc_assert (operands[2] == const1_rtx); 5732 return "dec{l}\t%0"; 5733 } 5734 5735 default: 5736 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5737 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5738 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5739 if ((INTVAL (operands[2]) == -128 5740 || (INTVAL (operands[2]) > 0 5741 && INTVAL (operands[2]) != 128))) 5742 return "sub{l}\t{%2, %0|%0, %2}"; 5743 operands[2] = GEN_INT (-INTVAL (operands[2])); 5744 return "add{l}\t{%2, %0|%0, %2}"; 5745 } 5746} 5747 [(set (attr "type") 5748 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5749 (const_string "incdec") 5750 (const_string "alu"))) 5751 (set_attr "mode" "SI")]) 5752 5753(define_insn "*addsi_5" 5754 [(set (reg FLAGS_REG) 5755 (compare 5756 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 5757 (match_operand:SI 2 "general_operand" "rmni")) 5758 (const_int 0))) 5759 (clobber (match_scratch:SI 0 "=r"))] 5760 "ix86_match_ccmode (insn, CCGOCmode) 5761 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5762 /* Current assemblers are broken and do not allow @GOTOFF in 5763 ought but a memory context. */ 5764 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5765{ 5766 switch (get_attr_type (insn)) 5767 { 5768 case TYPE_INCDEC: 5769 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5770 if (operands[2] == const1_rtx) 5771 return "inc{l}\t%0"; 5772 else 5773 { 5774 gcc_assert (operands[2] == constm1_rtx); 5775 return "dec{l}\t%0"; 5776 } 5777 5778 default: 5779 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5780 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5781 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5782 if (GET_CODE (operands[2]) == CONST_INT 5783 && (INTVAL (operands[2]) == 128 5784 || (INTVAL (operands[2]) < 0 5785 && INTVAL (operands[2]) != -128))) 5786 { 5787 operands[2] = GEN_INT (-INTVAL (operands[2])); 5788 return "sub{l}\t{%2, %0|%0, %2}"; 5789 } 5790 return "add{l}\t{%2, %0|%0, %2}"; 5791 } 5792} 5793 [(set (attr "type") 5794 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5795 (const_string "incdec") 5796 (const_string "alu"))) 5797 (set_attr "mode" "SI")]) 5798 5799(define_expand "addhi3" 5800 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 5801 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "") 5802 (match_operand:HI 2 "general_operand" ""))) 5803 (clobber (reg:CC FLAGS_REG))])] 5804 "TARGET_HIMODE_MATH" 5805 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;") 5806 5807;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah 5808;; type optimizations enabled by define-splits. This is not important 5809;; for PII, and in fact harmful because of partial register stalls. 5810 5811(define_insn "*addhi_1_lea" 5812 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") 5813 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r") 5814 (match_operand:HI 2 "general_operand" "ri,rm,lni"))) 5815 (clobber (reg:CC FLAGS_REG))] 5816 "!TARGET_PARTIAL_REG_STALL 5817 && ix86_binary_operator_ok (PLUS, HImode, operands)" 5818{ 5819 switch (get_attr_type (insn)) 5820 { 5821 case TYPE_LEA: 5822 return "#"; 5823 case TYPE_INCDEC: 5824 if (operands[2] == const1_rtx) 5825 return "inc{w}\t%0"; 5826 else 5827 { 5828 gcc_assert (operands[2] == constm1_rtx); 5829 return "dec{w}\t%0"; 5830 } 5831 5832 default: 5833 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5834 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5835 if (GET_CODE (operands[2]) == CONST_INT 5836 && (INTVAL (operands[2]) == 128 5837 || (INTVAL (operands[2]) < 0 5838 && INTVAL (operands[2]) != -128))) 5839 { 5840 operands[2] = GEN_INT (-INTVAL (operands[2])); 5841 return "sub{w}\t{%2, %0|%0, %2}"; 5842 } 5843 return "add{w}\t{%2, %0|%0, %2}"; 5844 } 5845} 5846 [(set (attr "type") 5847 (if_then_else (eq_attr "alternative" "2") 5848 (const_string "lea") 5849 (if_then_else (match_operand:HI 2 "incdec_operand" "") 5850 (const_string "incdec") 5851 (const_string "alu")))) 5852 (set_attr "mode" "HI,HI,SI")]) 5853 5854(define_insn "*addhi_1" 5855 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 5856 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 5857 (match_operand:HI 2 "general_operand" "ri,rm"))) 5858 (clobber (reg:CC FLAGS_REG))] 5859 "TARGET_PARTIAL_REG_STALL 5860 && ix86_binary_operator_ok (PLUS, HImode, operands)" 5861{ 5862 switch (get_attr_type (insn)) 5863 { 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 (match_operand:HI 2 "incdec_operand" "") 5889 (const_string "incdec") 5890 (const_string "alu"))) 5891 (set_attr "mode" "HI")]) 5892 5893(define_insn "*addhi_2" 5894 [(set (reg FLAGS_REG) 5895 (compare 5896 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 5897 (match_operand:HI 2 "general_operand" "rmni,rni")) 5898 (const_int 0))) 5899 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 5900 (plus:HI (match_dup 1) (match_dup 2)))] 5901 "ix86_match_ccmode (insn, CCGOCmode) 5902 && ix86_binary_operator_ok (PLUS, HImode, operands)" 5903{ 5904 switch (get_attr_type (insn)) 5905 { 5906 case TYPE_INCDEC: 5907 if (operands[2] == const1_rtx) 5908 return "inc{w}\t%0"; 5909 else 5910 { 5911 gcc_assert (operands[2] == constm1_rtx); 5912 return "dec{w}\t%0"; 5913 } 5914 5915 default: 5916 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5917 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5918 if (GET_CODE (operands[2]) == CONST_INT 5919 && (INTVAL (operands[2]) == 128 5920 || (INTVAL (operands[2]) < 0 5921 && INTVAL (operands[2]) != -128))) 5922 { 5923 operands[2] = GEN_INT (-INTVAL (operands[2])); 5924 return "sub{w}\t{%2, %0|%0, %2}"; 5925 } 5926 return "add{w}\t{%2, %0|%0, %2}"; 5927 } 5928} 5929 [(set (attr "type") 5930 (if_then_else (match_operand:HI 2 "incdec_operand" "") 5931 (const_string "incdec") 5932 (const_string "alu"))) 5933 (set_attr "mode" "HI")]) 5934 5935(define_insn "*addhi_3" 5936 [(set (reg FLAGS_REG) 5937 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni")) 5938 (match_operand:HI 1 "nonimmediate_operand" "%0"))) 5939 (clobber (match_scratch:HI 0 "=r"))] 5940 "ix86_match_ccmode (insn, CCZmode) 5941 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 5942{ 5943 switch (get_attr_type (insn)) 5944 { 5945 case TYPE_INCDEC: 5946 if (operands[2] == const1_rtx) 5947 return "inc{w}\t%0"; 5948 else 5949 { 5950 gcc_assert (operands[2] == constm1_rtx); 5951 return "dec{w}\t%0"; 5952 } 5953 5954 default: 5955 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5956 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5957 if (GET_CODE (operands[2]) == CONST_INT 5958 && (INTVAL (operands[2]) == 128 5959 || (INTVAL (operands[2]) < 0 5960 && INTVAL (operands[2]) != -128))) 5961 { 5962 operands[2] = GEN_INT (-INTVAL (operands[2])); 5963 return "sub{w}\t{%2, %0|%0, %2}"; 5964 } 5965 return "add{w}\t{%2, %0|%0, %2}"; 5966 } 5967} 5968 [(set (attr "type") 5969 (if_then_else (match_operand:HI 2 "incdec_operand" "") 5970 (const_string "incdec") 5971 (const_string "alu"))) 5972 (set_attr "mode" "HI")]) 5973 5974; See comments above addsi_4 for details. 5975(define_insn "*addhi_4" 5976 [(set (reg FLAGS_REG) 5977 (compare (match_operand:HI 1 "nonimmediate_operand" "0") 5978 (match_operand:HI 2 "const_int_operand" "n"))) 5979 (clobber (match_scratch:HI 0 "=rm"))] 5980 "ix86_match_ccmode (insn, CCGCmode) 5981 && (INTVAL (operands[2]) & 0xffff) != 0x8000" 5982{ 5983 switch (get_attr_type (insn)) 5984 { 5985 case TYPE_INCDEC: 5986 if (operands[2] == constm1_rtx) 5987 return "inc{w}\t%0"; 5988 else 5989 { 5990 gcc_assert (operands[2] == const1_rtx); 5991 return "dec{w}\t%0"; 5992 } 5993 5994 default: 5995 gcc_assert (rtx_equal_p (operands[0], operands[1])); 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 ((INTVAL (operands[2]) == -128 5999 || (INTVAL (operands[2]) > 0 6000 && INTVAL (operands[2]) != 128))) 6001 return "sub{w}\t{%2, %0|%0, %2}"; 6002 operands[2] = GEN_INT (-INTVAL (operands[2])); 6003 return "add{w}\t{%2, %0|%0, %2}"; 6004 } 6005} 6006 [(set (attr "type") 6007 (if_then_else (match_operand:HI 2 "incdec_operand" "") 6008 (const_string "incdec") 6009 (const_string "alu"))) 6010 (set_attr "mode" "SI")]) 6011 6012 6013(define_insn "*addhi_5" 6014 [(set (reg FLAGS_REG) 6015 (compare 6016 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0") 6017 (match_operand:HI 2 "general_operand" "rmni")) 6018 (const_int 0))) 6019 (clobber (match_scratch:HI 0 "=r"))] 6020 "ix86_match_ccmode (insn, CCGOCmode) 6021 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6022{ 6023 switch (get_attr_type (insn)) 6024 { 6025 case TYPE_INCDEC: 6026 if (operands[2] == const1_rtx) 6027 return "inc{w}\t%0"; 6028 else 6029 { 6030 gcc_assert (operands[2] == constm1_rtx); 6031 return "dec{w}\t%0"; 6032 } 6033 6034 default: 6035 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 6036 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 6037 if (GET_CODE (operands[2]) == CONST_INT 6038 && (INTVAL (operands[2]) == 128 6039 || (INTVAL (operands[2]) < 0 6040 && INTVAL (operands[2]) != -128))) 6041 { 6042 operands[2] = GEN_INT (-INTVAL (operands[2])); 6043 return "sub{w}\t{%2, %0|%0, %2}"; 6044 } 6045 return "add{w}\t{%2, %0|%0, %2}"; 6046 } 6047} 6048 [(set (attr "type") 6049 (if_then_else (match_operand:HI 2 "incdec_operand" "") 6050 (const_string "incdec") 6051 (const_string "alu"))) 6052 (set_attr "mode" "HI")]) 6053 6054(define_expand "addqi3" 6055 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") 6056 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "") 6057 (match_operand:QI 2 "general_operand" ""))) 6058 (clobber (reg:CC FLAGS_REG))])] 6059 "TARGET_QIMODE_MATH" 6060 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;") 6061 6062;; %%% Potential partial reg stall on alternative 2. What to do? 6063(define_insn "*addqi_1_lea" 6064 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r") 6065 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r") 6066 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln"))) 6067 (clobber (reg:CC FLAGS_REG))] 6068 "!TARGET_PARTIAL_REG_STALL 6069 && ix86_binary_operator_ok (PLUS, QImode, operands)" 6070{ 6071 int widen = (which_alternative == 2); 6072 switch (get_attr_type (insn)) 6073 { 6074 case TYPE_LEA: 6075 return "#"; 6076 case TYPE_INCDEC: 6077 if (operands[2] == const1_rtx) 6078 return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; 6079 else 6080 { 6081 gcc_assert (operands[2] == constm1_rtx); 6082 return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; 6083 } 6084 6085 default: 6086 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 6087 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 6088 if (GET_CODE (operands[2]) == CONST_INT 6089 && (INTVAL (operands[2]) == 128 6090 || (INTVAL (operands[2]) < 0 6091 && INTVAL (operands[2]) != -128))) 6092 { 6093 operands[2] = GEN_INT (-INTVAL (operands[2])); 6094 if (widen) 6095 return "sub{l}\t{%2, %k0|%k0, %2}"; 6096 else 6097 return "sub{b}\t{%2, %0|%0, %2}"; 6098 } 6099 if (widen) 6100 return "add{l}\t{%k2, %k0|%k0, %k2}"; 6101 else 6102 return "add{b}\t{%2, %0|%0, %2}"; 6103 } 6104} 6105 [(set (attr "type") 6106 (if_then_else (eq_attr "alternative" "3") 6107 (const_string "lea") 6108 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6109 (const_string "incdec") 6110 (const_string "alu")))) 6111 (set_attr "mode" "QI,QI,SI,SI")]) 6112 6113(define_insn "*addqi_1" 6114 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 6115 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 6116 (match_operand:QI 2 "general_operand" "qn,qmn,rn"))) 6117 (clobber (reg:CC FLAGS_REG))] 6118 "TARGET_PARTIAL_REG_STALL 6119 && ix86_binary_operator_ok (PLUS, QImode, operands)" 6120{ 6121 int widen = (which_alternative == 2); 6122 switch (get_attr_type (insn)) 6123 { 6124 case TYPE_INCDEC: 6125 if (operands[2] == const1_rtx) 6126 return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; 6127 else 6128 { 6129 gcc_assert (operands[2] == constm1_rtx); 6130 return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; 6131 } 6132 6133 default: 6134 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 6135 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 6136 if (GET_CODE (operands[2]) == CONST_INT 6137 && (INTVAL (operands[2]) == 128 6138 || (INTVAL (operands[2]) < 0 6139 && INTVAL (operands[2]) != -128))) 6140 { 6141 operands[2] = GEN_INT (-INTVAL (operands[2])); 6142 if (widen) 6143 return "sub{l}\t{%2, %k0|%k0, %2}"; 6144 else 6145 return "sub{b}\t{%2, %0|%0, %2}"; 6146 } 6147 if (widen) 6148 return "add{l}\t{%k2, %k0|%k0, %k2}"; 6149 else 6150 return "add{b}\t{%2, %0|%0, %2}"; 6151 } 6152} 6153 [(set (attr "type") 6154 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6155 (const_string "incdec") 6156 (const_string "alu"))) 6157 (set_attr "mode" "QI,QI,SI")]) 6158 6159(define_insn "*addqi_1_slp" 6160 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 6161 (plus:QI (match_dup 0) 6162 (match_operand:QI 1 "general_operand" "qn,qnm"))) 6163 (clobber (reg:CC FLAGS_REG))] 6164 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 6165 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 6166{ 6167 switch (get_attr_type (insn)) 6168 { 6169 case TYPE_INCDEC: 6170 if (operands[1] == const1_rtx) 6171 return "inc{b}\t%0"; 6172 else 6173 { 6174 gcc_assert (operands[1] == constm1_rtx); 6175 return "dec{b}\t%0"; 6176 } 6177 6178 default: 6179 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */ 6180 if (GET_CODE (operands[1]) == CONST_INT 6181 && INTVAL (operands[1]) < 0) 6182 { 6183 operands[1] = GEN_INT (-INTVAL (operands[1])); 6184 return "sub{b}\t{%1, %0|%0, %1}"; 6185 } 6186 return "add{b}\t{%1, %0|%0, %1}"; 6187 } 6188} 6189 [(set (attr "type") 6190 (if_then_else (match_operand:QI 1 "incdec_operand" "") 6191 (const_string "incdec") 6192 (const_string "alu1"))) 6193 (set (attr "memory") 6194 (if_then_else (match_operand 1 "memory_operand" "") 6195 (const_string "load") 6196 (const_string "none"))) 6197 (set_attr "mode" "QI")]) 6198 6199(define_insn "*addqi_2" 6200 [(set (reg FLAGS_REG) 6201 (compare 6202 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 6203 (match_operand:QI 2 "general_operand" "qmni,qni")) 6204 (const_int 0))) 6205 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 6206 (plus:QI (match_dup 1) (match_dup 2)))] 6207 "ix86_match_ccmode (insn, CCGOCmode) 6208 && ix86_binary_operator_ok (PLUS, QImode, operands)" 6209{ 6210 switch (get_attr_type (insn)) 6211 { 6212 case TYPE_INCDEC: 6213 if (operands[2] == const1_rtx) 6214 return "inc{b}\t%0"; 6215 else 6216 { 6217 gcc_assert (operands[2] == constm1_rtx 6218 || (GET_CODE (operands[2]) == CONST_INT 6219 && INTVAL (operands[2]) == 255)); 6220 return "dec{b}\t%0"; 6221 } 6222 6223 default: 6224 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ 6225 if (GET_CODE (operands[2]) == CONST_INT 6226 && INTVAL (operands[2]) < 0) 6227 { 6228 operands[2] = GEN_INT (-INTVAL (operands[2])); 6229 return "sub{b}\t{%2, %0|%0, %2}"; 6230 } 6231 return "add{b}\t{%2, %0|%0, %2}"; 6232 } 6233} 6234 [(set (attr "type") 6235 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6236 (const_string "incdec") 6237 (const_string "alu"))) 6238 (set_attr "mode" "QI")]) 6239 6240(define_insn "*addqi_3" 6241 [(set (reg FLAGS_REG) 6242 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni")) 6243 (match_operand:QI 1 "nonimmediate_operand" "%0"))) 6244 (clobber (match_scratch:QI 0 "=q"))] 6245 "ix86_match_ccmode (insn, CCZmode) 6246 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6247{ 6248 switch (get_attr_type (insn)) 6249 { 6250 case TYPE_INCDEC: 6251 if (operands[2] == const1_rtx) 6252 return "inc{b}\t%0"; 6253 else 6254 { 6255 gcc_assert (operands[2] == constm1_rtx 6256 || (GET_CODE (operands[2]) == CONST_INT 6257 && INTVAL (operands[2]) == 255)); 6258 return "dec{b}\t%0"; 6259 } 6260 6261 default: 6262 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ 6263 if (GET_CODE (operands[2]) == CONST_INT 6264 && INTVAL (operands[2]) < 0) 6265 { 6266 operands[2] = GEN_INT (-INTVAL (operands[2])); 6267 return "sub{b}\t{%2, %0|%0, %2}"; 6268 } 6269 return "add{b}\t{%2, %0|%0, %2}"; 6270 } 6271} 6272 [(set (attr "type") 6273 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6274 (const_string "incdec") 6275 (const_string "alu"))) 6276 (set_attr "mode" "QI")]) 6277 6278; See comments above addsi_4 for details. 6279(define_insn "*addqi_4" 6280 [(set (reg FLAGS_REG) 6281 (compare (match_operand:QI 1 "nonimmediate_operand" "0") 6282 (match_operand:QI 2 "const_int_operand" "n"))) 6283 (clobber (match_scratch:QI 0 "=qm"))] 6284 "ix86_match_ccmode (insn, CCGCmode) 6285 && (INTVAL (operands[2]) & 0xff) != 0x80" 6286{ 6287 switch (get_attr_type (insn)) 6288 { 6289 case TYPE_INCDEC: 6290 if (operands[2] == constm1_rtx 6291 || (GET_CODE (operands[2]) == CONST_INT 6292 && INTVAL (operands[2]) == 255)) 6293 return "inc{b}\t%0"; 6294 else 6295 { 6296 gcc_assert (operands[2] == const1_rtx); 6297 return "dec{b}\t%0"; 6298 } 6299 6300 default: 6301 gcc_assert (rtx_equal_p (operands[0], operands[1])); 6302 if (INTVAL (operands[2]) < 0) 6303 { 6304 operands[2] = GEN_INT (-INTVAL (operands[2])); 6305 return "add{b}\t{%2, %0|%0, %2}"; 6306 } 6307 return "sub{b}\t{%2, %0|%0, %2}"; 6308 } 6309} 6310 [(set (attr "type") 6311 (if_then_else (match_operand:HI 2 "incdec_operand" "") 6312 (const_string "incdec") 6313 (const_string "alu"))) 6314 (set_attr "mode" "QI")]) 6315 6316 6317(define_insn "*addqi_5" 6318 [(set (reg FLAGS_REG) 6319 (compare 6320 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 6321 (match_operand:QI 2 "general_operand" "qmni")) 6322 (const_int 0))) 6323 (clobber (match_scratch:QI 0 "=q"))] 6324 "ix86_match_ccmode (insn, CCGOCmode) 6325 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6326{ 6327 switch (get_attr_type (insn)) 6328 { 6329 case TYPE_INCDEC: 6330 if (operands[2] == const1_rtx) 6331 return "inc{b}\t%0"; 6332 else 6333 { 6334 gcc_assert (operands[2] == constm1_rtx 6335 || (GET_CODE (operands[2]) == CONST_INT 6336 && INTVAL (operands[2]) == 255)); 6337 return "dec{b}\t%0"; 6338 } 6339 6340 default: 6341 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ 6342 if (GET_CODE (operands[2]) == CONST_INT 6343 && INTVAL (operands[2]) < 0) 6344 { 6345 operands[2] = GEN_INT (-INTVAL (operands[2])); 6346 return "sub{b}\t{%2, %0|%0, %2}"; 6347 } 6348 return "add{b}\t{%2, %0|%0, %2}"; 6349 } 6350} 6351 [(set (attr "type") 6352 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6353 (const_string "incdec") 6354 (const_string "alu"))) 6355 (set_attr "mode" "QI")]) 6356 6357 6358(define_insn "addqi_ext_1" 6359 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6360 (const_int 8) 6361 (const_int 8)) 6362 (plus:SI 6363 (zero_extract:SI 6364 (match_operand 1 "ext_register_operand" "0") 6365 (const_int 8) 6366 (const_int 8)) 6367 (match_operand:QI 2 "general_operand" "Qmn"))) 6368 (clobber (reg:CC FLAGS_REG))] 6369 "!TARGET_64BIT" 6370{ 6371 switch (get_attr_type (insn)) 6372 { 6373 case TYPE_INCDEC: 6374 if (operands[2] == const1_rtx) 6375 return "inc{b}\t%h0"; 6376 else 6377 { 6378 gcc_assert (operands[2] == constm1_rtx 6379 || (GET_CODE (operands[2]) == CONST_INT 6380 && INTVAL (operands[2]) == 255)); 6381 return "dec{b}\t%h0"; 6382 } 6383 6384 default: 6385 return "add{b}\t{%2, %h0|%h0, %2}"; 6386 } 6387} 6388 [(set (attr "type") 6389 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6390 (const_string "incdec") 6391 (const_string "alu"))) 6392 (set_attr "mode" "QI")]) 6393 6394(define_insn "*addqi_ext_1_rex64" 6395 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6396 (const_int 8) 6397 (const_int 8)) 6398 (plus:SI 6399 (zero_extract:SI 6400 (match_operand 1 "ext_register_operand" "0") 6401 (const_int 8) 6402 (const_int 8)) 6403 (match_operand:QI 2 "nonmemory_operand" "Qn"))) 6404 (clobber (reg:CC FLAGS_REG))] 6405 "TARGET_64BIT" 6406{ 6407 switch (get_attr_type (insn)) 6408 { 6409 case TYPE_INCDEC: 6410 if (operands[2] == const1_rtx) 6411 return "inc{b}\t%h0"; 6412 else 6413 { 6414 gcc_assert (operands[2] == constm1_rtx 6415 || (GET_CODE (operands[2]) == CONST_INT 6416 && INTVAL (operands[2]) == 255)); 6417 return "dec{b}\t%h0"; 6418 } 6419 6420 default: 6421 return "add{b}\t{%2, %h0|%h0, %2}"; 6422 } 6423} 6424 [(set (attr "type") 6425 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6426 (const_string "incdec") 6427 (const_string "alu"))) 6428 (set_attr "mode" "QI")]) 6429 6430(define_insn "*addqi_ext_2" 6431 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6432 (const_int 8) 6433 (const_int 8)) 6434 (plus:SI 6435 (zero_extract:SI 6436 (match_operand 1 "ext_register_operand" "%0") 6437 (const_int 8) 6438 (const_int 8)) 6439 (zero_extract:SI 6440 (match_operand 2 "ext_register_operand" "Q") 6441 (const_int 8) 6442 (const_int 8)))) 6443 (clobber (reg:CC FLAGS_REG))] 6444 "" 6445 "add{b}\t{%h2, %h0|%h0, %h2}" 6446 [(set_attr "type" "alu") 6447 (set_attr "mode" "QI")]) 6448 6449;; The patterns that match these are at the end of this file. 6450 6451(define_expand "addxf3" 6452 [(set (match_operand:XF 0 "register_operand" "") 6453 (plus:XF (match_operand:XF 1 "register_operand" "") 6454 (match_operand:XF 2 "register_operand" "")))] 6455 "TARGET_80387" 6456 "") 6457 6458(define_expand "adddf3" 6459 [(set (match_operand:DF 0 "register_operand" "") 6460 (plus:DF (match_operand:DF 1 "register_operand" "") 6461 (match_operand:DF 2 "nonimmediate_operand" "")))] 6462 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 6463 "") 6464 6465(define_expand "addsf3" 6466 [(set (match_operand:SF 0 "register_operand" "") 6467 (plus:SF (match_operand:SF 1 "register_operand" "") 6468 (match_operand:SF 2 "nonimmediate_operand" "")))] 6469 "TARGET_80387 || TARGET_SSE_MATH" 6470 "") 6471 6472;; Subtract instructions 6473 6474;; %%% splits for subditi3 6475 6476(define_expand "subti3" 6477 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "") 6478 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "") 6479 (match_operand:TI 2 "x86_64_general_operand" ""))) 6480 (clobber (reg:CC FLAGS_REG))])] 6481 "TARGET_64BIT" 6482 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;") 6483 6484(define_insn "*subti3_1" 6485 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o") 6486 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0") 6487 (match_operand:TI 2 "x86_64_general_operand" "roe,re"))) 6488 (clobber (reg:CC FLAGS_REG))] 6489 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)" 6490 "#") 6491 6492(define_split 6493 [(set (match_operand:TI 0 "nonimmediate_operand" "") 6494 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "") 6495 (match_operand:TI 2 "x86_64_general_operand" ""))) 6496 (clobber (reg:CC FLAGS_REG))] 6497 "TARGET_64BIT && reload_completed" 6498 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2))) 6499 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))]) 6500 (parallel [(set (match_dup 3) 6501 (minus:DI (match_dup 4) 6502 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) 6503 (match_dup 5)))) 6504 (clobber (reg:CC FLAGS_REG))])] 6505 "split_ti (operands+0, 1, operands+0, operands+3); 6506 split_ti (operands+1, 1, operands+1, operands+4); 6507 split_ti (operands+2, 1, operands+2, operands+5);") 6508 6509;; %%% splits for subsidi3 6510 6511(define_expand "subdi3" 6512 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 6513 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "") 6514 (match_operand:DI 2 "x86_64_general_operand" ""))) 6515 (clobber (reg:CC FLAGS_REG))])] 6516 "" 6517 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;") 6518 6519(define_insn "*subdi3_1" 6520 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") 6521 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6522 (match_operand:DI 2 "general_operand" "roiF,riF"))) 6523 (clobber (reg:CC FLAGS_REG))] 6524 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" 6525 "#") 6526 6527(define_split 6528 [(set (match_operand:DI 0 "nonimmediate_operand" "") 6529 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "") 6530 (match_operand:DI 2 "general_operand" ""))) 6531 (clobber (reg:CC FLAGS_REG))] 6532 "!TARGET_64BIT && reload_completed" 6533 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2))) 6534 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 6535 (parallel [(set (match_dup 3) 6536 (minus:SI (match_dup 4) 6537 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) 6538 (match_dup 5)))) 6539 (clobber (reg:CC FLAGS_REG))])] 6540 "split_di (operands+0, 1, operands+0, operands+3); 6541 split_di (operands+1, 1, operands+1, operands+4); 6542 split_di (operands+2, 1, operands+2, operands+5);") 6543 6544(define_insn "subdi3_carry_rex64" 6545 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6546 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6547 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "") 6548 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))) 6549 (clobber (reg:CC FLAGS_REG))] 6550 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" 6551 "sbb{q}\t{%2, %0|%0, %2}" 6552 [(set_attr "type" "alu") 6553 (set_attr "pent_pair" "pu") 6554 (set_attr "mode" "DI")]) 6555 6556(define_insn "*subdi_1_rex64" 6557 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6558 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6559 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 6560 (clobber (reg:CC FLAGS_REG))] 6561 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" 6562 "sub{q}\t{%2, %0|%0, %2}" 6563 [(set_attr "type" "alu") 6564 (set_attr "mode" "DI")]) 6565 6566(define_insn "*subdi_2_rex64" 6567 [(set (reg FLAGS_REG) 6568 (compare 6569 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6570 (match_operand:DI 2 "x86_64_general_operand" "re,rm")) 6571 (const_int 0))) 6572 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6573 (minus:DI (match_dup 1) (match_dup 2)))] 6574 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 6575 && ix86_binary_operator_ok (MINUS, DImode, operands)" 6576 "sub{q}\t{%2, %0|%0, %2}" 6577 [(set_attr "type" "alu") 6578 (set_attr "mode" "DI")]) 6579 6580(define_insn "*subdi_3_rex63" 6581 [(set (reg FLAGS_REG) 6582 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0") 6583 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 6584 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6585 (minus:DI (match_dup 1) (match_dup 2)))] 6586 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 6587 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6588 "sub{q}\t{%2, %0|%0, %2}" 6589 [(set_attr "type" "alu") 6590 (set_attr "mode" "DI")]) 6591 6592(define_insn "subqi3_carry" 6593 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 6594 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 6595 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "") 6596 (match_operand:QI 2 "general_operand" "qi,qm")))) 6597 (clobber (reg:CC FLAGS_REG))] 6598 "ix86_binary_operator_ok (MINUS, QImode, operands)" 6599 "sbb{b}\t{%2, %0|%0, %2}" 6600 [(set_attr "type" "alu") 6601 (set_attr "pent_pair" "pu") 6602 (set_attr "mode" "QI")]) 6603 6604(define_insn "subhi3_carry" 6605 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6606 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 6607 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "") 6608 (match_operand:HI 2 "general_operand" "ri,rm")))) 6609 (clobber (reg:CC FLAGS_REG))] 6610 "ix86_binary_operator_ok (MINUS, HImode, operands)" 6611 "sbb{w}\t{%2, %0|%0, %2}" 6612 [(set_attr "type" "alu") 6613 (set_attr "pent_pair" "pu") 6614 (set_attr "mode" "HI")]) 6615 6616(define_insn "subsi3_carry" 6617 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6618 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6619 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 6620 (match_operand:SI 2 "general_operand" "ri,rm")))) 6621 (clobber (reg:CC FLAGS_REG))] 6622 "ix86_binary_operator_ok (MINUS, SImode, operands)" 6623 "sbb{l}\t{%2, %0|%0, %2}" 6624 [(set_attr "type" "alu") 6625 (set_attr "pent_pair" "pu") 6626 (set_attr "mode" "SI")]) 6627 6628(define_insn "subsi3_carry_zext" 6629 [(set (match_operand:DI 0 "register_operand" "=rm,r") 6630 (zero_extend:DI 6631 (minus:SI (match_operand:SI 1 "register_operand" "0,0") 6632 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 6633 (match_operand:SI 2 "general_operand" "ri,rm"))))) 6634 (clobber (reg:CC FLAGS_REG))] 6635 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6636 "sbb{l}\t{%2, %k0|%k0, %2}" 6637 [(set_attr "type" "alu") 6638 (set_attr "pent_pair" "pu") 6639 (set_attr "mode" "SI")]) 6640 6641(define_expand "subsi3" 6642 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 6643 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "") 6644 (match_operand:SI 2 "general_operand" ""))) 6645 (clobber (reg:CC FLAGS_REG))])] 6646 "" 6647 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;") 6648 6649(define_insn "*subsi_1" 6650 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6651 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6652 (match_operand:SI 2 "general_operand" "ri,rm"))) 6653 (clobber (reg:CC FLAGS_REG))] 6654 "ix86_binary_operator_ok (MINUS, SImode, operands)" 6655 "sub{l}\t{%2, %0|%0, %2}" 6656 [(set_attr "type" "alu") 6657 (set_attr "mode" "SI")]) 6658 6659(define_insn "*subsi_1_zext" 6660 [(set (match_operand:DI 0 "register_operand" "=r") 6661 (zero_extend:DI 6662 (minus:SI (match_operand:SI 1 "register_operand" "0") 6663 (match_operand:SI 2 "general_operand" "rim")))) 6664 (clobber (reg:CC FLAGS_REG))] 6665 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6666 "sub{l}\t{%2, %k0|%k0, %2}" 6667 [(set_attr "type" "alu") 6668 (set_attr "mode" "SI")]) 6669 6670(define_insn "*subsi_2" 6671 [(set (reg FLAGS_REG) 6672 (compare 6673 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6674 (match_operand:SI 2 "general_operand" "ri,rm")) 6675 (const_int 0))) 6676 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6677 (minus:SI (match_dup 1) (match_dup 2)))] 6678 "ix86_match_ccmode (insn, CCGOCmode) 6679 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6680 "sub{l}\t{%2, %0|%0, %2}" 6681 [(set_attr "type" "alu") 6682 (set_attr "mode" "SI")]) 6683 6684(define_insn "*subsi_2_zext" 6685 [(set (reg FLAGS_REG) 6686 (compare 6687 (minus:SI (match_operand:SI 1 "register_operand" "0") 6688 (match_operand:SI 2 "general_operand" "rim")) 6689 (const_int 0))) 6690 (set (match_operand:DI 0 "register_operand" "=r") 6691 (zero_extend:DI 6692 (minus:SI (match_dup 1) 6693 (match_dup 2))))] 6694 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 6695 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6696 "sub{l}\t{%2, %k0|%k0, %2}" 6697 [(set_attr "type" "alu") 6698 (set_attr "mode" "SI")]) 6699 6700(define_insn "*subsi_3" 6701 [(set (reg FLAGS_REG) 6702 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0") 6703 (match_operand:SI 2 "general_operand" "ri,rm"))) 6704 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6705 (minus:SI (match_dup 1) (match_dup 2)))] 6706 "ix86_match_ccmode (insn, CCmode) 6707 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6708 "sub{l}\t{%2, %0|%0, %2}" 6709 [(set_attr "type" "alu") 6710 (set_attr "mode" "SI")]) 6711 6712(define_insn "*subsi_3_zext" 6713 [(set (reg FLAGS_REG) 6714 (compare (match_operand:SI 1 "register_operand" "0") 6715 (match_operand:SI 2 "general_operand" "rim"))) 6716 (set (match_operand:DI 0 "register_operand" "=r") 6717 (zero_extend:DI 6718 (minus:SI (match_dup 1) 6719 (match_dup 2))))] 6720 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 6721 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6722 "sub{l}\t{%2, %1|%1, %2}" 6723 [(set_attr "type" "alu") 6724 (set_attr "mode" "DI")]) 6725 6726(define_expand "subhi3" 6727 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 6728 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "") 6729 (match_operand:HI 2 "general_operand" ""))) 6730 (clobber (reg:CC FLAGS_REG))])] 6731 "TARGET_HIMODE_MATH" 6732 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;") 6733 6734(define_insn "*subhi_1" 6735 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6736 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 6737 (match_operand:HI 2 "general_operand" "ri,rm"))) 6738 (clobber (reg:CC FLAGS_REG))] 6739 "ix86_binary_operator_ok (MINUS, HImode, operands)" 6740 "sub{w}\t{%2, %0|%0, %2}" 6741 [(set_attr "type" "alu") 6742 (set_attr "mode" "HI")]) 6743 6744(define_insn "*subhi_2" 6745 [(set (reg FLAGS_REG) 6746 (compare 6747 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 6748 (match_operand:HI 2 "general_operand" "ri,rm")) 6749 (const_int 0))) 6750 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6751 (minus:HI (match_dup 1) (match_dup 2)))] 6752 "ix86_match_ccmode (insn, CCGOCmode) 6753 && ix86_binary_operator_ok (MINUS, HImode, operands)" 6754 "sub{w}\t{%2, %0|%0, %2}" 6755 [(set_attr "type" "alu") 6756 (set_attr "mode" "HI")]) 6757 6758(define_insn "*subhi_3" 6759 [(set (reg FLAGS_REG) 6760 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0") 6761 (match_operand:HI 2 "general_operand" "ri,rm"))) 6762 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6763 (minus:HI (match_dup 1) (match_dup 2)))] 6764 "ix86_match_ccmode (insn, CCmode) 6765 && ix86_binary_operator_ok (MINUS, HImode, operands)" 6766 "sub{w}\t{%2, %0|%0, %2}" 6767 [(set_attr "type" "alu") 6768 (set_attr "mode" "HI")]) 6769 6770(define_expand "subqi3" 6771 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") 6772 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "") 6773 (match_operand:QI 2 "general_operand" ""))) 6774 (clobber (reg:CC FLAGS_REG))])] 6775 "TARGET_QIMODE_MATH" 6776 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;") 6777 6778(define_insn "*subqi_1" 6779 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 6780 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 6781 (match_operand:QI 2 "general_operand" "qn,qmn"))) 6782 (clobber (reg:CC FLAGS_REG))] 6783 "ix86_binary_operator_ok (MINUS, QImode, operands)" 6784 "sub{b}\t{%2, %0|%0, %2}" 6785 [(set_attr "type" "alu") 6786 (set_attr "mode" "QI")]) 6787 6788(define_insn "*subqi_1_slp" 6789 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 6790 (minus:QI (match_dup 0) 6791 (match_operand:QI 1 "general_operand" "qn,qmn"))) 6792 (clobber (reg:CC FLAGS_REG))] 6793 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 6794 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 6795 "sub{b}\t{%1, %0|%0, %1}" 6796 [(set_attr "type" "alu1") 6797 (set_attr "mode" "QI")]) 6798 6799(define_insn "*subqi_2" 6800 [(set (reg FLAGS_REG) 6801 (compare 6802 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 6803 (match_operand:QI 2 "general_operand" "qi,qm")) 6804 (const_int 0))) 6805 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q") 6806 (minus:HI (match_dup 1) (match_dup 2)))] 6807 "ix86_match_ccmode (insn, CCGOCmode) 6808 && ix86_binary_operator_ok (MINUS, QImode, operands)" 6809 "sub{b}\t{%2, %0|%0, %2}" 6810 [(set_attr "type" "alu") 6811 (set_attr "mode" "QI")]) 6812 6813(define_insn "*subqi_3" 6814 [(set (reg FLAGS_REG) 6815 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0") 6816 (match_operand:QI 2 "general_operand" "qi,qm"))) 6817 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q") 6818 (minus:HI (match_dup 1) (match_dup 2)))] 6819 "ix86_match_ccmode (insn, CCmode) 6820 && ix86_binary_operator_ok (MINUS, QImode, operands)" 6821 "sub{b}\t{%2, %0|%0, %2}" 6822 [(set_attr "type" "alu") 6823 (set_attr "mode" "QI")]) 6824 6825;; The patterns that match these are at the end of this file. 6826 6827(define_expand "subxf3" 6828 [(set (match_operand:XF 0 "register_operand" "") 6829 (minus:XF (match_operand:XF 1 "register_operand" "") 6830 (match_operand:XF 2 "register_operand" "")))] 6831 "TARGET_80387" 6832 "") 6833 6834(define_expand "subdf3" 6835 [(set (match_operand:DF 0 "register_operand" "") 6836 (minus:DF (match_operand:DF 1 "register_operand" "") 6837 (match_operand:DF 2 "nonimmediate_operand" "")))] 6838 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 6839 "") 6840 6841(define_expand "subsf3" 6842 [(set (match_operand:SF 0 "register_operand" "") 6843 (minus:SF (match_operand:SF 1 "register_operand" "") 6844 (match_operand:SF 2 "nonimmediate_operand" "")))] 6845 "TARGET_80387 || TARGET_SSE_MATH" 6846 "") 6847 6848;; Multiply instructions 6849 6850(define_expand "muldi3" 6851 [(parallel [(set (match_operand:DI 0 "register_operand" "") 6852 (mult:DI (match_operand:DI 1 "register_operand" "") 6853 (match_operand:DI 2 "x86_64_general_operand" ""))) 6854 (clobber (reg:CC FLAGS_REG))])] 6855 "TARGET_64BIT" 6856 "") 6857 6858(define_insn "*muldi3_1_rex64" 6859 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 6860 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0") 6861 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr"))) 6862 (clobber (reg:CC FLAGS_REG))] 6863 "TARGET_64BIT 6864 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6865 "@ 6866 imul{q}\t{%2, %1, %0|%0, %1, %2} 6867 imul{q}\t{%2, %1, %0|%0, %1, %2} 6868 imul{q}\t{%2, %0|%0, %2}" 6869 [(set_attr "type" "imul") 6870 (set_attr "prefix_0f" "0,0,1") 6871 (set (attr "athlon_decode") 6872 (cond [(eq_attr "cpu" "athlon") 6873 (const_string "vector") 6874 (eq_attr "alternative" "1") 6875 (const_string "vector") 6876 (and (eq_attr "alternative" "2") 6877 (match_operand 1 "memory_operand" "")) 6878 (const_string "vector")] 6879 (const_string "direct"))) 6880 (set_attr "mode" "DI")]) 6881 6882(define_expand "mulsi3" 6883 [(parallel [(set (match_operand:SI 0 "register_operand" "") 6884 (mult:SI (match_operand:SI 1 "register_operand" "") 6885 (match_operand:SI 2 "general_operand" ""))) 6886 (clobber (reg:CC FLAGS_REG))])] 6887 "" 6888 "") 6889 6890(define_insn "*mulsi3_1" 6891 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 6892 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") 6893 (match_operand:SI 2 "general_operand" "K,i,mr"))) 6894 (clobber (reg:CC FLAGS_REG))] 6895 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 6896 "@ 6897 imul{l}\t{%2, %1, %0|%0, %1, %2} 6898 imul{l}\t{%2, %1, %0|%0, %1, %2} 6899 imul{l}\t{%2, %0|%0, %2}" 6900 [(set_attr "type" "imul") 6901 (set_attr "prefix_0f" "0,0,1") 6902 (set (attr "athlon_decode") 6903 (cond [(eq_attr "cpu" "athlon") 6904 (const_string "vector") 6905 (eq_attr "alternative" "1") 6906 (const_string "vector") 6907 (and (eq_attr "alternative" "2") 6908 (match_operand 1 "memory_operand" "")) 6909 (const_string "vector")] 6910 (const_string "direct"))) 6911 (set_attr "mode" "SI")]) 6912 6913(define_insn "*mulsi3_1_zext" 6914 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 6915 (zero_extend:DI 6916 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") 6917 (match_operand:SI 2 "general_operand" "K,i,mr")))) 6918 (clobber (reg:CC FLAGS_REG))] 6919 "TARGET_64BIT 6920 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6921 "@ 6922 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6923 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6924 imul{l}\t{%2, %k0|%k0, %2}" 6925 [(set_attr "type" "imul") 6926 (set_attr "prefix_0f" "0,0,1") 6927 (set (attr "athlon_decode") 6928 (cond [(eq_attr "cpu" "athlon") 6929 (const_string "vector") 6930 (eq_attr "alternative" "1") 6931 (const_string "vector") 6932 (and (eq_attr "alternative" "2") 6933 (match_operand 1 "memory_operand" "")) 6934 (const_string "vector")] 6935 (const_string "direct"))) 6936 (set_attr "mode" "SI")]) 6937 6938(define_expand "mulhi3" 6939 [(parallel [(set (match_operand:HI 0 "register_operand" "") 6940 (mult:HI (match_operand:HI 1 "register_operand" "") 6941 (match_operand:HI 2 "general_operand" ""))) 6942 (clobber (reg:CC FLAGS_REG))])] 6943 "TARGET_HIMODE_MATH" 6944 "") 6945 6946(define_insn "*mulhi3_1" 6947 [(set (match_operand:HI 0 "register_operand" "=r,r,r") 6948 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0") 6949 (match_operand:HI 2 "general_operand" "K,i,mr"))) 6950 (clobber (reg:CC FLAGS_REG))] 6951 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 6952 "@ 6953 imul{w}\t{%2, %1, %0|%0, %1, %2} 6954 imul{w}\t{%2, %1, %0|%0, %1, %2} 6955 imul{w}\t{%2, %0|%0, %2}" 6956 [(set_attr "type" "imul") 6957 (set_attr "prefix_0f" "0,0,1") 6958 (set (attr "athlon_decode") 6959 (cond [(eq_attr "cpu" "athlon") 6960 (const_string "vector") 6961 (eq_attr "alternative" "1,2") 6962 (const_string "vector")] 6963 (const_string "direct"))) 6964 (set_attr "mode" "HI")]) 6965 6966(define_expand "mulqi3" 6967 [(parallel [(set (match_operand:QI 0 "register_operand" "") 6968 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "") 6969 (match_operand:QI 2 "register_operand" ""))) 6970 (clobber (reg:CC FLAGS_REG))])] 6971 "TARGET_QIMODE_MATH" 6972 "") 6973 6974(define_insn "*mulqi3_1" 6975 [(set (match_operand:QI 0 "register_operand" "=a") 6976 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 6977 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 6978 (clobber (reg:CC FLAGS_REG))] 6979 "TARGET_QIMODE_MATH 6980 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6981 "mul{b}\t%2" 6982 [(set_attr "type" "imul") 6983 (set_attr "length_immediate" "0") 6984 (set (attr "athlon_decode") 6985 (if_then_else (eq_attr "cpu" "athlon") 6986 (const_string "vector") 6987 (const_string "direct"))) 6988 (set_attr "mode" "QI")]) 6989 6990(define_expand "umulqihi3" 6991 [(parallel [(set (match_operand:HI 0 "register_operand" "") 6992 (mult:HI (zero_extend:HI 6993 (match_operand:QI 1 "nonimmediate_operand" "")) 6994 (zero_extend:HI 6995 (match_operand:QI 2 "register_operand" "")))) 6996 (clobber (reg:CC FLAGS_REG))])] 6997 "TARGET_QIMODE_MATH" 6998 "") 6999 7000(define_insn "*umulqihi3_1" 7001 [(set (match_operand:HI 0 "register_operand" "=a") 7002 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0")) 7003 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm")))) 7004 (clobber (reg:CC FLAGS_REG))] 7005 "TARGET_QIMODE_MATH 7006 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7007 "mul{b}\t%2" 7008 [(set_attr "type" "imul") 7009 (set_attr "length_immediate" "0") 7010 (set (attr "athlon_decode") 7011 (if_then_else (eq_attr "cpu" "athlon") 7012 (const_string "vector") 7013 (const_string "direct"))) 7014 (set_attr "mode" "QI")]) 7015 7016(define_expand "mulqihi3" 7017 [(parallel [(set (match_operand:HI 0 "register_operand" "") 7018 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")) 7019 (sign_extend:HI (match_operand:QI 2 "register_operand" "")))) 7020 (clobber (reg:CC FLAGS_REG))])] 7021 "TARGET_QIMODE_MATH" 7022 "") 7023 7024(define_insn "*mulqihi3_insn" 7025 [(set (match_operand:HI 0 "register_operand" "=a") 7026 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0")) 7027 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm")))) 7028 (clobber (reg:CC FLAGS_REG))] 7029 "TARGET_QIMODE_MATH 7030 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7031 "imul{b}\t%2" 7032 [(set_attr "type" "imul") 7033 (set_attr "length_immediate" "0") 7034 (set (attr "athlon_decode") 7035 (if_then_else (eq_attr "cpu" "athlon") 7036 (const_string "vector") 7037 (const_string "direct"))) 7038 (set_attr "mode" "QI")]) 7039 7040(define_expand "umulditi3" 7041 [(parallel [(set (match_operand:TI 0 "register_operand" "") 7042 (mult:TI (zero_extend:TI 7043 (match_operand:DI 1 "nonimmediate_operand" "")) 7044 (zero_extend:TI 7045 (match_operand:DI 2 "register_operand" "")))) 7046 (clobber (reg:CC FLAGS_REG))])] 7047 "TARGET_64BIT" 7048 "") 7049 7050(define_insn "*umulditi3_insn" 7051 [(set (match_operand:TI 0 "register_operand" "=A") 7052 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0")) 7053 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm")))) 7054 (clobber (reg:CC FLAGS_REG))] 7055 "TARGET_64BIT 7056 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7057 "mul{q}\t%2" 7058 [(set_attr "type" "imul") 7059 (set_attr "length_immediate" "0") 7060 (set (attr "athlon_decode") 7061 (if_then_else (eq_attr "cpu" "athlon") 7062 (const_string "vector") 7063 (const_string "double"))) 7064 (set_attr "mode" "DI")]) 7065 7066;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers 7067(define_expand "umulsidi3" 7068 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7069 (mult:DI (zero_extend:DI 7070 (match_operand:SI 1 "nonimmediate_operand" "")) 7071 (zero_extend:DI 7072 (match_operand:SI 2 "register_operand" "")))) 7073 (clobber (reg:CC FLAGS_REG))])] 7074 "!TARGET_64BIT" 7075 "") 7076 7077(define_insn "*umulsidi3_insn" 7078 [(set (match_operand:DI 0 "register_operand" "=A") 7079 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0")) 7080 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))) 7081 (clobber (reg:CC FLAGS_REG))] 7082 "!TARGET_64BIT 7083 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7084 "mul{l}\t%2" 7085 [(set_attr "type" "imul") 7086 (set_attr "length_immediate" "0") 7087 (set (attr "athlon_decode") 7088 (if_then_else (eq_attr "cpu" "athlon") 7089 (const_string "vector") 7090 (const_string "double"))) 7091 (set_attr "mode" "SI")]) 7092 7093(define_expand "mulditi3" 7094 [(parallel [(set (match_operand:TI 0 "register_operand" "") 7095 (mult:TI (sign_extend:TI 7096 (match_operand:DI 1 "nonimmediate_operand" "")) 7097 (sign_extend:TI 7098 (match_operand:DI 2 "register_operand" "")))) 7099 (clobber (reg:CC FLAGS_REG))])] 7100 "TARGET_64BIT" 7101 "") 7102 7103(define_insn "*mulditi3_insn" 7104 [(set (match_operand:TI 0 "register_operand" "=A") 7105 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0")) 7106 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm")))) 7107 (clobber (reg:CC FLAGS_REG))] 7108 "TARGET_64BIT 7109 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7110 "imul{q}\t%2" 7111 [(set_attr "type" "imul") 7112 (set_attr "length_immediate" "0") 7113 (set (attr "athlon_decode") 7114 (if_then_else (eq_attr "cpu" "athlon") 7115 (const_string "vector") 7116 (const_string "double"))) 7117 (set_attr "mode" "DI")]) 7118 7119(define_expand "mulsidi3" 7120 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7121 (mult:DI (sign_extend:DI 7122 (match_operand:SI 1 "nonimmediate_operand" "")) 7123 (sign_extend:DI 7124 (match_operand:SI 2 "register_operand" "")))) 7125 (clobber (reg:CC FLAGS_REG))])] 7126 "!TARGET_64BIT" 7127 "") 7128 7129(define_insn "*mulsidi3_insn" 7130 [(set (match_operand:DI 0 "register_operand" "=A") 7131 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0")) 7132 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))) 7133 (clobber (reg:CC FLAGS_REG))] 7134 "!TARGET_64BIT 7135 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7136 "imul{l}\t%2" 7137 [(set_attr "type" "imul") 7138 (set_attr "length_immediate" "0") 7139 (set (attr "athlon_decode") 7140 (if_then_else (eq_attr "cpu" "athlon") 7141 (const_string "vector") 7142 (const_string "double"))) 7143 (set_attr "mode" "SI")]) 7144 7145(define_expand "umuldi3_highpart" 7146 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7147 (truncate:DI 7148 (lshiftrt:TI 7149 (mult:TI (zero_extend:TI 7150 (match_operand:DI 1 "nonimmediate_operand" "")) 7151 (zero_extend:TI 7152 (match_operand:DI 2 "register_operand" ""))) 7153 (const_int 64)))) 7154 (clobber (match_scratch:DI 3 "")) 7155 (clobber (reg:CC FLAGS_REG))])] 7156 "TARGET_64BIT" 7157 "") 7158 7159(define_insn "*umuldi3_highpart_rex64" 7160 [(set (match_operand:DI 0 "register_operand" "=d") 7161 (truncate:DI 7162 (lshiftrt:TI 7163 (mult:TI (zero_extend:TI 7164 (match_operand:DI 1 "nonimmediate_operand" "%a")) 7165 (zero_extend:TI 7166 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7167 (const_int 64)))) 7168 (clobber (match_scratch:DI 3 "=1")) 7169 (clobber (reg:CC FLAGS_REG))] 7170 "TARGET_64BIT 7171 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7172 "mul{q}\t%2" 7173 [(set_attr "type" "imul") 7174 (set_attr "length_immediate" "0") 7175 (set (attr "athlon_decode") 7176 (if_then_else (eq_attr "cpu" "athlon") 7177 (const_string "vector") 7178 (const_string "double"))) 7179 (set_attr "mode" "DI")]) 7180 7181(define_expand "umulsi3_highpart" 7182 [(parallel [(set (match_operand:SI 0 "register_operand" "") 7183 (truncate:SI 7184 (lshiftrt:DI 7185 (mult:DI (zero_extend:DI 7186 (match_operand:SI 1 "nonimmediate_operand" "")) 7187 (zero_extend:DI 7188 (match_operand:SI 2 "register_operand" ""))) 7189 (const_int 32)))) 7190 (clobber (match_scratch:SI 3 "")) 7191 (clobber (reg:CC FLAGS_REG))])] 7192 "" 7193 "") 7194 7195(define_insn "*umulsi3_highpart_insn" 7196 [(set (match_operand:SI 0 "register_operand" "=d") 7197 (truncate:SI 7198 (lshiftrt:DI 7199 (mult:DI (zero_extend:DI 7200 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7201 (zero_extend:DI 7202 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7203 (const_int 32)))) 7204 (clobber (match_scratch:SI 3 "=1")) 7205 (clobber (reg:CC FLAGS_REG))] 7206 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 7207 "mul{l}\t%2" 7208 [(set_attr "type" "imul") 7209 (set_attr "length_immediate" "0") 7210 (set (attr "athlon_decode") 7211 (if_then_else (eq_attr "cpu" "athlon") 7212 (const_string "vector") 7213 (const_string "double"))) 7214 (set_attr "mode" "SI")]) 7215 7216(define_insn "*umulsi3_highpart_zext" 7217 [(set (match_operand:DI 0 "register_operand" "=d") 7218 (zero_extend:DI (truncate:SI 7219 (lshiftrt:DI 7220 (mult:DI (zero_extend:DI 7221 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7222 (zero_extend:DI 7223 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7224 (const_int 32))))) 7225 (clobber (match_scratch:SI 3 "=1")) 7226 (clobber (reg:CC FLAGS_REG))] 7227 "TARGET_64BIT 7228 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7229 "mul{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 "mode" "SI")]) 7237 7238(define_expand "smuldi3_highpart" 7239 [(parallel [(set (match_operand:DI 0 "register_operand" "=d") 7240 (truncate:DI 7241 (lshiftrt:TI 7242 (mult:TI (sign_extend:TI 7243 (match_operand:DI 1 "nonimmediate_operand" "")) 7244 (sign_extend:TI 7245 (match_operand:DI 2 "register_operand" ""))) 7246 (const_int 64)))) 7247 (clobber (match_scratch:DI 3 "")) 7248 (clobber (reg:CC FLAGS_REG))])] 7249 "TARGET_64BIT" 7250 "") 7251 7252(define_insn "*smuldi3_highpart_rex64" 7253 [(set (match_operand:DI 0 "register_operand" "=d") 7254 (truncate:DI 7255 (lshiftrt:TI 7256 (mult:TI (sign_extend:TI 7257 (match_operand:DI 1 "nonimmediate_operand" "%a")) 7258 (sign_extend:TI 7259 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7260 (const_int 64)))) 7261 (clobber (match_scratch:DI 3 "=1")) 7262 (clobber (reg:CC FLAGS_REG))] 7263 "TARGET_64BIT 7264 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7265 "imul{q}\t%2" 7266 [(set_attr "type" "imul") 7267 (set (attr "athlon_decode") 7268 (if_then_else (eq_attr "cpu" "athlon") 7269 (const_string "vector") 7270 (const_string "double"))) 7271 (set_attr "mode" "DI")]) 7272 7273(define_expand "smulsi3_highpart" 7274 [(parallel [(set (match_operand:SI 0 "register_operand" "") 7275 (truncate:SI 7276 (lshiftrt:DI 7277 (mult:DI (sign_extend:DI 7278 (match_operand:SI 1 "nonimmediate_operand" "")) 7279 (sign_extend:DI 7280 (match_operand:SI 2 "register_operand" ""))) 7281 (const_int 32)))) 7282 (clobber (match_scratch:SI 3 "")) 7283 (clobber (reg:CC FLAGS_REG))])] 7284 "" 7285 "") 7286 7287(define_insn "*smulsi3_highpart_insn" 7288 [(set (match_operand:SI 0 "register_operand" "=d") 7289 (truncate:SI 7290 (lshiftrt:DI 7291 (mult:DI (sign_extend:DI 7292 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7293 (sign_extend:DI 7294 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7295 (const_int 32)))) 7296 (clobber (match_scratch:SI 3 "=1")) 7297 (clobber (reg:CC FLAGS_REG))] 7298 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 7299 "imul{l}\t%2" 7300 [(set_attr "type" "imul") 7301 (set (attr "athlon_decode") 7302 (if_then_else (eq_attr "cpu" "athlon") 7303 (const_string "vector") 7304 (const_string "double"))) 7305 (set_attr "mode" "SI")]) 7306 7307(define_insn "*smulsi3_highpart_zext" 7308 [(set (match_operand:DI 0 "register_operand" "=d") 7309 (zero_extend:DI (truncate:SI 7310 (lshiftrt:DI 7311 (mult:DI (sign_extend:DI 7312 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7313 (sign_extend:DI 7314 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7315 (const_int 32))))) 7316 (clobber (match_scratch:SI 3 "=1")) 7317 (clobber (reg:CC FLAGS_REG))] 7318 "TARGET_64BIT 7319 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7320 "imul{l}\t%2" 7321 [(set_attr "type" "imul") 7322 (set (attr "athlon_decode") 7323 (if_then_else (eq_attr "cpu" "athlon") 7324 (const_string "vector") 7325 (const_string "double"))) 7326 (set_attr "mode" "SI")]) 7327 7328;; The patterns that match these are at the end of this file. 7329 7330(define_expand "mulxf3" 7331 [(set (match_operand:XF 0 "register_operand" "") 7332 (mult:XF (match_operand:XF 1 "register_operand" "") 7333 (match_operand:XF 2 "register_operand" "")))] 7334 "TARGET_80387" 7335 "") 7336 7337(define_expand "muldf3" 7338 [(set (match_operand:DF 0 "register_operand" "") 7339 (mult:DF (match_operand:DF 1 "register_operand" "") 7340 (match_operand:DF 2 "nonimmediate_operand" "")))] 7341 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 7342 "") 7343 7344(define_expand "mulsf3" 7345 [(set (match_operand:SF 0 "register_operand" "") 7346 (mult:SF (match_operand:SF 1 "register_operand" "") 7347 (match_operand:SF 2 "nonimmediate_operand" "")))] 7348 "TARGET_80387 || TARGET_SSE_MATH" 7349 "") 7350 7351;; Divide instructions 7352 7353(define_insn "divqi3" 7354 [(set (match_operand:QI 0 "register_operand" "=a") 7355 (div:QI (match_operand:HI 1 "register_operand" "0") 7356 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 7357 (clobber (reg:CC FLAGS_REG))] 7358 "TARGET_QIMODE_MATH" 7359 "idiv{b}\t%2" 7360 [(set_attr "type" "idiv") 7361 (set_attr "mode" "QI")]) 7362 7363(define_insn "udivqi3" 7364 [(set (match_operand:QI 0 "register_operand" "=a") 7365 (udiv:QI (match_operand:HI 1 "register_operand" "0") 7366 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 7367 (clobber (reg:CC FLAGS_REG))] 7368 "TARGET_QIMODE_MATH" 7369 "div{b}\t%2" 7370 [(set_attr "type" "idiv") 7371 (set_attr "mode" "QI")]) 7372 7373;; The patterns that match these are at the end of this file. 7374 7375(define_expand "divxf3" 7376 [(set (match_operand:XF 0 "register_operand" "") 7377 (div:XF (match_operand:XF 1 "register_operand" "") 7378 (match_operand:XF 2 "register_operand" "")))] 7379 "TARGET_80387" 7380 "") 7381 7382(define_expand "divdf3" 7383 [(set (match_operand:DF 0 "register_operand" "") 7384 (div:DF (match_operand:DF 1 "register_operand" "") 7385 (match_operand:DF 2 "nonimmediate_operand" "")))] 7386 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 7387 "") 7388 7389(define_expand "divsf3" 7390 [(set (match_operand:SF 0 "register_operand" "") 7391 (div:SF (match_operand:SF 1 "register_operand" "") 7392 (match_operand:SF 2 "nonimmediate_operand" "")))] 7393 "TARGET_80387 || TARGET_SSE_MATH" 7394 "") 7395 7396;; Remainder instructions. 7397 7398(define_expand "divmoddi4" 7399 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7400 (div:DI (match_operand:DI 1 "register_operand" "") 7401 (match_operand:DI 2 "nonimmediate_operand" ""))) 7402 (set (match_operand:DI 3 "register_operand" "") 7403 (mod:DI (match_dup 1) (match_dup 2))) 7404 (clobber (reg:CC FLAGS_REG))])] 7405 "TARGET_64BIT" 7406 "") 7407 7408;; Allow to come the parameter in eax or edx to avoid extra moves. 7409;; Penalize eax case slightly because it results in worse scheduling 7410;; of code. 7411(define_insn "*divmoddi4_nocltd_rex64" 7412 [(set (match_operand:DI 0 "register_operand" "=&a,?a") 7413 (div:DI (match_operand:DI 2 "register_operand" "1,0") 7414 (match_operand:DI 3 "nonimmediate_operand" "rm,rm"))) 7415 (set (match_operand:DI 1 "register_operand" "=&d,&d") 7416 (mod:DI (match_dup 2) (match_dup 3))) 7417 (clobber (reg:CC FLAGS_REG))] 7418 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD" 7419 "#" 7420 [(set_attr "type" "multi")]) 7421 7422(define_insn "*divmoddi4_cltd_rex64" 7423 [(set (match_operand:DI 0 "register_operand" "=a") 7424 (div:DI (match_operand:DI 2 "register_operand" "a") 7425 (match_operand:DI 3 "nonimmediate_operand" "rm"))) 7426 (set (match_operand:DI 1 "register_operand" "=&d") 7427 (mod:DI (match_dup 2) (match_dup 3))) 7428 (clobber (reg:CC FLAGS_REG))] 7429 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)" 7430 "#" 7431 [(set_attr "type" "multi")]) 7432 7433(define_insn "*divmoddi_noext_rex64" 7434 [(set (match_operand:DI 0 "register_operand" "=a") 7435 (div:DI (match_operand:DI 1 "register_operand" "0") 7436 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7437 (set (match_operand:DI 3 "register_operand" "=d") 7438 (mod:DI (match_dup 1) (match_dup 2))) 7439 (use (match_operand:DI 4 "register_operand" "3")) 7440 (clobber (reg:CC FLAGS_REG))] 7441 "TARGET_64BIT" 7442 "idiv{q}\t%2" 7443 [(set_attr "type" "idiv") 7444 (set_attr "mode" "DI")]) 7445 7446(define_split 7447 [(set (match_operand:DI 0 "register_operand" "") 7448 (div:DI (match_operand:DI 1 "register_operand" "") 7449 (match_operand:DI 2 "nonimmediate_operand" ""))) 7450 (set (match_operand:DI 3 "register_operand" "") 7451 (mod:DI (match_dup 1) (match_dup 2))) 7452 (clobber (reg:CC FLAGS_REG))] 7453 "TARGET_64BIT && reload_completed" 7454 [(parallel [(set (match_dup 3) 7455 (ashiftrt:DI (match_dup 4) (const_int 63))) 7456 (clobber (reg:CC FLAGS_REG))]) 7457 (parallel [(set (match_dup 0) 7458 (div:DI (reg:DI 0) (match_dup 2))) 7459 (set (match_dup 3) 7460 (mod:DI (reg:DI 0) (match_dup 2))) 7461 (use (match_dup 3)) 7462 (clobber (reg:CC FLAGS_REG))])] 7463{ 7464 /* Avoid use of cltd in favor of a mov+shift. */ 7465 if (!TARGET_USE_CLTD && !optimize_size) 7466 { 7467 if (true_regnum (operands[1])) 7468 emit_move_insn (operands[0], operands[1]); 7469 else 7470 emit_move_insn (operands[3], operands[1]); 7471 operands[4] = operands[3]; 7472 } 7473 else 7474 { 7475 gcc_assert (!true_regnum (operands[1])); 7476 operands[4] = operands[1]; 7477 } 7478}) 7479 7480 7481(define_expand "divmodsi4" 7482 [(parallel [(set (match_operand:SI 0 "register_operand" "") 7483 (div:SI (match_operand:SI 1 "register_operand" "") 7484 (match_operand:SI 2 "nonimmediate_operand" ""))) 7485 (set (match_operand:SI 3 "register_operand" "") 7486 (mod:SI (match_dup 1) (match_dup 2))) 7487 (clobber (reg:CC FLAGS_REG))])] 7488 "" 7489 "") 7490 7491;; Allow to come the parameter in eax or edx to avoid extra moves. 7492;; Penalize eax case slightly because it results in worse scheduling 7493;; of code. 7494(define_insn "*divmodsi4_nocltd" 7495 [(set (match_operand:SI 0 "register_operand" "=&a,?a") 7496 (div:SI (match_operand:SI 2 "register_operand" "1,0") 7497 (match_operand:SI 3 "nonimmediate_operand" "rm,rm"))) 7498 (set (match_operand:SI 1 "register_operand" "=&d,&d") 7499 (mod:SI (match_dup 2) (match_dup 3))) 7500 (clobber (reg:CC FLAGS_REG))] 7501 "!optimize_size && !TARGET_USE_CLTD" 7502 "#" 7503 [(set_attr "type" "multi")]) 7504 7505(define_insn "*divmodsi4_cltd" 7506 [(set (match_operand:SI 0 "register_operand" "=a") 7507 (div:SI (match_operand:SI 2 "register_operand" "a") 7508 (match_operand:SI 3 "nonimmediate_operand" "rm"))) 7509 (set (match_operand:SI 1 "register_operand" "=&d") 7510 (mod:SI (match_dup 2) (match_dup 3))) 7511 (clobber (reg:CC FLAGS_REG))] 7512 "optimize_size || TARGET_USE_CLTD" 7513 "#" 7514 [(set_attr "type" "multi")]) 7515 7516(define_insn "*divmodsi_noext" 7517 [(set (match_operand:SI 0 "register_operand" "=a") 7518 (div:SI (match_operand:SI 1 "register_operand" "0") 7519 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7520 (set (match_operand:SI 3 "register_operand" "=d") 7521 (mod:SI (match_dup 1) (match_dup 2))) 7522 (use (match_operand:SI 4 "register_operand" "3")) 7523 (clobber (reg:CC FLAGS_REG))] 7524 "" 7525 "idiv{l}\t%2" 7526 [(set_attr "type" "idiv") 7527 (set_attr "mode" "SI")]) 7528 7529(define_split 7530 [(set (match_operand:SI 0 "register_operand" "") 7531 (div:SI (match_operand:SI 1 "register_operand" "") 7532 (match_operand:SI 2 "nonimmediate_operand" ""))) 7533 (set (match_operand:SI 3 "register_operand" "") 7534 (mod:SI (match_dup 1) (match_dup 2))) 7535 (clobber (reg:CC FLAGS_REG))] 7536 "reload_completed" 7537 [(parallel [(set (match_dup 3) 7538 (ashiftrt:SI (match_dup 4) (const_int 31))) 7539 (clobber (reg:CC FLAGS_REG))]) 7540 (parallel [(set (match_dup 0) 7541 (div:SI (reg:SI 0) (match_dup 2))) 7542 (set (match_dup 3) 7543 (mod:SI (reg:SI 0) (match_dup 2))) 7544 (use (match_dup 3)) 7545 (clobber (reg:CC FLAGS_REG))])] 7546{ 7547 /* Avoid use of cltd in favor of a mov+shift. */ 7548 if (!TARGET_USE_CLTD && !optimize_size) 7549 { 7550 if (true_regnum (operands[1])) 7551 emit_move_insn (operands[0], operands[1]); 7552 else 7553 emit_move_insn (operands[3], operands[1]); 7554 operands[4] = operands[3]; 7555 } 7556 else 7557 { 7558 gcc_assert (!true_regnum (operands[1])); 7559 operands[4] = operands[1]; 7560 } 7561}) 7562;; %%% Split me. 7563(define_insn "divmodhi4" 7564 [(set (match_operand:HI 0 "register_operand" "=a") 7565 (div:HI (match_operand:HI 1 "register_operand" "0") 7566 (match_operand:HI 2 "nonimmediate_operand" "rm"))) 7567 (set (match_operand:HI 3 "register_operand" "=&d") 7568 (mod:HI (match_dup 1) (match_dup 2))) 7569 (clobber (reg:CC FLAGS_REG))] 7570 "TARGET_HIMODE_MATH" 7571 "cwtd\;idiv{w}\t%2" 7572 [(set_attr "type" "multi") 7573 (set_attr "length_immediate" "0") 7574 (set_attr "mode" "SI")]) 7575 7576(define_insn "udivmoddi4" 7577 [(set (match_operand:DI 0 "register_operand" "=a") 7578 (udiv:DI (match_operand:DI 1 "register_operand" "0") 7579 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7580 (set (match_operand:DI 3 "register_operand" "=&d") 7581 (umod:DI (match_dup 1) (match_dup 2))) 7582 (clobber (reg:CC FLAGS_REG))] 7583 "TARGET_64BIT" 7584 "xor{q}\t%3, %3\;div{q}\t%2" 7585 [(set_attr "type" "multi") 7586 (set_attr "length_immediate" "0") 7587 (set_attr "mode" "DI")]) 7588 7589(define_insn "*udivmoddi4_noext" 7590 [(set (match_operand:DI 0 "register_operand" "=a") 7591 (udiv:DI (match_operand:DI 1 "register_operand" "0") 7592 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7593 (set (match_operand:DI 3 "register_operand" "=d") 7594 (umod:DI (match_dup 1) (match_dup 2))) 7595 (use (match_dup 3)) 7596 (clobber (reg:CC FLAGS_REG))] 7597 "TARGET_64BIT" 7598 "div{q}\t%2" 7599 [(set_attr "type" "idiv") 7600 (set_attr "mode" "DI")]) 7601 7602(define_split 7603 [(set (match_operand:DI 0 "register_operand" "") 7604 (udiv:DI (match_operand:DI 1 "register_operand" "") 7605 (match_operand:DI 2 "nonimmediate_operand" ""))) 7606 (set (match_operand:DI 3 "register_operand" "") 7607 (umod:DI (match_dup 1) (match_dup 2))) 7608 (clobber (reg:CC FLAGS_REG))] 7609 "TARGET_64BIT && reload_completed" 7610 [(set (match_dup 3) (const_int 0)) 7611 (parallel [(set (match_dup 0) 7612 (udiv:DI (match_dup 1) (match_dup 2))) 7613 (set (match_dup 3) 7614 (umod:DI (match_dup 1) (match_dup 2))) 7615 (use (match_dup 3)) 7616 (clobber (reg:CC FLAGS_REG))])] 7617 "") 7618 7619(define_insn "udivmodsi4" 7620 [(set (match_operand:SI 0 "register_operand" "=a") 7621 (udiv:SI (match_operand:SI 1 "register_operand" "0") 7622 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7623 (set (match_operand:SI 3 "register_operand" "=&d") 7624 (umod:SI (match_dup 1) (match_dup 2))) 7625 (clobber (reg:CC FLAGS_REG))] 7626 "" 7627 "xor{l}\t%3, %3\;div{l}\t%2" 7628 [(set_attr "type" "multi") 7629 (set_attr "length_immediate" "0") 7630 (set_attr "mode" "SI")]) 7631 7632(define_insn "*udivmodsi4_noext" 7633 [(set (match_operand:SI 0 "register_operand" "=a") 7634 (udiv:SI (match_operand:SI 1 "register_operand" "0") 7635 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7636 (set (match_operand:SI 3 "register_operand" "=d") 7637 (umod:SI (match_dup 1) (match_dup 2))) 7638 (use (match_dup 3)) 7639 (clobber (reg:CC FLAGS_REG))] 7640 "" 7641 "div{l}\t%2" 7642 [(set_attr "type" "idiv") 7643 (set_attr "mode" "SI")]) 7644 7645(define_split 7646 [(set (match_operand:SI 0 "register_operand" "") 7647 (udiv:SI (match_operand:SI 1 "register_operand" "") 7648 (match_operand:SI 2 "nonimmediate_operand" ""))) 7649 (set (match_operand:SI 3 "register_operand" "") 7650 (umod:SI (match_dup 1) (match_dup 2))) 7651 (clobber (reg:CC FLAGS_REG))] 7652 "reload_completed" 7653 [(set (match_dup 3) (const_int 0)) 7654 (parallel [(set (match_dup 0) 7655 (udiv:SI (match_dup 1) (match_dup 2))) 7656 (set (match_dup 3) 7657 (umod:SI (match_dup 1) (match_dup 2))) 7658 (use (match_dup 3)) 7659 (clobber (reg:CC FLAGS_REG))])] 7660 "") 7661 7662(define_expand "udivmodhi4" 7663 [(set (match_dup 4) (const_int 0)) 7664 (parallel [(set (match_operand:HI 0 "register_operand" "") 7665 (udiv:HI (match_operand:HI 1 "register_operand" "") 7666 (match_operand:HI 2 "nonimmediate_operand" ""))) 7667 (set (match_operand:HI 3 "register_operand" "") 7668 (umod:HI (match_dup 1) (match_dup 2))) 7669 (use (match_dup 4)) 7670 (clobber (reg:CC FLAGS_REG))])] 7671 "TARGET_HIMODE_MATH" 7672 "operands[4] = gen_reg_rtx (HImode);") 7673 7674(define_insn "*udivmodhi_noext" 7675 [(set (match_operand:HI 0 "register_operand" "=a") 7676 (udiv:HI (match_operand:HI 1 "register_operand" "0") 7677 (match_operand:HI 2 "nonimmediate_operand" "rm"))) 7678 (set (match_operand:HI 3 "register_operand" "=d") 7679 (umod:HI (match_dup 1) (match_dup 2))) 7680 (use (match_operand:HI 4 "register_operand" "3")) 7681 (clobber (reg:CC FLAGS_REG))] 7682 "" 7683 "div{w}\t%2" 7684 [(set_attr "type" "idiv") 7685 (set_attr "mode" "HI")]) 7686 7687;; We cannot use div/idiv for double division, because it causes 7688;; "division by zero" on the overflow and that's not what we expect 7689;; from truncate. Because true (non truncating) double division is 7690;; never generated, we can't create this insn anyway. 7691; 7692;(define_insn "" 7693; [(set (match_operand:SI 0 "register_operand" "=a") 7694; (truncate:SI 7695; (udiv:DI (match_operand:DI 1 "register_operand" "A") 7696; (zero_extend:DI 7697; (match_operand:SI 2 "nonimmediate_operand" "rm"))))) 7698; (set (match_operand:SI 3 "register_operand" "=d") 7699; (truncate:SI 7700; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2))))) 7701; (clobber (reg:CC FLAGS_REG))] 7702; "" 7703; "div{l}\t{%2, %0|%0, %2}" 7704; [(set_attr "type" "idiv")]) 7705 7706;;- Logical AND instructions 7707 7708;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al. 7709;; Note that this excludes ah. 7710 7711(define_insn "*testdi_1_rex64" 7712 [(set (reg FLAGS_REG) 7713 (compare 7714 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm") 7715 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re")) 7716 (const_int 0)))] 7717 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7718 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7719 "@ 7720 test{l}\t{%k1, %k0|%k0, %k1} 7721 test{l}\t{%k1, %k0|%k0, %k1} 7722 test{q}\t{%1, %0|%0, %1} 7723 test{q}\t{%1, %0|%0, %1} 7724 test{q}\t{%1, %0|%0, %1}" 7725 [(set_attr "type" "test") 7726 (set_attr "modrm" "0,1,0,1,1") 7727 (set_attr "mode" "SI,SI,DI,DI,DI") 7728 (set_attr "pent_pair" "uv,np,uv,np,uv")]) 7729 7730(define_insn "testsi_1" 7731 [(set (reg FLAGS_REG) 7732 (compare 7733 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm") 7734 (match_operand:SI 1 "general_operand" "in,in,rin")) 7735 (const_int 0)))] 7736 "ix86_match_ccmode (insn, CCNOmode) 7737 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7738 "test{l}\t{%1, %0|%0, %1}" 7739 [(set_attr "type" "test") 7740 (set_attr "modrm" "0,1,1") 7741 (set_attr "mode" "SI") 7742 (set_attr "pent_pair" "uv,np,uv")]) 7743 7744(define_expand "testsi_ccno_1" 7745 [(set (reg:CCNO FLAGS_REG) 7746 (compare:CCNO 7747 (and:SI (match_operand:SI 0 "nonimmediate_operand" "") 7748 (match_operand:SI 1 "nonmemory_operand" "")) 7749 (const_int 0)))] 7750 "" 7751 "") 7752 7753(define_insn "*testhi_1" 7754 [(set (reg FLAGS_REG) 7755 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm") 7756 (match_operand:HI 1 "general_operand" "n,n,rn")) 7757 (const_int 0)))] 7758 "ix86_match_ccmode (insn, CCNOmode) 7759 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7760 "test{w}\t{%1, %0|%0, %1}" 7761 [(set_attr "type" "test") 7762 (set_attr "modrm" "0,1,1") 7763 (set_attr "mode" "HI") 7764 (set_attr "pent_pair" "uv,np,uv")]) 7765 7766(define_expand "testqi_ccz_1" 7767 [(set (reg:CCZ FLAGS_REG) 7768 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "") 7769 (match_operand:QI 1 "nonmemory_operand" "")) 7770 (const_int 0)))] 7771 "" 7772 "") 7773 7774(define_insn "*testqi_1_maybe_si" 7775 [(set (reg FLAGS_REG) 7776 (compare 7777 (and:QI 7778 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r") 7779 (match_operand:QI 1 "general_operand" "n,n,qn,n")) 7780 (const_int 0)))] 7781 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 7782 && ix86_match_ccmode (insn, 7783 GET_CODE (operands[1]) == CONST_INT 7784 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)" 7785{ 7786 if (which_alternative == 3) 7787 { 7788 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0) 7789 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); 7790 return "test{l}\t{%1, %k0|%k0, %1}"; 7791 } 7792 return "test{b}\t{%1, %0|%0, %1}"; 7793} 7794 [(set_attr "type" "test") 7795 (set_attr "modrm" "0,1,1,1") 7796 (set_attr "mode" "QI,QI,QI,SI") 7797 (set_attr "pent_pair" "uv,np,uv,np")]) 7798 7799(define_insn "*testqi_1" 7800 [(set (reg FLAGS_REG) 7801 (compare 7802 (and:QI 7803 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm") 7804 (match_operand:QI 1 "general_operand" "n,n,qn")) 7805 (const_int 0)))] 7806 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 7807 && ix86_match_ccmode (insn, CCNOmode)" 7808 "test{b}\t{%1, %0|%0, %1}" 7809 [(set_attr "type" "test") 7810 (set_attr "modrm" "0,1,1") 7811 (set_attr "mode" "QI") 7812 (set_attr "pent_pair" "uv,np,uv")]) 7813 7814(define_expand "testqi_ext_ccno_0" 7815 [(set (reg:CCNO FLAGS_REG) 7816 (compare:CCNO 7817 (and:SI 7818 (zero_extract:SI 7819 (match_operand 0 "ext_register_operand" "") 7820 (const_int 8) 7821 (const_int 8)) 7822 (match_operand 1 "const_int_operand" "")) 7823 (const_int 0)))] 7824 "" 7825 "") 7826 7827(define_insn "*testqi_ext_0" 7828 [(set (reg FLAGS_REG) 7829 (compare 7830 (and:SI 7831 (zero_extract:SI 7832 (match_operand 0 "ext_register_operand" "Q") 7833 (const_int 8) 7834 (const_int 8)) 7835 (match_operand 1 "const_int_operand" "n")) 7836 (const_int 0)))] 7837 "ix86_match_ccmode (insn, CCNOmode)" 7838 "test{b}\t{%1, %h0|%h0, %1}" 7839 [(set_attr "type" "test") 7840 (set_attr "mode" "QI") 7841 (set_attr "length_immediate" "1") 7842 (set_attr "pent_pair" "np")]) 7843 7844(define_insn "*testqi_ext_1" 7845 [(set (reg FLAGS_REG) 7846 (compare 7847 (and:SI 7848 (zero_extract:SI 7849 (match_operand 0 "ext_register_operand" "Q") 7850 (const_int 8) 7851 (const_int 8)) 7852 (zero_extend:SI 7853 (match_operand:QI 1 "general_operand" "Qm"))) 7854 (const_int 0)))] 7855 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7856 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7857 "test{b}\t{%1, %h0|%h0, %1}" 7858 [(set_attr "type" "test") 7859 (set_attr "mode" "QI")]) 7860 7861(define_insn "*testqi_ext_1_rex64" 7862 [(set (reg FLAGS_REG) 7863 (compare 7864 (and:SI 7865 (zero_extract:SI 7866 (match_operand 0 "ext_register_operand" "Q") 7867 (const_int 8) 7868 (const_int 8)) 7869 (zero_extend:SI 7870 (match_operand:QI 1 "register_operand" "Q"))) 7871 (const_int 0)))] 7872 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 7873 "test{b}\t{%1, %h0|%h0, %1}" 7874 [(set_attr "type" "test") 7875 (set_attr "mode" "QI")]) 7876 7877(define_insn "*testqi_ext_2" 7878 [(set (reg FLAGS_REG) 7879 (compare 7880 (and:SI 7881 (zero_extract:SI 7882 (match_operand 0 "ext_register_operand" "Q") 7883 (const_int 8) 7884 (const_int 8)) 7885 (zero_extract:SI 7886 (match_operand 1 "ext_register_operand" "Q") 7887 (const_int 8) 7888 (const_int 8))) 7889 (const_int 0)))] 7890 "ix86_match_ccmode (insn, CCNOmode)" 7891 "test{b}\t{%h1, %h0|%h0, %h1}" 7892 [(set_attr "type" "test") 7893 (set_attr "mode" "QI")]) 7894 7895;; Combine likes to form bit extractions for some tests. Humor it. 7896(define_insn "*testqi_ext_3" 7897 [(set (reg FLAGS_REG) 7898 (compare (zero_extract:SI 7899 (match_operand 0 "nonimmediate_operand" "rm") 7900 (match_operand:SI 1 "const_int_operand" "") 7901 (match_operand:SI 2 "const_int_operand" "")) 7902 (const_int 0)))] 7903 "ix86_match_ccmode (insn, CCNOmode) 7904 && INTVAL (operands[1]) > 0 7905 && INTVAL (operands[2]) >= 0 7906 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 7907 && (GET_MODE (operands[0]) == SImode 7908 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode) 7909 || GET_MODE (operands[0]) == HImode 7910 || GET_MODE (operands[0]) == QImode)" 7911 "#") 7912 7913(define_insn "*testqi_ext_3_rex64" 7914 [(set (reg FLAGS_REG) 7915 (compare (zero_extract:DI 7916 (match_operand 0 "nonimmediate_operand" "rm") 7917 (match_operand:DI 1 "const_int_operand" "") 7918 (match_operand:DI 2 "const_int_operand" "")) 7919 (const_int 0)))] 7920 "TARGET_64BIT 7921 && ix86_match_ccmode (insn, CCNOmode) 7922 && INTVAL (operands[1]) > 0 7923 && INTVAL (operands[2]) >= 0 7924 /* Ensure that resulting mask is zero or sign extended operand. */ 7925 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 7926 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64 7927 && INTVAL (operands[1]) > 32)) 7928 && (GET_MODE (operands[0]) == SImode 7929 || GET_MODE (operands[0]) == DImode 7930 || GET_MODE (operands[0]) == HImode 7931 || GET_MODE (operands[0]) == QImode)" 7932 "#") 7933 7934(define_split 7935 [(set (match_operand 0 "flags_reg_operand" "") 7936 (match_operator 1 "compare_operator" 7937 [(zero_extract 7938 (match_operand 2 "nonimmediate_operand" "") 7939 (match_operand 3 "const_int_operand" "") 7940 (match_operand 4 "const_int_operand" "")) 7941 (const_int 0)]))] 7942 "ix86_match_ccmode (insn, CCNOmode)" 7943 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))] 7944{ 7945 rtx val = operands[2]; 7946 HOST_WIDE_INT len = INTVAL (operands[3]); 7947 HOST_WIDE_INT pos = INTVAL (operands[4]); 7948 HOST_WIDE_INT mask; 7949 enum machine_mode mode, submode; 7950 7951 mode = GET_MODE (val); 7952 if (GET_CODE (val) == MEM) 7953 { 7954 /* ??? Combine likes to put non-volatile mem extractions in QImode 7955 no matter the size of the test. So find a mode that works. */ 7956 if (! MEM_VOLATILE_P (val)) 7957 { 7958 mode = smallest_mode_for_size (pos + len, MODE_INT); 7959 val = adjust_address (val, mode, 0); 7960 } 7961 } 7962 else if (GET_CODE (val) == SUBREG 7963 && (submode = GET_MODE (SUBREG_REG (val)), 7964 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)) 7965 && pos + len <= GET_MODE_BITSIZE (submode)) 7966 { 7967 /* Narrow a paradoxical subreg to prevent partial register stalls. */ 7968 mode = submode; 7969 val = SUBREG_REG (val); 7970 } 7971 else if (mode == HImode && pos + len <= 8) 7972 { 7973 /* Small HImode tests can be converted to QImode. */ 7974 mode = QImode; 7975 val = gen_lowpart (QImode, val); 7976 } 7977 7978 if (len == HOST_BITS_PER_WIDE_INT) 7979 mask = -1; 7980 else 7981 mask = ((HOST_WIDE_INT)1 << len) - 1; 7982 mask <<= pos; 7983 7984 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode)); 7985}) 7986 7987;; Convert HImode/SImode test instructions with immediate to QImode ones. 7988;; i386 does not allow to encode test with 8bit sign extended immediate, so 7989;; this is relatively important trick. 7990;; Do the conversion only post-reload to avoid limiting of the register class 7991;; to QI regs. 7992(define_split 7993 [(set (match_operand 0 "flags_reg_operand" "") 7994 (match_operator 1 "compare_operator" 7995 [(and (match_operand 2 "register_operand" "") 7996 (match_operand 3 "const_int_operand" "")) 7997 (const_int 0)]))] 7998 "reload_completed 7999 && QI_REG_P (operands[2]) 8000 && GET_MODE (operands[2]) != QImode 8001 && ((ix86_match_ccmode (insn, CCZmode) 8002 && !(INTVAL (operands[3]) & ~(255 << 8))) 8003 || (ix86_match_ccmode (insn, CCNOmode) 8004 && !(INTVAL (operands[3]) & ~(127 << 8))))" 8005 [(set (match_dup 0) 8006 (match_op_dup 1 8007 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8)) 8008 (match_dup 3)) 8009 (const_int 0)]))] 8010 "operands[2] = gen_lowpart (SImode, operands[2]); 8011 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);") 8012 8013(define_split 8014 [(set (match_operand 0 "flags_reg_operand" "") 8015 (match_operator 1 "compare_operator" 8016 [(and (match_operand 2 "nonimmediate_operand" "") 8017 (match_operand 3 "const_int_operand" "")) 8018 (const_int 0)]))] 8019 "reload_completed 8020 && GET_MODE (operands[2]) != QImode 8021 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2])) 8022 && ((ix86_match_ccmode (insn, CCZmode) 8023 && !(INTVAL (operands[3]) & ~255)) 8024 || (ix86_match_ccmode (insn, CCNOmode) 8025 && !(INTVAL (operands[3]) & ~127)))" 8026 [(set (match_dup 0) 8027 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 8028 (const_int 0)]))] 8029 "operands[2] = gen_lowpart (QImode, operands[2]); 8030 operands[3] = gen_lowpart (QImode, operands[3]);") 8031 8032 8033;; %%% This used to optimize known byte-wide and operations to memory, 8034;; and sometimes to QImode registers. If this is considered useful, 8035;; it should be done with splitters. 8036 8037(define_expand "anddi3" 8038 [(set (match_operand:DI 0 "nonimmediate_operand" "") 8039 (and:DI (match_operand:DI 1 "nonimmediate_operand" "") 8040 (match_operand:DI 2 "x86_64_szext_general_operand" ""))) 8041 (clobber (reg:CC FLAGS_REG))] 8042 "TARGET_64BIT" 8043 "ix86_expand_binary_operator (AND, DImode, operands); DONE;") 8044 8045(define_insn "*anddi_1_rex64" 8046 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r") 8047 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm") 8048 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L"))) 8049 (clobber (reg:CC FLAGS_REG))] 8050 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)" 8051{ 8052 switch (get_attr_type (insn)) 8053 { 8054 case TYPE_IMOVX: 8055 { 8056 enum machine_mode mode; 8057 8058 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 8059 if (INTVAL (operands[2]) == 0xff) 8060 mode = QImode; 8061 else 8062 { 8063 gcc_assert (INTVAL (operands[2]) == 0xffff); 8064 mode = HImode; 8065 } 8066 8067 operands[1] = gen_lowpart (mode, operands[1]); 8068 if (mode == QImode) 8069 return "movz{bq|x}\t{%1,%0|%0, %1}"; 8070 else 8071 return "movz{wq|x}\t{%1,%0|%0, %1}"; 8072 } 8073 8074 default: 8075 gcc_assert (rtx_equal_p (operands[0], operands[1])); 8076 if (get_attr_mode (insn) == MODE_SI) 8077 return "and{l}\t{%k2, %k0|%k0, %k2}"; 8078 else 8079 return "and{q}\t{%2, %0|%0, %2}"; 8080 } 8081} 8082 [(set_attr "type" "alu,alu,alu,imovx") 8083 (set_attr "length_immediate" "*,*,*,0") 8084 (set_attr "mode" "SI,DI,DI,DI")]) 8085 8086(define_insn "*anddi_2" 8087 [(set (reg FLAGS_REG) 8088 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") 8089 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re")) 8090 (const_int 0))) 8091 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm") 8092 (and:DI (match_dup 1) (match_dup 2)))] 8093 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8094 && ix86_binary_operator_ok (AND, DImode, operands)" 8095 "@ 8096 and{l}\t{%k2, %k0|%k0, %k2} 8097 and{q}\t{%2, %0|%0, %2} 8098 and{q}\t{%2, %0|%0, %2}" 8099 [(set_attr "type" "alu") 8100 (set_attr "mode" "SI,DI,DI")]) 8101 8102(define_expand "andsi3" 8103 [(set (match_operand:SI 0 "nonimmediate_operand" "") 8104 (and:SI (match_operand:SI 1 "nonimmediate_operand" "") 8105 (match_operand:SI 2 "general_operand" ""))) 8106 (clobber (reg:CC FLAGS_REG))] 8107 "" 8108 "ix86_expand_binary_operator (AND, SImode, operands); DONE;") 8109 8110(define_insn "*andsi_1" 8111 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r") 8112 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm") 8113 (match_operand:SI 2 "general_operand" "ri,rm,L"))) 8114 (clobber (reg:CC FLAGS_REG))] 8115 "ix86_binary_operator_ok (AND, SImode, operands)" 8116{ 8117 switch (get_attr_type (insn)) 8118 { 8119 case TYPE_IMOVX: 8120 { 8121 enum machine_mode mode; 8122 8123 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 8124 if (INTVAL (operands[2]) == 0xff) 8125 mode = QImode; 8126 else 8127 { 8128 gcc_assert (INTVAL (operands[2]) == 0xffff); 8129 mode = HImode; 8130 } 8131 8132 operands[1] = gen_lowpart (mode, operands[1]); 8133 if (mode == QImode) 8134 return "movz{bl|x}\t{%1,%0|%0, %1}"; 8135 else 8136 return "movz{wl|x}\t{%1,%0|%0, %1}"; 8137 } 8138 8139 default: 8140 gcc_assert (rtx_equal_p (operands[0], operands[1])); 8141 return "and{l}\t{%2, %0|%0, %2}"; 8142 } 8143} 8144 [(set_attr "type" "alu,alu,imovx") 8145 (set_attr "length_immediate" "*,*,0") 8146 (set_attr "mode" "SI")]) 8147 8148(define_split 8149 [(set (match_operand 0 "register_operand" "") 8150 (and (match_dup 0) 8151 (const_int -65536))) 8152 (clobber (reg:CC FLAGS_REG))] 8153 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)" 8154 [(set (strict_low_part (match_dup 1)) (const_int 0))] 8155 "operands[1] = gen_lowpart (HImode, operands[0]);") 8156 8157(define_split 8158 [(set (match_operand 0 "ext_register_operand" "") 8159 (and (match_dup 0) 8160 (const_int -256))) 8161 (clobber (reg:CC FLAGS_REG))] 8162 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed" 8163 [(set (strict_low_part (match_dup 1)) (const_int 0))] 8164 "operands[1] = gen_lowpart (QImode, operands[0]);") 8165 8166(define_split 8167 [(set (match_operand 0 "ext_register_operand" "") 8168 (and (match_dup 0) 8169 (const_int -65281))) 8170 (clobber (reg:CC FLAGS_REG))] 8171 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed" 8172 [(parallel [(set (zero_extract:SI (match_dup 0) 8173 (const_int 8) 8174 (const_int 8)) 8175 (xor:SI 8176 (zero_extract:SI (match_dup 0) 8177 (const_int 8) 8178 (const_int 8)) 8179 (zero_extract:SI (match_dup 0) 8180 (const_int 8) 8181 (const_int 8)))) 8182 (clobber (reg:CC FLAGS_REG))])] 8183 "operands[0] = gen_lowpart (SImode, operands[0]);") 8184 8185;; See comment for addsi_1_zext why we do use nonimmediate_operand 8186(define_insn "*andsi_1_zext" 8187 [(set (match_operand:DI 0 "register_operand" "=r") 8188 (zero_extend:DI 8189 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8190 (match_operand:SI 2 "general_operand" "rim")))) 8191 (clobber (reg:CC FLAGS_REG))] 8192 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" 8193 "and{l}\t{%2, %k0|%k0, %2}" 8194 [(set_attr "type" "alu") 8195 (set_attr "mode" "SI")]) 8196 8197(define_insn "*andsi_2" 8198 [(set (reg FLAGS_REG) 8199 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8200 (match_operand:SI 2 "general_operand" "rim,ri")) 8201 (const_int 0))) 8202 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 8203 (and:SI (match_dup 1) (match_dup 2)))] 8204 "ix86_match_ccmode (insn, CCNOmode) 8205 && ix86_binary_operator_ok (AND, SImode, operands)" 8206 "and{l}\t{%2, %0|%0, %2}" 8207 [(set_attr "type" "alu") 8208 (set_attr "mode" "SI")]) 8209 8210;; See comment for addsi_1_zext why we do use nonimmediate_operand 8211(define_insn "*andsi_2_zext" 8212 [(set (reg FLAGS_REG) 8213 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8214 (match_operand:SI 2 "general_operand" "rim")) 8215 (const_int 0))) 8216 (set (match_operand:DI 0 "register_operand" "=r") 8217 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] 8218 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8219 && ix86_binary_operator_ok (AND, SImode, operands)" 8220 "and{l}\t{%2, %k0|%k0, %2}" 8221 [(set_attr "type" "alu") 8222 (set_attr "mode" "SI")]) 8223 8224(define_expand "andhi3" 8225 [(set (match_operand:HI 0 "nonimmediate_operand" "") 8226 (and:HI (match_operand:HI 1 "nonimmediate_operand" "") 8227 (match_operand:HI 2 "general_operand" ""))) 8228 (clobber (reg:CC FLAGS_REG))] 8229 "TARGET_HIMODE_MATH" 8230 "ix86_expand_binary_operator (AND, HImode, operands); DONE;") 8231 8232(define_insn "*andhi_1" 8233 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") 8234 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm") 8235 (match_operand:HI 2 "general_operand" "ri,rm,L"))) 8236 (clobber (reg:CC FLAGS_REG))] 8237 "ix86_binary_operator_ok (AND, HImode, operands)" 8238{ 8239 switch (get_attr_type (insn)) 8240 { 8241 case TYPE_IMOVX: 8242 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 8243 gcc_assert (INTVAL (operands[2]) == 0xff); 8244 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}"; 8245 8246 default: 8247 gcc_assert (rtx_equal_p (operands[0], operands[1])); 8248 8249 return "and{w}\t{%2, %0|%0, %2}"; 8250 } 8251} 8252 [(set_attr "type" "alu,alu,imovx") 8253 (set_attr "length_immediate" "*,*,0") 8254 (set_attr "mode" "HI,HI,SI")]) 8255 8256(define_insn "*andhi_2" 8257 [(set (reg FLAGS_REG) 8258 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 8259 (match_operand:HI 2 "general_operand" "rim,ri")) 8260 (const_int 0))) 8261 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 8262 (and:HI (match_dup 1) (match_dup 2)))] 8263 "ix86_match_ccmode (insn, CCNOmode) 8264 && ix86_binary_operator_ok (AND, HImode, operands)" 8265 "and{w}\t{%2, %0|%0, %2}" 8266 [(set_attr "type" "alu") 8267 (set_attr "mode" "HI")]) 8268 8269(define_expand "andqi3" 8270 [(set (match_operand:QI 0 "nonimmediate_operand" "") 8271 (and:QI (match_operand:QI 1 "nonimmediate_operand" "") 8272 (match_operand:QI 2 "general_operand" ""))) 8273 (clobber (reg:CC FLAGS_REG))] 8274 "TARGET_QIMODE_MATH" 8275 "ix86_expand_binary_operator (AND, QImode, operands); DONE;") 8276 8277;; %%% Potential partial reg stall on alternative 2. What to do? 8278(define_insn "*andqi_1" 8279 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 8280 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8281 (match_operand:QI 2 "general_operand" "qi,qmi,ri"))) 8282 (clobber (reg:CC FLAGS_REG))] 8283 "ix86_binary_operator_ok (AND, QImode, operands)" 8284 "@ 8285 and{b}\t{%2, %0|%0, %2} 8286 and{b}\t{%2, %0|%0, %2} 8287 and{l}\t{%k2, %k0|%k0, %k2}" 8288 [(set_attr "type" "alu") 8289 (set_attr "mode" "QI,QI,SI")]) 8290 8291(define_insn "*andqi_1_slp" 8292 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 8293 (and:QI (match_dup 0) 8294 (match_operand:QI 1 "general_operand" "qi,qmi"))) 8295 (clobber (reg:CC FLAGS_REG))] 8296 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8297 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8298 "and{b}\t{%1, %0|%0, %1}" 8299 [(set_attr "type" "alu1") 8300 (set_attr "mode" "QI")]) 8301 8302(define_insn "*andqi_2_maybe_si" 8303 [(set (reg FLAGS_REG) 8304 (compare (and:QI 8305 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8306 (match_operand:QI 2 "general_operand" "qim,qi,i")) 8307 (const_int 0))) 8308 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r") 8309 (and:QI (match_dup 1) (match_dup 2)))] 8310 "ix86_binary_operator_ok (AND, QImode, operands) 8311 && ix86_match_ccmode (insn, 8312 GET_CODE (operands[2]) == CONST_INT 8313 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)" 8314{ 8315 if (which_alternative == 2) 8316 { 8317 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) 8318 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); 8319 return "and{l}\t{%2, %k0|%k0, %2}"; 8320 } 8321 return "and{b}\t{%2, %0|%0, %2}"; 8322} 8323 [(set_attr "type" "alu") 8324 (set_attr "mode" "QI,QI,SI")]) 8325 8326(define_insn "*andqi_2" 8327 [(set (reg FLAGS_REG) 8328 (compare (and:QI 8329 (match_operand:QI 1 "nonimmediate_operand" "%0,0") 8330 (match_operand:QI 2 "general_operand" "qim,qi")) 8331 (const_int 0))) 8332 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 8333 (and:QI (match_dup 1) (match_dup 2)))] 8334 "ix86_match_ccmode (insn, CCNOmode) 8335 && ix86_binary_operator_ok (AND, QImode, operands)" 8336 "and{b}\t{%2, %0|%0, %2}" 8337 [(set_attr "type" "alu") 8338 (set_attr "mode" "QI")]) 8339 8340(define_insn "*andqi_2_slp" 8341 [(set (reg FLAGS_REG) 8342 (compare (and:QI 8343 (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 8344 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi")) 8345 (const_int 0))) 8346 (set (strict_low_part (match_dup 0)) 8347 (and:QI (match_dup 0) (match_dup 1)))] 8348 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8349 && ix86_match_ccmode (insn, CCNOmode) 8350 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8351 "and{b}\t{%1, %0|%0, %1}" 8352 [(set_attr "type" "alu1") 8353 (set_attr "mode" "QI")]) 8354 8355;; ??? A bug in recog prevents it from recognizing a const_int as an 8356;; operand to zero_extend in andqi_ext_1. It was checking explicitly 8357;; for a QImode operand, which of course failed. 8358 8359(define_insn "andqi_ext_0" 8360 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8361 (const_int 8) 8362 (const_int 8)) 8363 (and:SI 8364 (zero_extract:SI 8365 (match_operand 1 "ext_register_operand" "0") 8366 (const_int 8) 8367 (const_int 8)) 8368 (match_operand 2 "const_int_operand" "n"))) 8369 (clobber (reg:CC FLAGS_REG))] 8370 "" 8371 "and{b}\t{%2, %h0|%h0, %2}" 8372 [(set_attr "type" "alu") 8373 (set_attr "length_immediate" "1") 8374 (set_attr "mode" "QI")]) 8375 8376;; Generated by peephole translating test to and. This shows up 8377;; often in fp comparisons. 8378 8379(define_insn "*andqi_ext_0_cc" 8380 [(set (reg FLAGS_REG) 8381 (compare 8382 (and:SI 8383 (zero_extract:SI 8384 (match_operand 1 "ext_register_operand" "0") 8385 (const_int 8) 8386 (const_int 8)) 8387 (match_operand 2 "const_int_operand" "n")) 8388 (const_int 0))) 8389 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8390 (const_int 8) 8391 (const_int 8)) 8392 (and:SI 8393 (zero_extract:SI 8394 (match_dup 1) 8395 (const_int 8) 8396 (const_int 8)) 8397 (match_dup 2)))] 8398 "ix86_match_ccmode (insn, CCNOmode)" 8399 "and{b}\t{%2, %h0|%h0, %2}" 8400 [(set_attr "type" "alu") 8401 (set_attr "length_immediate" "1") 8402 (set_attr "mode" "QI")]) 8403 8404(define_insn "*andqi_ext_1" 8405 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8406 (const_int 8) 8407 (const_int 8)) 8408 (and:SI 8409 (zero_extract:SI 8410 (match_operand 1 "ext_register_operand" "0") 8411 (const_int 8) 8412 (const_int 8)) 8413 (zero_extend:SI 8414 (match_operand:QI 2 "general_operand" "Qm")))) 8415 (clobber (reg:CC FLAGS_REG))] 8416 "!TARGET_64BIT" 8417 "and{b}\t{%2, %h0|%h0, %2}" 8418 [(set_attr "type" "alu") 8419 (set_attr "length_immediate" "0") 8420 (set_attr "mode" "QI")]) 8421 8422(define_insn "*andqi_ext_1_rex64" 8423 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8424 (const_int 8) 8425 (const_int 8)) 8426 (and:SI 8427 (zero_extract:SI 8428 (match_operand 1 "ext_register_operand" "0") 8429 (const_int 8) 8430 (const_int 8)) 8431 (zero_extend:SI 8432 (match_operand 2 "ext_register_operand" "Q")))) 8433 (clobber (reg:CC FLAGS_REG))] 8434 "TARGET_64BIT" 8435 "and{b}\t{%2, %h0|%h0, %2}" 8436 [(set_attr "type" "alu") 8437 (set_attr "length_immediate" "0") 8438 (set_attr "mode" "QI")]) 8439 8440(define_insn "*andqi_ext_2" 8441 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8442 (const_int 8) 8443 (const_int 8)) 8444 (and:SI 8445 (zero_extract:SI 8446 (match_operand 1 "ext_register_operand" "%0") 8447 (const_int 8) 8448 (const_int 8)) 8449 (zero_extract:SI 8450 (match_operand 2 "ext_register_operand" "Q") 8451 (const_int 8) 8452 (const_int 8)))) 8453 (clobber (reg:CC FLAGS_REG))] 8454 "" 8455 "and{b}\t{%h2, %h0|%h0, %h2}" 8456 [(set_attr "type" "alu") 8457 (set_attr "length_immediate" "0") 8458 (set_attr "mode" "QI")]) 8459 8460;; Convert wide AND instructions with immediate operand to shorter QImode 8461;; equivalents when possible. 8462;; Don't do the splitting with memory operands, since it introduces risk 8463;; of memory mismatch stalls. We may want to do the splitting for optimizing 8464;; for size, but that can (should?) be handled by generic code instead. 8465(define_split 8466 [(set (match_operand 0 "register_operand" "") 8467 (and (match_operand 1 "register_operand" "") 8468 (match_operand 2 "const_int_operand" ""))) 8469 (clobber (reg:CC FLAGS_REG))] 8470 "reload_completed 8471 && QI_REG_P (operands[0]) 8472 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8473 && !(~INTVAL (operands[2]) & ~(255 << 8)) 8474 && GET_MODE (operands[0]) != QImode" 8475 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8476 (and:SI (zero_extract:SI (match_dup 1) 8477 (const_int 8) (const_int 8)) 8478 (match_dup 2))) 8479 (clobber (reg:CC FLAGS_REG))])] 8480 "operands[0] = gen_lowpart (SImode, operands[0]); 8481 operands[1] = gen_lowpart (SImode, operands[1]); 8482 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") 8483 8484;; Since AND can be encoded with sign extended immediate, this is only 8485;; profitable when 7th bit is not set. 8486(define_split 8487 [(set (match_operand 0 "register_operand" "") 8488 (and (match_operand 1 "general_operand" "") 8489 (match_operand 2 "const_int_operand" ""))) 8490 (clobber (reg:CC FLAGS_REG))] 8491 "reload_completed 8492 && ANY_QI_REG_P (operands[0]) 8493 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8494 && !(~INTVAL (operands[2]) & ~255) 8495 && !(INTVAL (operands[2]) & 128) 8496 && GET_MODE (operands[0]) != QImode" 8497 [(parallel [(set (strict_low_part (match_dup 0)) 8498 (and:QI (match_dup 1) 8499 (match_dup 2))) 8500 (clobber (reg:CC FLAGS_REG))])] 8501 "operands[0] = gen_lowpart (QImode, operands[0]); 8502 operands[1] = gen_lowpart (QImode, operands[1]); 8503 operands[2] = gen_lowpart (QImode, operands[2]);") 8504 8505;; Logical inclusive OR instructions 8506 8507;; %%% This used to optimize known byte-wide and operations to memory. 8508;; If this is considered useful, it should be done with splitters. 8509 8510(define_expand "iordi3" 8511 [(set (match_operand:DI 0 "nonimmediate_operand" "") 8512 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "") 8513 (match_operand:DI 2 "x86_64_general_operand" ""))) 8514 (clobber (reg:CC FLAGS_REG))] 8515 "TARGET_64BIT" 8516 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;") 8517 8518(define_insn "*iordi_1_rex64" 8519 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 8520 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8521 (match_operand:DI 2 "x86_64_general_operand" "re,rme"))) 8522 (clobber (reg:CC FLAGS_REG))] 8523 "TARGET_64BIT 8524 && ix86_binary_operator_ok (IOR, DImode, operands)" 8525 "or{q}\t{%2, %0|%0, %2}" 8526 [(set_attr "type" "alu") 8527 (set_attr "mode" "DI")]) 8528 8529(define_insn "*iordi_2_rex64" 8530 [(set (reg FLAGS_REG) 8531 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8532 (match_operand:DI 2 "x86_64_general_operand" "rem,re")) 8533 (const_int 0))) 8534 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") 8535 (ior:DI (match_dup 1) (match_dup 2)))] 8536 "TARGET_64BIT 8537 && ix86_match_ccmode (insn, CCNOmode) 8538 && ix86_binary_operator_ok (IOR, DImode, operands)" 8539 "or{q}\t{%2, %0|%0, %2}" 8540 [(set_attr "type" "alu") 8541 (set_attr "mode" "DI")]) 8542 8543(define_insn "*iordi_3_rex64" 8544 [(set (reg FLAGS_REG) 8545 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0") 8546 (match_operand:DI 2 "x86_64_general_operand" "rem")) 8547 (const_int 0))) 8548 (clobber (match_scratch:DI 0 "=r"))] 8549 "TARGET_64BIT 8550 && ix86_match_ccmode (insn, CCNOmode) 8551 && ix86_binary_operator_ok (IOR, DImode, operands)" 8552 "or{q}\t{%2, %0|%0, %2}" 8553 [(set_attr "type" "alu") 8554 (set_attr "mode" "DI")]) 8555 8556 8557(define_expand "iorsi3" 8558 [(set (match_operand:SI 0 "nonimmediate_operand" "") 8559 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "") 8560 (match_operand:SI 2 "general_operand" ""))) 8561 (clobber (reg:CC FLAGS_REG))] 8562 "" 8563 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;") 8564 8565(define_insn "*iorsi_1" 8566 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 8567 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8568 (match_operand:SI 2 "general_operand" "ri,rmi"))) 8569 (clobber (reg:CC FLAGS_REG))] 8570 "ix86_binary_operator_ok (IOR, SImode, operands)" 8571 "or{l}\t{%2, %0|%0, %2}" 8572 [(set_attr "type" "alu") 8573 (set_attr "mode" "SI")]) 8574 8575;; See comment for addsi_1_zext why we do use nonimmediate_operand 8576(define_insn "*iorsi_1_zext" 8577 [(set (match_operand:DI 0 "register_operand" "=rm") 8578 (zero_extend:DI 8579 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8580 (match_operand:SI 2 "general_operand" "rim")))) 8581 (clobber (reg:CC FLAGS_REG))] 8582 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)" 8583 "or{l}\t{%2, %k0|%k0, %2}" 8584 [(set_attr "type" "alu") 8585 (set_attr "mode" "SI")]) 8586 8587(define_insn "*iorsi_1_zext_imm" 8588 [(set (match_operand:DI 0 "register_operand" "=rm") 8589 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 8590 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 8591 (clobber (reg:CC FLAGS_REG))] 8592 "TARGET_64BIT" 8593 "or{l}\t{%2, %k0|%k0, %2}" 8594 [(set_attr "type" "alu") 8595 (set_attr "mode" "SI")]) 8596 8597(define_insn "*iorsi_2" 8598 [(set (reg FLAGS_REG) 8599 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8600 (match_operand:SI 2 "general_operand" "rim,ri")) 8601 (const_int 0))) 8602 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 8603 (ior:SI (match_dup 1) (match_dup 2)))] 8604 "ix86_match_ccmode (insn, CCNOmode) 8605 && ix86_binary_operator_ok (IOR, SImode, operands)" 8606 "or{l}\t{%2, %0|%0, %2}" 8607 [(set_attr "type" "alu") 8608 (set_attr "mode" "SI")]) 8609 8610;; See comment for addsi_1_zext why we do use nonimmediate_operand 8611;; ??? Special case for immediate operand is missing - it is tricky. 8612(define_insn "*iorsi_2_zext" 8613 [(set (reg FLAGS_REG) 8614 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8615 (match_operand:SI 2 "general_operand" "rim")) 8616 (const_int 0))) 8617 (set (match_operand:DI 0 "register_operand" "=r") 8618 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))] 8619 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8620 && ix86_binary_operator_ok (IOR, SImode, operands)" 8621 "or{l}\t{%2, %k0|%k0, %2}" 8622 [(set_attr "type" "alu") 8623 (set_attr "mode" "SI")]) 8624 8625(define_insn "*iorsi_2_zext_imm" 8626 [(set (reg FLAGS_REG) 8627 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8628 (match_operand 2 "x86_64_zext_immediate_operand" "Z")) 8629 (const_int 0))) 8630 (set (match_operand:DI 0 "register_operand" "=r") 8631 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 8632 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8633 && ix86_binary_operator_ok (IOR, SImode, operands)" 8634 "or{l}\t{%2, %k0|%k0, %2}" 8635 [(set_attr "type" "alu") 8636 (set_attr "mode" "SI")]) 8637 8638(define_insn "*iorsi_3" 8639 [(set (reg FLAGS_REG) 8640 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8641 (match_operand:SI 2 "general_operand" "rim")) 8642 (const_int 0))) 8643 (clobber (match_scratch:SI 0 "=r"))] 8644 "ix86_match_ccmode (insn, CCNOmode) 8645 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 8646 "or{l}\t{%2, %0|%0, %2}" 8647 [(set_attr "type" "alu") 8648 (set_attr "mode" "SI")]) 8649 8650(define_expand "iorhi3" 8651 [(set (match_operand:HI 0 "nonimmediate_operand" "") 8652 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "") 8653 (match_operand:HI 2 "general_operand" ""))) 8654 (clobber (reg:CC FLAGS_REG))] 8655 "TARGET_HIMODE_MATH" 8656 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;") 8657 8658(define_insn "*iorhi_1" 8659 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m") 8660 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 8661 (match_operand:HI 2 "general_operand" "rmi,ri"))) 8662 (clobber (reg:CC FLAGS_REG))] 8663 "ix86_binary_operator_ok (IOR, HImode, operands)" 8664 "or{w}\t{%2, %0|%0, %2}" 8665 [(set_attr "type" "alu") 8666 (set_attr "mode" "HI")]) 8667 8668(define_insn "*iorhi_2" 8669 [(set (reg FLAGS_REG) 8670 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 8671 (match_operand:HI 2 "general_operand" "rim,ri")) 8672 (const_int 0))) 8673 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 8674 (ior:HI (match_dup 1) (match_dup 2)))] 8675 "ix86_match_ccmode (insn, CCNOmode) 8676 && ix86_binary_operator_ok (IOR, HImode, operands)" 8677 "or{w}\t{%2, %0|%0, %2}" 8678 [(set_attr "type" "alu") 8679 (set_attr "mode" "HI")]) 8680 8681(define_insn "*iorhi_3" 8682 [(set (reg FLAGS_REG) 8683 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0") 8684 (match_operand:HI 2 "general_operand" "rim")) 8685 (const_int 0))) 8686 (clobber (match_scratch:HI 0 "=r"))] 8687 "ix86_match_ccmode (insn, CCNOmode) 8688 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 8689 "or{w}\t{%2, %0|%0, %2}" 8690 [(set_attr "type" "alu") 8691 (set_attr "mode" "HI")]) 8692 8693(define_expand "iorqi3" 8694 [(set (match_operand:QI 0 "nonimmediate_operand" "") 8695 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "") 8696 (match_operand:QI 2 "general_operand" ""))) 8697 (clobber (reg:CC FLAGS_REG))] 8698 "TARGET_QIMODE_MATH" 8699 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;") 8700 8701;; %%% Potential partial reg stall on alternative 2. What to do? 8702(define_insn "*iorqi_1" 8703 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") 8704 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8705 (match_operand:QI 2 "general_operand" "qmi,qi,ri"))) 8706 (clobber (reg:CC FLAGS_REG))] 8707 "ix86_binary_operator_ok (IOR, QImode, operands)" 8708 "@ 8709 or{b}\t{%2, %0|%0, %2} 8710 or{b}\t{%2, %0|%0, %2} 8711 or{l}\t{%k2, %k0|%k0, %k2}" 8712 [(set_attr "type" "alu") 8713 (set_attr "mode" "QI,QI,SI")]) 8714 8715(define_insn "*iorqi_1_slp" 8716 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m")) 8717 (ior:QI (match_dup 0) 8718 (match_operand:QI 1 "general_operand" "qmi,qi"))) 8719 (clobber (reg:CC FLAGS_REG))] 8720 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8721 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8722 "or{b}\t{%1, %0|%0, %1}" 8723 [(set_attr "type" "alu1") 8724 (set_attr "mode" "QI")]) 8725 8726(define_insn "*iorqi_2" 8727 [(set (reg FLAGS_REG) 8728 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 8729 (match_operand:QI 2 "general_operand" "qim,qi")) 8730 (const_int 0))) 8731 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 8732 (ior:QI (match_dup 1) (match_dup 2)))] 8733 "ix86_match_ccmode (insn, CCNOmode) 8734 && ix86_binary_operator_ok (IOR, QImode, operands)" 8735 "or{b}\t{%2, %0|%0, %2}" 8736 [(set_attr "type" "alu") 8737 (set_attr "mode" "QI")]) 8738 8739(define_insn "*iorqi_2_slp" 8740 [(set (reg FLAGS_REG) 8741 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 8742 (match_operand:QI 1 "general_operand" "qim,qi")) 8743 (const_int 0))) 8744 (set (strict_low_part (match_dup 0)) 8745 (ior:QI (match_dup 0) (match_dup 1)))] 8746 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8747 && ix86_match_ccmode (insn, CCNOmode) 8748 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8749 "or{b}\t{%1, %0|%0, %1}" 8750 [(set_attr "type" "alu1") 8751 (set_attr "mode" "QI")]) 8752 8753(define_insn "*iorqi_3" 8754 [(set (reg FLAGS_REG) 8755 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 8756 (match_operand:QI 2 "general_operand" "qim")) 8757 (const_int 0))) 8758 (clobber (match_scratch:QI 0 "=q"))] 8759 "ix86_match_ccmode (insn, CCNOmode) 8760 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 8761 "or{b}\t{%2, %0|%0, %2}" 8762 [(set_attr "type" "alu") 8763 (set_attr "mode" "QI")]) 8764 8765(define_insn "iorqi_ext_0" 8766 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8767 (const_int 8) 8768 (const_int 8)) 8769 (ior:SI 8770 (zero_extract:SI 8771 (match_operand 1 "ext_register_operand" "0") 8772 (const_int 8) 8773 (const_int 8)) 8774 (match_operand 2 "const_int_operand" "n"))) 8775 (clobber (reg:CC FLAGS_REG))] 8776 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 8777 "or{b}\t{%2, %h0|%h0, %2}" 8778 [(set_attr "type" "alu") 8779 (set_attr "length_immediate" "1") 8780 (set_attr "mode" "QI")]) 8781 8782(define_insn "*iorqi_ext_1" 8783 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8784 (const_int 8) 8785 (const_int 8)) 8786 (ior:SI 8787 (zero_extract:SI 8788 (match_operand 1 "ext_register_operand" "0") 8789 (const_int 8) 8790 (const_int 8)) 8791 (zero_extend:SI 8792 (match_operand:QI 2 "general_operand" "Qm")))) 8793 (clobber (reg:CC FLAGS_REG))] 8794 "!TARGET_64BIT 8795 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 8796 "or{b}\t{%2, %h0|%h0, %2}" 8797 [(set_attr "type" "alu") 8798 (set_attr "length_immediate" "0") 8799 (set_attr "mode" "QI")]) 8800 8801(define_insn "*iorqi_ext_1_rex64" 8802 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8803 (const_int 8) 8804 (const_int 8)) 8805 (ior:SI 8806 (zero_extract:SI 8807 (match_operand 1 "ext_register_operand" "0") 8808 (const_int 8) 8809 (const_int 8)) 8810 (zero_extend:SI 8811 (match_operand 2 "ext_register_operand" "Q")))) 8812 (clobber (reg:CC FLAGS_REG))] 8813 "TARGET_64BIT 8814 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 8815 "or{b}\t{%2, %h0|%h0, %2}" 8816 [(set_attr "type" "alu") 8817 (set_attr "length_immediate" "0") 8818 (set_attr "mode" "QI")]) 8819 8820(define_insn "*iorqi_ext_2" 8821 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8822 (const_int 8) 8823 (const_int 8)) 8824 (ior:SI 8825 (zero_extract:SI (match_operand 1 "ext_register_operand" "0") 8826 (const_int 8) 8827 (const_int 8)) 8828 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 8829 (const_int 8) 8830 (const_int 8)))) 8831 (clobber (reg:CC FLAGS_REG))] 8832 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 8833 "ior{b}\t{%h2, %h0|%h0, %h2}" 8834 [(set_attr "type" "alu") 8835 (set_attr "length_immediate" "0") 8836 (set_attr "mode" "QI")]) 8837 8838(define_split 8839 [(set (match_operand 0 "register_operand" "") 8840 (ior (match_operand 1 "register_operand" "") 8841 (match_operand 2 "const_int_operand" ""))) 8842 (clobber (reg:CC FLAGS_REG))] 8843 "reload_completed 8844 && QI_REG_P (operands[0]) 8845 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8846 && !(INTVAL (operands[2]) & ~(255 << 8)) 8847 && GET_MODE (operands[0]) != QImode" 8848 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8849 (ior:SI (zero_extract:SI (match_dup 1) 8850 (const_int 8) (const_int 8)) 8851 (match_dup 2))) 8852 (clobber (reg:CC FLAGS_REG))])] 8853 "operands[0] = gen_lowpart (SImode, operands[0]); 8854 operands[1] = gen_lowpart (SImode, operands[1]); 8855 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") 8856 8857;; Since OR can be encoded with sign extended immediate, this is only 8858;; profitable when 7th bit is set. 8859(define_split 8860 [(set (match_operand 0 "register_operand" "") 8861 (ior (match_operand 1 "general_operand" "") 8862 (match_operand 2 "const_int_operand" ""))) 8863 (clobber (reg:CC FLAGS_REG))] 8864 "reload_completed 8865 && ANY_QI_REG_P (operands[0]) 8866 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8867 && !(INTVAL (operands[2]) & ~255) 8868 && (INTVAL (operands[2]) & 128) 8869 && GET_MODE (operands[0]) != QImode" 8870 [(parallel [(set (strict_low_part (match_dup 0)) 8871 (ior:QI (match_dup 1) 8872 (match_dup 2))) 8873 (clobber (reg:CC FLAGS_REG))])] 8874 "operands[0] = gen_lowpart (QImode, operands[0]); 8875 operands[1] = gen_lowpart (QImode, operands[1]); 8876 operands[2] = gen_lowpart (QImode, operands[2]);") 8877 8878;; Logical XOR instructions 8879 8880;; %%% This used to optimize known byte-wide and operations to memory. 8881;; If this is considered useful, it should be done with splitters. 8882 8883(define_expand "xordi3" 8884 [(set (match_operand:DI 0 "nonimmediate_operand" "") 8885 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "") 8886 (match_operand:DI 2 "x86_64_general_operand" ""))) 8887 (clobber (reg:CC FLAGS_REG))] 8888 "TARGET_64BIT" 8889 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;") 8890 8891(define_insn "*xordi_1_rex64" 8892 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 8893 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8894 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 8895 (clobber (reg:CC FLAGS_REG))] 8896 "TARGET_64BIT 8897 && ix86_binary_operator_ok (XOR, DImode, operands)" 8898 "@ 8899 xor{q}\t{%2, %0|%0, %2} 8900 xor{q}\t{%2, %0|%0, %2}" 8901 [(set_attr "type" "alu") 8902 (set_attr "mode" "DI,DI")]) 8903 8904(define_insn "*xordi_2_rex64" 8905 [(set (reg FLAGS_REG) 8906 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8907 (match_operand:DI 2 "x86_64_general_operand" "rem,re")) 8908 (const_int 0))) 8909 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") 8910 (xor:DI (match_dup 1) (match_dup 2)))] 8911 "TARGET_64BIT 8912 && ix86_match_ccmode (insn, CCNOmode) 8913 && ix86_binary_operator_ok (XOR, DImode, operands)" 8914 "@ 8915 xor{q}\t{%2, %0|%0, %2} 8916 xor{q}\t{%2, %0|%0, %2}" 8917 [(set_attr "type" "alu") 8918 (set_attr "mode" "DI,DI")]) 8919 8920(define_insn "*xordi_3_rex64" 8921 [(set (reg FLAGS_REG) 8922 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0") 8923 (match_operand:DI 2 "x86_64_general_operand" "rem")) 8924 (const_int 0))) 8925 (clobber (match_scratch:DI 0 "=r"))] 8926 "TARGET_64BIT 8927 && ix86_match_ccmode (insn, CCNOmode) 8928 && ix86_binary_operator_ok (XOR, DImode, operands)" 8929 "xor{q}\t{%2, %0|%0, %2}" 8930 [(set_attr "type" "alu") 8931 (set_attr "mode" "DI")]) 8932 8933(define_expand "xorsi3" 8934 [(set (match_operand:SI 0 "nonimmediate_operand" "") 8935 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "") 8936 (match_operand:SI 2 "general_operand" ""))) 8937 (clobber (reg:CC FLAGS_REG))] 8938 "" 8939 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;") 8940 8941(define_insn "*xorsi_1" 8942 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 8943 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8944 (match_operand:SI 2 "general_operand" "ri,rm"))) 8945 (clobber (reg:CC FLAGS_REG))] 8946 "ix86_binary_operator_ok (XOR, SImode, operands)" 8947 "xor{l}\t{%2, %0|%0, %2}" 8948 [(set_attr "type" "alu") 8949 (set_attr "mode" "SI")]) 8950 8951;; See comment for addsi_1_zext why we do use nonimmediate_operand 8952;; Add speccase for immediates 8953(define_insn "*xorsi_1_zext" 8954 [(set (match_operand:DI 0 "register_operand" "=r") 8955 (zero_extend:DI 8956 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8957 (match_operand:SI 2 "general_operand" "rim")))) 8958 (clobber (reg:CC FLAGS_REG))] 8959 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)" 8960 "xor{l}\t{%2, %k0|%k0, %2}" 8961 [(set_attr "type" "alu") 8962 (set_attr "mode" "SI")]) 8963 8964(define_insn "*xorsi_1_zext_imm" 8965 [(set (match_operand:DI 0 "register_operand" "=r") 8966 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 8967 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 8968 (clobber (reg:CC FLAGS_REG))] 8969 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)" 8970 "xor{l}\t{%2, %k0|%k0, %2}" 8971 [(set_attr "type" "alu") 8972 (set_attr "mode" "SI")]) 8973 8974(define_insn "*xorsi_2" 8975 [(set (reg FLAGS_REG) 8976 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8977 (match_operand:SI 2 "general_operand" "rim,ri")) 8978 (const_int 0))) 8979 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 8980 (xor:SI (match_dup 1) (match_dup 2)))] 8981 "ix86_match_ccmode (insn, CCNOmode) 8982 && ix86_binary_operator_ok (XOR, SImode, operands)" 8983 "xor{l}\t{%2, %0|%0, %2}" 8984 [(set_attr "type" "alu") 8985 (set_attr "mode" "SI")]) 8986 8987;; See comment for addsi_1_zext why we do use nonimmediate_operand 8988;; ??? Special case for immediate operand is missing - it is tricky. 8989(define_insn "*xorsi_2_zext" 8990 [(set (reg FLAGS_REG) 8991 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8992 (match_operand:SI 2 "general_operand" "rim")) 8993 (const_int 0))) 8994 (set (match_operand:DI 0 "register_operand" "=r") 8995 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))] 8996 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8997 && ix86_binary_operator_ok (XOR, SImode, operands)" 8998 "xor{l}\t{%2, %k0|%k0, %2}" 8999 [(set_attr "type" "alu") 9000 (set_attr "mode" "SI")]) 9001 9002(define_insn "*xorsi_2_zext_imm" 9003 [(set (reg FLAGS_REG) 9004 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9005 (match_operand 2 "x86_64_zext_immediate_operand" "Z")) 9006 (const_int 0))) 9007 (set (match_operand:DI 0 "register_operand" "=r") 9008 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 9009 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9010 && ix86_binary_operator_ok (XOR, SImode, operands)" 9011 "xor{l}\t{%2, %k0|%k0, %2}" 9012 [(set_attr "type" "alu") 9013 (set_attr "mode" "SI")]) 9014 9015(define_insn "*xorsi_3" 9016 [(set (reg FLAGS_REG) 9017 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9018 (match_operand:SI 2 "general_operand" "rim")) 9019 (const_int 0))) 9020 (clobber (match_scratch:SI 0 "=r"))] 9021 "ix86_match_ccmode (insn, CCNOmode) 9022 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 9023 "xor{l}\t{%2, %0|%0, %2}" 9024 [(set_attr "type" "alu") 9025 (set_attr "mode" "SI")]) 9026 9027(define_expand "xorhi3" 9028 [(set (match_operand:HI 0 "nonimmediate_operand" "") 9029 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "") 9030 (match_operand:HI 2 "general_operand" ""))) 9031 (clobber (reg:CC FLAGS_REG))] 9032 "TARGET_HIMODE_MATH" 9033 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;") 9034 9035(define_insn "*xorhi_1" 9036 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m") 9037 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 9038 (match_operand:HI 2 "general_operand" "rmi,ri"))) 9039 (clobber (reg:CC FLAGS_REG))] 9040 "ix86_binary_operator_ok (XOR, HImode, operands)" 9041 "xor{w}\t{%2, %0|%0, %2}" 9042 [(set_attr "type" "alu") 9043 (set_attr "mode" "HI")]) 9044 9045(define_insn "*xorhi_2" 9046 [(set (reg FLAGS_REG) 9047 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 9048 (match_operand:HI 2 "general_operand" "rim,ri")) 9049 (const_int 0))) 9050 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 9051 (xor:HI (match_dup 1) (match_dup 2)))] 9052 "ix86_match_ccmode (insn, CCNOmode) 9053 && ix86_binary_operator_ok (XOR, HImode, operands)" 9054 "xor{w}\t{%2, %0|%0, %2}" 9055 [(set_attr "type" "alu") 9056 (set_attr "mode" "HI")]) 9057 9058(define_insn "*xorhi_3" 9059 [(set (reg FLAGS_REG) 9060 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0") 9061 (match_operand:HI 2 "general_operand" "rim")) 9062 (const_int 0))) 9063 (clobber (match_scratch:HI 0 "=r"))] 9064 "ix86_match_ccmode (insn, CCNOmode) 9065 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 9066 "xor{w}\t{%2, %0|%0, %2}" 9067 [(set_attr "type" "alu") 9068 (set_attr "mode" "HI")]) 9069 9070(define_expand "xorqi3" 9071 [(set (match_operand:QI 0 "nonimmediate_operand" "") 9072 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "") 9073 (match_operand:QI 2 "general_operand" ""))) 9074 (clobber (reg:CC FLAGS_REG))] 9075 "TARGET_QIMODE_MATH" 9076 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;") 9077 9078;; %%% Potential partial reg stall on alternative 2. What to do? 9079(define_insn "*xorqi_1" 9080 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") 9081 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 9082 (match_operand:QI 2 "general_operand" "qmi,qi,ri"))) 9083 (clobber (reg:CC FLAGS_REG))] 9084 "ix86_binary_operator_ok (XOR, QImode, operands)" 9085 "@ 9086 xor{b}\t{%2, %0|%0, %2} 9087 xor{b}\t{%2, %0|%0, %2} 9088 xor{l}\t{%k2, %k0|%k0, %k2}" 9089 [(set_attr "type" "alu") 9090 (set_attr "mode" "QI,QI,SI")]) 9091 9092(define_insn "*xorqi_1_slp" 9093 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 9094 (xor:QI (match_dup 0) 9095 (match_operand:QI 1 "general_operand" "qi,qmi"))) 9096 (clobber (reg:CC FLAGS_REG))] 9097 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 9098 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 9099 "xor{b}\t{%1, %0|%0, %1}" 9100 [(set_attr "type" "alu1") 9101 (set_attr "mode" "QI")]) 9102 9103(define_insn "xorqi_ext_0" 9104 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9105 (const_int 8) 9106 (const_int 8)) 9107 (xor:SI 9108 (zero_extract:SI 9109 (match_operand 1 "ext_register_operand" "0") 9110 (const_int 8) 9111 (const_int 8)) 9112 (match_operand 2 "const_int_operand" "n"))) 9113 (clobber (reg:CC FLAGS_REG))] 9114 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 9115 "xor{b}\t{%2, %h0|%h0, %2}" 9116 [(set_attr "type" "alu") 9117 (set_attr "length_immediate" "1") 9118 (set_attr "mode" "QI")]) 9119 9120(define_insn "*xorqi_ext_1" 9121 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9122 (const_int 8) 9123 (const_int 8)) 9124 (xor:SI 9125 (zero_extract:SI 9126 (match_operand 1 "ext_register_operand" "0") 9127 (const_int 8) 9128 (const_int 8)) 9129 (zero_extend:SI 9130 (match_operand:QI 2 "general_operand" "Qm")))) 9131 (clobber (reg:CC FLAGS_REG))] 9132 "!TARGET_64BIT 9133 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 9134 "xor{b}\t{%2, %h0|%h0, %2}" 9135 [(set_attr "type" "alu") 9136 (set_attr "length_immediate" "0") 9137 (set_attr "mode" "QI")]) 9138 9139(define_insn "*xorqi_ext_1_rex64" 9140 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9141 (const_int 8) 9142 (const_int 8)) 9143 (xor:SI 9144 (zero_extract:SI 9145 (match_operand 1 "ext_register_operand" "0") 9146 (const_int 8) 9147 (const_int 8)) 9148 (zero_extend:SI 9149 (match_operand 2 "ext_register_operand" "Q")))) 9150 (clobber (reg:CC FLAGS_REG))] 9151 "TARGET_64BIT 9152 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 9153 "xor{b}\t{%2, %h0|%h0, %2}" 9154 [(set_attr "type" "alu") 9155 (set_attr "length_immediate" "0") 9156 (set_attr "mode" "QI")]) 9157 9158(define_insn "*xorqi_ext_2" 9159 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9160 (const_int 8) 9161 (const_int 8)) 9162 (xor:SI 9163 (zero_extract:SI (match_operand 1 "ext_register_operand" "0") 9164 (const_int 8) 9165 (const_int 8)) 9166 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 9167 (const_int 8) 9168 (const_int 8)))) 9169 (clobber (reg:CC FLAGS_REG))] 9170 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 9171 "xor{b}\t{%h2, %h0|%h0, %h2}" 9172 [(set_attr "type" "alu") 9173 (set_attr "length_immediate" "0") 9174 (set_attr "mode" "QI")]) 9175 9176(define_insn "*xorqi_cc_1" 9177 [(set (reg FLAGS_REG) 9178 (compare 9179 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 9180 (match_operand:QI 2 "general_operand" "qim,qi")) 9181 (const_int 0))) 9182 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 9183 (xor:QI (match_dup 1) (match_dup 2)))] 9184 "ix86_match_ccmode (insn, CCNOmode) 9185 && ix86_binary_operator_ok (XOR, QImode, operands)" 9186 "xor{b}\t{%2, %0|%0, %2}" 9187 [(set_attr "type" "alu") 9188 (set_attr "mode" "QI")]) 9189 9190(define_insn "*xorqi_2_slp" 9191 [(set (reg FLAGS_REG) 9192 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 9193 (match_operand:QI 1 "general_operand" "qim,qi")) 9194 (const_int 0))) 9195 (set (strict_low_part (match_dup 0)) 9196 (xor:QI (match_dup 0) (match_dup 1)))] 9197 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 9198 && ix86_match_ccmode (insn, CCNOmode) 9199 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 9200 "xor{b}\t{%1, %0|%0, %1}" 9201 [(set_attr "type" "alu1") 9202 (set_attr "mode" "QI")]) 9203 9204(define_insn "*xorqi_cc_2" 9205 [(set (reg FLAGS_REG) 9206 (compare 9207 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 9208 (match_operand:QI 2 "general_operand" "qim")) 9209 (const_int 0))) 9210 (clobber (match_scratch:QI 0 "=q"))] 9211 "ix86_match_ccmode (insn, CCNOmode) 9212 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 9213 "xor{b}\t{%2, %0|%0, %2}" 9214 [(set_attr "type" "alu") 9215 (set_attr "mode" "QI")]) 9216 9217(define_insn "*xorqi_cc_ext_1" 9218 [(set (reg FLAGS_REG) 9219 (compare 9220 (xor:SI 9221 (zero_extract:SI 9222 (match_operand 1 "ext_register_operand" "0") 9223 (const_int 8) 9224 (const_int 8)) 9225 (match_operand:QI 2 "general_operand" "qmn")) 9226 (const_int 0))) 9227 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q") 9228 (const_int 8) 9229 (const_int 8)) 9230 (xor:SI 9231 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) 9232 (match_dup 2)))] 9233 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 9234 "xor{b}\t{%2, %h0|%h0, %2}" 9235 [(set_attr "type" "alu") 9236 (set_attr "mode" "QI")]) 9237 9238(define_insn "*xorqi_cc_ext_1_rex64" 9239 [(set (reg FLAGS_REG) 9240 (compare 9241 (xor:SI 9242 (zero_extract:SI 9243 (match_operand 1 "ext_register_operand" "0") 9244 (const_int 8) 9245 (const_int 8)) 9246 (match_operand:QI 2 "nonmemory_operand" "Qn")) 9247 (const_int 0))) 9248 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9249 (const_int 8) 9250 (const_int 8)) 9251 (xor:SI 9252 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) 9253 (match_dup 2)))] 9254 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 9255 "xor{b}\t{%2, %h0|%h0, %2}" 9256 [(set_attr "type" "alu") 9257 (set_attr "mode" "QI")]) 9258 9259(define_expand "xorqi_cc_ext_1" 9260 [(parallel [ 9261 (set (reg:CCNO FLAGS_REG) 9262 (compare:CCNO 9263 (xor:SI 9264 (zero_extract:SI 9265 (match_operand 1 "ext_register_operand" "") 9266 (const_int 8) 9267 (const_int 8)) 9268 (match_operand:QI 2 "general_operand" "")) 9269 (const_int 0))) 9270 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "") 9271 (const_int 8) 9272 (const_int 8)) 9273 (xor:SI 9274 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) 9275 (match_dup 2)))])] 9276 "" 9277 "") 9278 9279(define_split 9280 [(set (match_operand 0 "register_operand" "") 9281 (xor (match_operand 1 "register_operand" "") 9282 (match_operand 2 "const_int_operand" ""))) 9283 (clobber (reg:CC FLAGS_REG))] 9284 "reload_completed 9285 && QI_REG_P (operands[0]) 9286 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 9287 && !(INTVAL (operands[2]) & ~(255 << 8)) 9288 && GET_MODE (operands[0]) != QImode" 9289 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 9290 (xor:SI (zero_extract:SI (match_dup 1) 9291 (const_int 8) (const_int 8)) 9292 (match_dup 2))) 9293 (clobber (reg:CC FLAGS_REG))])] 9294 "operands[0] = gen_lowpart (SImode, operands[0]); 9295 operands[1] = gen_lowpart (SImode, operands[1]); 9296 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") 9297 9298;; Since XOR can be encoded with sign extended immediate, this is only 9299;; profitable when 7th bit is set. 9300(define_split 9301 [(set (match_operand 0 "register_operand" "") 9302 (xor (match_operand 1 "general_operand" "") 9303 (match_operand 2 "const_int_operand" ""))) 9304 (clobber (reg:CC FLAGS_REG))] 9305 "reload_completed 9306 && ANY_QI_REG_P (operands[0]) 9307 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 9308 && !(INTVAL (operands[2]) & ~255) 9309 && (INTVAL (operands[2]) & 128) 9310 && GET_MODE (operands[0]) != QImode" 9311 [(parallel [(set (strict_low_part (match_dup 0)) 9312 (xor:QI (match_dup 1) 9313 (match_dup 2))) 9314 (clobber (reg:CC FLAGS_REG))])] 9315 "operands[0] = gen_lowpart (QImode, operands[0]); 9316 operands[1] = gen_lowpart (QImode, operands[1]); 9317 operands[2] = gen_lowpart (QImode, operands[2]);") 9318 9319;; Negation instructions 9320 9321(define_expand "negti2" 9322 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "") 9323 (neg:TI (match_operand:TI 1 "nonimmediate_operand" ""))) 9324 (clobber (reg:CC FLAGS_REG))])] 9325 "TARGET_64BIT" 9326 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;") 9327 9328(define_insn "*negti2_1" 9329 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro") 9330 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0"))) 9331 (clobber (reg:CC FLAGS_REG))] 9332 "TARGET_64BIT 9333 && ix86_unary_operator_ok (NEG, TImode, operands)" 9334 "#") 9335 9336(define_split 9337 [(set (match_operand:TI 0 "nonimmediate_operand" "") 9338 (neg:TI (match_operand:TI 1 "nonimmediate_operand" ""))) 9339 (clobber (reg:CC FLAGS_REG))] 9340 "TARGET_64BIT && reload_completed" 9341 [(parallel 9342 [(set (reg:CCZ FLAGS_REG) 9343 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0))) 9344 (set (match_dup 0) (neg:DI (match_dup 2)))]) 9345 (parallel 9346 [(set (match_dup 1) 9347 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) 9348 (match_dup 3)) 9349 (const_int 0))) 9350 (clobber (reg:CC FLAGS_REG))]) 9351 (parallel 9352 [(set (match_dup 1) 9353 (neg:DI (match_dup 1))) 9354 (clobber (reg:CC FLAGS_REG))])] 9355 "split_ti (operands+1, 1, operands+2, operands+3); 9356 split_ti (operands+0, 1, operands+0, operands+1);") 9357 9358(define_expand "negdi2" 9359 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 9360 (neg:DI (match_operand:DI 1 "nonimmediate_operand" ""))) 9361 (clobber (reg:CC FLAGS_REG))])] 9362 "" 9363 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;") 9364 9365(define_insn "*negdi2_1" 9366 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro") 9367 (neg:DI (match_operand:DI 1 "general_operand" "0"))) 9368 (clobber (reg:CC FLAGS_REG))] 9369 "!TARGET_64BIT 9370 && ix86_unary_operator_ok (NEG, DImode, operands)" 9371 "#") 9372 9373(define_split 9374 [(set (match_operand:DI 0 "nonimmediate_operand" "") 9375 (neg:DI (match_operand:DI 1 "general_operand" ""))) 9376 (clobber (reg:CC FLAGS_REG))] 9377 "!TARGET_64BIT && reload_completed" 9378 [(parallel 9379 [(set (reg:CCZ FLAGS_REG) 9380 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0))) 9381 (set (match_dup 0) (neg:SI (match_dup 2)))]) 9382 (parallel 9383 [(set (match_dup 1) 9384 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) 9385 (match_dup 3)) 9386 (const_int 0))) 9387 (clobber (reg:CC FLAGS_REG))]) 9388 (parallel 9389 [(set (match_dup 1) 9390 (neg:SI (match_dup 1))) 9391 (clobber (reg:CC FLAGS_REG))])] 9392 "split_di (operands+1, 1, operands+2, operands+3); 9393 split_di (operands+0, 1, operands+0, operands+1);") 9394 9395(define_insn "*negdi2_1_rex64" 9396 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9397 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))) 9398 (clobber (reg:CC FLAGS_REG))] 9399 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)" 9400 "neg{q}\t%0" 9401 [(set_attr "type" "negnot") 9402 (set_attr "mode" "DI")]) 9403 9404;; The problem with neg is that it does not perform (compare x 0), 9405;; it really performs (compare 0 x), which leaves us with the zero 9406;; flag being the only useful item. 9407 9408(define_insn "*negdi2_cmpz_rex64" 9409 [(set (reg:CCZ FLAGS_REG) 9410 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")) 9411 (const_int 0))) 9412 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9413 (neg:DI (match_dup 1)))] 9414 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)" 9415 "neg{q}\t%0" 9416 [(set_attr "type" "negnot") 9417 (set_attr "mode" "DI")]) 9418 9419 9420(define_expand "negsi2" 9421 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 9422 (neg:SI (match_operand:SI 1 "nonimmediate_operand" ""))) 9423 (clobber (reg:CC FLAGS_REG))])] 9424 "" 9425 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;") 9426 9427(define_insn "*negsi2_1" 9428 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 9429 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))) 9430 (clobber (reg:CC FLAGS_REG))] 9431 "ix86_unary_operator_ok (NEG, SImode, operands)" 9432 "neg{l}\t%0" 9433 [(set_attr "type" "negnot") 9434 (set_attr "mode" "SI")]) 9435 9436;; Combine is quite creative about this pattern. 9437(define_insn "*negsi2_1_zext" 9438 [(set (match_operand:DI 0 "register_operand" "=r") 9439 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0") 9440 (const_int 32))) 9441 (const_int 32))) 9442 (clobber (reg:CC FLAGS_REG))] 9443 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9444 "neg{l}\t%k0" 9445 [(set_attr "type" "negnot") 9446 (set_attr "mode" "SI")]) 9447 9448;; The problem with neg is that it does not perform (compare x 0), 9449;; it really performs (compare 0 x), which leaves us with the zero 9450;; flag being the only useful item. 9451 9452(define_insn "*negsi2_cmpz" 9453 [(set (reg:CCZ FLAGS_REG) 9454 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")) 9455 (const_int 0))) 9456 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 9457 (neg:SI (match_dup 1)))] 9458 "ix86_unary_operator_ok (NEG, SImode, operands)" 9459 "neg{l}\t%0" 9460 [(set_attr "type" "negnot") 9461 (set_attr "mode" "SI")]) 9462 9463(define_insn "*negsi2_cmpz_zext" 9464 [(set (reg:CCZ FLAGS_REG) 9465 (compare:CCZ (lshiftrt:DI 9466 (neg:DI (ashift:DI 9467 (match_operand:DI 1 "register_operand" "0") 9468 (const_int 32))) 9469 (const_int 32)) 9470 (const_int 0))) 9471 (set (match_operand:DI 0 "register_operand" "=r") 9472 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1) 9473 (const_int 32))) 9474 (const_int 32)))] 9475 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9476 "neg{l}\t%k0" 9477 [(set_attr "type" "negnot") 9478 (set_attr "mode" "SI")]) 9479 9480(define_expand "neghi2" 9481 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 9482 (neg:HI (match_operand:HI 1 "nonimmediate_operand" ""))) 9483 (clobber (reg:CC FLAGS_REG))])] 9484 "TARGET_HIMODE_MATH" 9485 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;") 9486 9487(define_insn "*neghi2_1" 9488 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 9489 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))) 9490 (clobber (reg:CC FLAGS_REG))] 9491 "ix86_unary_operator_ok (NEG, HImode, operands)" 9492 "neg{w}\t%0" 9493 [(set_attr "type" "negnot") 9494 (set_attr "mode" "HI")]) 9495 9496(define_insn "*neghi2_cmpz" 9497 [(set (reg:CCZ FLAGS_REG) 9498 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")) 9499 (const_int 0))) 9500 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 9501 (neg:HI (match_dup 1)))] 9502 "ix86_unary_operator_ok (NEG, HImode, operands)" 9503 "neg{w}\t%0" 9504 [(set_attr "type" "negnot") 9505 (set_attr "mode" "HI")]) 9506 9507(define_expand "negqi2" 9508 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") 9509 (neg:QI (match_operand:QI 1 "nonimmediate_operand" ""))) 9510 (clobber (reg:CC FLAGS_REG))])] 9511 "TARGET_QIMODE_MATH" 9512 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;") 9513 9514(define_insn "*negqi2_1" 9515 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 9516 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))) 9517 (clobber (reg:CC FLAGS_REG))] 9518 "ix86_unary_operator_ok (NEG, QImode, operands)" 9519 "neg{b}\t%0" 9520 [(set_attr "type" "negnot") 9521 (set_attr "mode" "QI")]) 9522 9523(define_insn "*negqi2_cmpz" 9524 [(set (reg:CCZ FLAGS_REG) 9525 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")) 9526 (const_int 0))) 9527 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 9528 (neg:QI (match_dup 1)))] 9529 "ix86_unary_operator_ok (NEG, QImode, operands)" 9530 "neg{b}\t%0" 9531 [(set_attr "type" "negnot") 9532 (set_attr "mode" "QI")]) 9533 9534;; Changing of sign for FP values is doable using integer unit too. 9535 9536(define_expand "negsf2" 9537 [(set (match_operand:SF 0 "nonimmediate_operand" "") 9538 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))] 9539 "TARGET_80387 || TARGET_SSE_MATH" 9540 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;") 9541 9542(define_expand "abssf2" 9543 [(set (match_operand:SF 0 "nonimmediate_operand" "") 9544 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))] 9545 "TARGET_80387 || TARGET_SSE_MATH" 9546 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;") 9547 9548(define_insn "*absnegsf2_mixed" 9549 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm") 9550 (match_operator:SF 3 "absneg_operator" 9551 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")])) 9552 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X ")) 9553 (clobber (reg:CC FLAGS_REG))] 9554 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387 9555 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)" 9556 "#") 9557 9558(define_insn "*absnegsf2_sse" 9559 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm") 9560 (match_operator:SF 3 "absneg_operator" 9561 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")])) 9562 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X")) 9563 (clobber (reg:CC FLAGS_REG))] 9564 "TARGET_SSE_MATH 9565 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)" 9566 "#") 9567 9568(define_insn "*absnegsf2_i387" 9569 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm") 9570 (match_operator:SF 3 "absneg_operator" 9571 [(match_operand:SF 1 "nonimmediate_operand" "0,0")])) 9572 (use (match_operand 2 "" "")) 9573 (clobber (reg:CC FLAGS_REG))] 9574 "TARGET_80387 && !TARGET_SSE_MATH 9575 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)" 9576 "#") 9577 9578(define_expand "copysignsf3" 9579 [(match_operand:SF 0 "register_operand" "") 9580 (match_operand:SF 1 "nonmemory_operand" "") 9581 (match_operand:SF 2 "register_operand" "")] 9582 "TARGET_SSE_MATH" 9583{ 9584 ix86_expand_copysign (operands); 9585 DONE; 9586}) 9587 9588(define_insn_and_split "copysignsf3_const" 9589 [(set (match_operand:SF 0 "register_operand" "=x") 9590 (unspec:SF 9591 [(match_operand:V4SF 1 "vector_move_operand" "xmC") 9592 (match_operand:SF 2 "register_operand" "0") 9593 (match_operand:V4SF 3 "nonimmediate_operand" "xm")] 9594 UNSPEC_COPYSIGN))] 9595 "TARGET_SSE_MATH" 9596 "#" 9597 "&& reload_completed" 9598 [(const_int 0)] 9599{ 9600 ix86_split_copysign_const (operands); 9601 DONE; 9602}) 9603 9604(define_insn "copysignsf3_var" 9605 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x") 9606 (unspec:SF 9607 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x") 9608 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x") 9609 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0") 9610 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")] 9611 UNSPEC_COPYSIGN)) 9612 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))] 9613 "TARGET_SSE_MATH" 9614 "#") 9615 9616(define_split 9617 [(set (match_operand:SF 0 "register_operand" "") 9618 (unspec:SF 9619 [(match_operand:SF 2 "register_operand" "") 9620 (match_operand:SF 3 "register_operand" "") 9621 (match_operand:V4SF 4 "" "") 9622 (match_operand:V4SF 5 "" "")] 9623 UNSPEC_COPYSIGN)) 9624 (clobber (match_scratch:V4SF 1 ""))] 9625 "TARGET_SSE_MATH && reload_completed" 9626 [(const_int 0)] 9627{ 9628 ix86_split_copysign_var (operands); 9629 DONE; 9630}) 9631 9632(define_expand "negdf2" 9633 [(set (match_operand:DF 0 "nonimmediate_operand" "") 9634 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))] 9635 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 9636 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;") 9637 9638(define_expand "absdf2" 9639 [(set (match_operand:DF 0 "nonimmediate_operand" "") 9640 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))] 9641 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 9642 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;") 9643 9644(define_insn "*absnegdf2_mixed" 9645 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm") 9646 (match_operator:DF 3 "absneg_operator" 9647 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")])) 9648 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X")) 9649 (clobber (reg:CC FLAGS_REG))] 9650 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387 9651 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)" 9652 "#") 9653 9654(define_insn "*absnegdf2_sse" 9655 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm") 9656 (match_operator:DF 3 "absneg_operator" 9657 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")])) 9658 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X ")) 9659 (clobber (reg:CC FLAGS_REG))] 9660 "TARGET_SSE2 && TARGET_SSE_MATH 9661 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)" 9662 "#") 9663 9664(define_insn "*absnegdf2_i387" 9665 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm") 9666 (match_operator:DF 3 "absneg_operator" 9667 [(match_operand:DF 1 "nonimmediate_operand" "0,0")])) 9668 (use (match_operand 2 "" "")) 9669 (clobber (reg:CC FLAGS_REG))] 9670 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH) 9671 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)" 9672 "#") 9673 9674(define_expand "copysigndf3" 9675 [(match_operand:DF 0 "register_operand" "") 9676 (match_operand:DF 1 "nonmemory_operand" "") 9677 (match_operand:DF 2 "register_operand" "")] 9678 "TARGET_SSE2 && TARGET_SSE_MATH" 9679{ 9680 ix86_expand_copysign (operands); 9681 DONE; 9682}) 9683 9684(define_insn_and_split "copysigndf3_const" 9685 [(set (match_operand:DF 0 "register_operand" "=x") 9686 (unspec:DF 9687 [(match_operand:V2DF 1 "vector_move_operand" "xmC") 9688 (match_operand:DF 2 "register_operand" "0") 9689 (match_operand:V2DF 3 "nonimmediate_operand" "xm")] 9690 UNSPEC_COPYSIGN))] 9691 "TARGET_SSE2 && TARGET_SSE_MATH" 9692 "#" 9693 "&& reload_completed" 9694 [(const_int 0)] 9695{ 9696 ix86_split_copysign_const (operands); 9697 DONE; 9698}) 9699 9700(define_insn "copysigndf3_var" 9701 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x") 9702 (unspec:DF 9703 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x") 9704 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x") 9705 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0") 9706 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")] 9707 UNSPEC_COPYSIGN)) 9708 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))] 9709 "TARGET_SSE2 && TARGET_SSE_MATH" 9710 "#") 9711 9712(define_split 9713 [(set (match_operand:DF 0 "register_operand" "") 9714 (unspec:DF 9715 [(match_operand:DF 2 "register_operand" "") 9716 (match_operand:DF 3 "register_operand" "") 9717 (match_operand:V2DF 4 "" "") 9718 (match_operand:V2DF 5 "" "")] 9719 UNSPEC_COPYSIGN)) 9720 (clobber (match_scratch:V2DF 1 ""))] 9721 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed" 9722 [(const_int 0)] 9723{ 9724 ix86_split_copysign_var (operands); 9725 DONE; 9726}) 9727 9728(define_expand "negxf2" 9729 [(set (match_operand:XF 0 "nonimmediate_operand" "") 9730 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))] 9731 "TARGET_80387" 9732 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;") 9733 9734(define_expand "absxf2" 9735 [(set (match_operand:XF 0 "nonimmediate_operand" "") 9736 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))] 9737 "TARGET_80387" 9738 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;") 9739 9740(define_insn "*absnegxf2_i387" 9741 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm") 9742 (match_operator:XF 3 "absneg_operator" 9743 [(match_operand:XF 1 "nonimmediate_operand" "0,0")])) 9744 (use (match_operand 2 "" "")) 9745 (clobber (reg:CC FLAGS_REG))] 9746 "TARGET_80387 9747 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)" 9748 "#") 9749 9750;; Splitters for fp abs and neg. 9751 9752(define_split 9753 [(set (match_operand 0 "fp_register_operand" "") 9754 (match_operator 1 "absneg_operator" [(match_dup 0)])) 9755 (use (match_operand 2 "" "")) 9756 (clobber (reg:CC FLAGS_REG))] 9757 "reload_completed" 9758 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))]) 9759 9760(define_split 9761 [(set (match_operand 0 "register_operand" "") 9762 (match_operator 3 "absneg_operator" 9763 [(match_operand 1 "register_operand" "")])) 9764 (use (match_operand 2 "nonimmediate_operand" "")) 9765 (clobber (reg:CC FLAGS_REG))] 9766 "reload_completed && SSE_REG_P (operands[0])" 9767 [(set (match_dup 0) (match_dup 3))] 9768{ 9769 enum machine_mode mode = GET_MODE (operands[0]); 9770 enum machine_mode vmode = GET_MODE (operands[2]); 9771 rtx tmp; 9772 9773 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0); 9774 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0); 9775 if (operands_match_p (operands[0], operands[2])) 9776 { 9777 tmp = operands[1]; 9778 operands[1] = operands[2]; 9779 operands[2] = tmp; 9780 } 9781 if (GET_CODE (operands[3]) == ABS) 9782 tmp = gen_rtx_AND (vmode, operands[1], operands[2]); 9783 else 9784 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]); 9785 operands[3] = tmp; 9786}) 9787 9788(define_split 9789 [(set (match_operand:SF 0 "register_operand" "") 9790 (match_operator:SF 1 "absneg_operator" [(match_dup 0)])) 9791 (use (match_operand:V4SF 2 "" "")) 9792 (clobber (reg:CC FLAGS_REG))] 9793 "reload_completed" 9794 [(parallel [(set (match_dup 0) (match_dup 1)) 9795 (clobber (reg:CC FLAGS_REG))])] 9796{ 9797 rtx tmp; 9798 operands[0] = gen_lowpart (SImode, operands[0]); 9799 if (GET_CODE (operands[1]) == ABS) 9800 { 9801 tmp = gen_int_mode (0x7fffffff, SImode); 9802 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9803 } 9804 else 9805 { 9806 tmp = gen_int_mode (0x80000000, SImode); 9807 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 9808 } 9809 operands[1] = tmp; 9810}) 9811 9812(define_split 9813 [(set (match_operand:DF 0 "register_operand" "") 9814 (match_operator:DF 1 "absneg_operator" [(match_dup 0)])) 9815 (use (match_operand 2 "" "")) 9816 (clobber (reg:CC FLAGS_REG))] 9817 "reload_completed" 9818 [(parallel [(set (match_dup 0) (match_dup 1)) 9819 (clobber (reg:CC FLAGS_REG))])] 9820{ 9821 rtx tmp; 9822 if (TARGET_64BIT) 9823 { 9824 tmp = gen_lowpart (DImode, operands[0]); 9825 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63)); 9826 operands[0] = tmp; 9827 9828 if (GET_CODE (operands[1]) == ABS) 9829 tmp = const0_rtx; 9830 else 9831 tmp = gen_rtx_NOT (DImode, tmp); 9832 } 9833 else 9834 { 9835 operands[0] = gen_highpart (SImode, operands[0]); 9836 if (GET_CODE (operands[1]) == ABS) 9837 { 9838 tmp = gen_int_mode (0x7fffffff, SImode); 9839 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9840 } 9841 else 9842 { 9843 tmp = gen_int_mode (0x80000000, SImode); 9844 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 9845 } 9846 } 9847 operands[1] = tmp; 9848}) 9849 9850(define_split 9851 [(set (match_operand:XF 0 "register_operand" "") 9852 (match_operator:XF 1 "absneg_operator" [(match_dup 0)])) 9853 (use (match_operand 2 "" "")) 9854 (clobber (reg:CC FLAGS_REG))] 9855 "reload_completed" 9856 [(parallel [(set (match_dup 0) (match_dup 1)) 9857 (clobber (reg:CC FLAGS_REG))])] 9858{ 9859 rtx tmp; 9860 operands[0] = gen_rtx_REG (SImode, 9861 true_regnum (operands[0]) 9862 + (TARGET_64BIT ? 1 : 2)); 9863 if (GET_CODE (operands[1]) == ABS) 9864 { 9865 tmp = GEN_INT (0x7fff); 9866 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9867 } 9868 else 9869 { 9870 tmp = GEN_INT (0x8000); 9871 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 9872 } 9873 operands[1] = tmp; 9874}) 9875 9876(define_split 9877 [(set (match_operand 0 "memory_operand" "") 9878 (match_operator 1 "absneg_operator" [(match_dup 0)])) 9879 (use (match_operand 2 "" "")) 9880 (clobber (reg:CC FLAGS_REG))] 9881 "reload_completed" 9882 [(parallel [(set (match_dup 0) (match_dup 1)) 9883 (clobber (reg:CC FLAGS_REG))])] 9884{ 9885 enum machine_mode mode = GET_MODE (operands[0]); 9886 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode); 9887 rtx tmp; 9888 9889 operands[0] = adjust_address (operands[0], QImode, size - 1); 9890 if (GET_CODE (operands[1]) == ABS) 9891 { 9892 tmp = gen_int_mode (0x7f, QImode); 9893 tmp = gen_rtx_AND (QImode, operands[0], tmp); 9894 } 9895 else 9896 { 9897 tmp = gen_int_mode (0x80, QImode); 9898 tmp = gen_rtx_XOR (QImode, operands[0], tmp); 9899 } 9900 operands[1] = tmp; 9901}) 9902 9903;; Conditionalize these after reload. If they match before reload, we 9904;; lose the clobber and ability to use integer instructions. 9905 9906(define_insn "*negsf2_1" 9907 [(set (match_operand:SF 0 "register_operand" "=f") 9908 (neg:SF (match_operand:SF 1 "register_operand" "0")))] 9909 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)" 9910 "fchs" 9911 [(set_attr "type" "fsgn") 9912 (set_attr "mode" "SF")]) 9913 9914(define_insn "*negdf2_1" 9915 [(set (match_operand:DF 0 "register_operand" "=f") 9916 (neg:DF (match_operand:DF 1 "register_operand" "0")))] 9917 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))" 9918 "fchs" 9919 [(set_attr "type" "fsgn") 9920 (set_attr "mode" "DF")]) 9921 9922(define_insn "*negxf2_1" 9923 [(set (match_operand:XF 0 "register_operand" "=f") 9924 (neg:XF (match_operand:XF 1 "register_operand" "0")))] 9925 "TARGET_80387" 9926 "fchs" 9927 [(set_attr "type" "fsgn") 9928 (set_attr "mode" "XF")]) 9929 9930(define_insn "*abssf2_1" 9931 [(set (match_operand:SF 0 "register_operand" "=f") 9932 (abs:SF (match_operand:SF 1 "register_operand" "0")))] 9933 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)" 9934 "fabs" 9935 [(set_attr "type" "fsgn") 9936 (set_attr "mode" "SF")]) 9937 9938(define_insn "*absdf2_1" 9939 [(set (match_operand:DF 0 "register_operand" "=f") 9940 (abs:DF (match_operand:DF 1 "register_operand" "0")))] 9941 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))" 9942 "fabs" 9943 [(set_attr "type" "fsgn") 9944 (set_attr "mode" "DF")]) 9945 9946(define_insn "*absxf2_1" 9947 [(set (match_operand:XF 0 "register_operand" "=f") 9948 (abs:XF (match_operand:XF 1 "register_operand" "0")))] 9949 "TARGET_80387" 9950 "fabs" 9951 [(set_attr "type" "fsgn") 9952 (set_attr "mode" "DF")]) 9953 9954(define_insn "*negextendsfdf2" 9955 [(set (match_operand:DF 0 "register_operand" "=f") 9956 (neg:DF (float_extend:DF 9957 (match_operand:SF 1 "register_operand" "0"))))] 9958 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 9959 "fchs" 9960 [(set_attr "type" "fsgn") 9961 (set_attr "mode" "DF")]) 9962 9963(define_insn "*negextenddfxf2" 9964 [(set (match_operand:XF 0 "register_operand" "=f") 9965 (neg:XF (float_extend:XF 9966 (match_operand:DF 1 "register_operand" "0"))))] 9967 "TARGET_80387" 9968 "fchs" 9969 [(set_attr "type" "fsgn") 9970 (set_attr "mode" "XF")]) 9971 9972(define_insn "*negextendsfxf2" 9973 [(set (match_operand:XF 0 "register_operand" "=f") 9974 (neg:XF (float_extend:XF 9975 (match_operand:SF 1 "register_operand" "0"))))] 9976 "TARGET_80387" 9977 "fchs" 9978 [(set_attr "type" "fsgn") 9979 (set_attr "mode" "XF")]) 9980 9981(define_insn "*absextendsfdf2" 9982 [(set (match_operand:DF 0 "register_operand" "=f") 9983 (abs:DF (float_extend:DF 9984 (match_operand:SF 1 "register_operand" "0"))))] 9985 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 9986 "fabs" 9987 [(set_attr "type" "fsgn") 9988 (set_attr "mode" "DF")]) 9989 9990(define_insn "*absextenddfxf2" 9991 [(set (match_operand:XF 0 "register_operand" "=f") 9992 (abs:XF (float_extend:XF 9993 (match_operand:DF 1 "register_operand" "0"))))] 9994 "TARGET_80387" 9995 "fabs" 9996 [(set_attr "type" "fsgn") 9997 (set_attr "mode" "XF")]) 9998 9999(define_insn "*absextendsfxf2" 10000 [(set (match_operand:XF 0 "register_operand" "=f") 10001 (abs:XF (float_extend:XF 10002 (match_operand:SF 1 "register_operand" "0"))))] 10003 "TARGET_80387" 10004 "fabs" 10005 [(set_attr "type" "fsgn") 10006 (set_attr "mode" "XF")]) 10007 10008;; One complement instructions 10009 10010(define_expand "one_cmpldi2" 10011 [(set (match_operand:DI 0 "nonimmediate_operand" "") 10012 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))] 10013 "TARGET_64BIT" 10014 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;") 10015 10016(define_insn "*one_cmpldi2_1_rex64" 10017 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 10018 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))] 10019 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)" 10020 "not{q}\t%0" 10021 [(set_attr "type" "negnot") 10022 (set_attr "mode" "DI")]) 10023 10024(define_insn "*one_cmpldi2_2_rex64" 10025 [(set (reg FLAGS_REG) 10026 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")) 10027 (const_int 0))) 10028 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 10029 (not:DI (match_dup 1)))] 10030 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 10031 && ix86_unary_operator_ok (NOT, DImode, operands)" 10032 "#" 10033 [(set_attr "type" "alu1") 10034 (set_attr "mode" "DI")]) 10035 10036(define_split 10037 [(set (match_operand 0 "flags_reg_operand" "") 10038 (match_operator 2 "compare_operator" 10039 [(not:DI (match_operand:DI 3 "nonimmediate_operand" "")) 10040 (const_int 0)])) 10041 (set (match_operand:DI 1 "nonimmediate_operand" "") 10042 (not:DI (match_dup 3)))] 10043 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 10044 [(parallel [(set (match_dup 0) 10045 (match_op_dup 2 10046 [(xor:DI (match_dup 3) (const_int -1)) 10047 (const_int 0)])) 10048 (set (match_dup 1) 10049 (xor:DI (match_dup 3) (const_int -1)))])] 10050 "") 10051 10052(define_expand "one_cmplsi2" 10053 [(set (match_operand:SI 0 "nonimmediate_operand" "") 10054 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))] 10055 "" 10056 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;") 10057 10058(define_insn "*one_cmplsi2_1" 10059 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 10060 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))] 10061 "ix86_unary_operator_ok (NOT, SImode, operands)" 10062 "not{l}\t%0" 10063 [(set_attr "type" "negnot") 10064 (set_attr "mode" "SI")]) 10065 10066;; ??? Currently never generated - xor is used instead. 10067(define_insn "*one_cmplsi2_1_zext" 10068 [(set (match_operand:DI 0 "register_operand" "=r") 10069 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))] 10070 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)" 10071 "not{l}\t%k0" 10072 [(set_attr "type" "negnot") 10073 (set_attr "mode" "SI")]) 10074 10075(define_insn "*one_cmplsi2_2" 10076 [(set (reg FLAGS_REG) 10077 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")) 10078 (const_int 0))) 10079 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 10080 (not:SI (match_dup 1)))] 10081 "ix86_match_ccmode (insn, CCNOmode) 10082 && ix86_unary_operator_ok (NOT, SImode, operands)" 10083 "#" 10084 [(set_attr "type" "alu1") 10085 (set_attr "mode" "SI")]) 10086 10087(define_split 10088 [(set (match_operand 0 "flags_reg_operand" "") 10089 (match_operator 2 "compare_operator" 10090 [(not:SI (match_operand:SI 3 "nonimmediate_operand" "")) 10091 (const_int 0)])) 10092 (set (match_operand:SI 1 "nonimmediate_operand" "") 10093 (not:SI (match_dup 3)))] 10094 "ix86_match_ccmode (insn, CCNOmode)" 10095 [(parallel [(set (match_dup 0) 10096 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 10097 (const_int 0)])) 10098 (set (match_dup 1) 10099 (xor:SI (match_dup 3) (const_int -1)))])] 10100 "") 10101 10102;; ??? Currently never generated - xor is used instead. 10103(define_insn "*one_cmplsi2_2_zext" 10104 [(set (reg FLAGS_REG) 10105 (compare (not:SI (match_operand:SI 1 "register_operand" "0")) 10106 (const_int 0))) 10107 (set (match_operand:DI 0 "register_operand" "=r") 10108 (zero_extend:DI (not:SI (match_dup 1))))] 10109 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 10110 && ix86_unary_operator_ok (NOT, SImode, operands)" 10111 "#" 10112 [(set_attr "type" "alu1") 10113 (set_attr "mode" "SI")]) 10114 10115(define_split 10116 [(set (match_operand 0 "flags_reg_operand" "") 10117 (match_operator 2 "compare_operator" 10118 [(not:SI (match_operand:SI 3 "register_operand" "")) 10119 (const_int 0)])) 10120 (set (match_operand:DI 1 "register_operand" "") 10121 (zero_extend:DI (not:SI (match_dup 3))))] 10122 "ix86_match_ccmode (insn, CCNOmode)" 10123 [(parallel [(set (match_dup 0) 10124 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 10125 (const_int 0)])) 10126 (set (match_dup 1) 10127 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])] 10128 "") 10129 10130(define_expand "one_cmplhi2" 10131 [(set (match_operand:HI 0 "nonimmediate_operand" "") 10132 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))] 10133 "TARGET_HIMODE_MATH" 10134 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;") 10135 10136(define_insn "*one_cmplhi2_1" 10137 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10138 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] 10139 "ix86_unary_operator_ok (NOT, HImode, operands)" 10140 "not{w}\t%0" 10141 [(set_attr "type" "negnot") 10142 (set_attr "mode" "HI")]) 10143 10144(define_insn "*one_cmplhi2_2" 10145 [(set (reg FLAGS_REG) 10146 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")) 10147 (const_int 0))) 10148 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10149 (not:HI (match_dup 1)))] 10150 "ix86_match_ccmode (insn, CCNOmode) 10151 && ix86_unary_operator_ok (NEG, HImode, operands)" 10152 "#" 10153 [(set_attr "type" "alu1") 10154 (set_attr "mode" "HI")]) 10155 10156(define_split 10157 [(set (match_operand 0 "flags_reg_operand" "") 10158 (match_operator 2 "compare_operator" 10159 [(not:HI (match_operand:HI 3 "nonimmediate_operand" "")) 10160 (const_int 0)])) 10161 (set (match_operand:HI 1 "nonimmediate_operand" "") 10162 (not:HI (match_dup 3)))] 10163 "ix86_match_ccmode (insn, CCNOmode)" 10164 [(parallel [(set (match_dup 0) 10165 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1)) 10166 (const_int 0)])) 10167 (set (match_dup 1) 10168 (xor:HI (match_dup 3) (const_int -1)))])] 10169 "") 10170 10171;; %%% Potential partial reg stall on alternative 1. What to do? 10172(define_expand "one_cmplqi2" 10173 [(set (match_operand:QI 0 "nonimmediate_operand" "") 10174 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))] 10175 "TARGET_QIMODE_MATH" 10176 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;") 10177 10178(define_insn "*one_cmplqi2_1" 10179 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") 10180 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] 10181 "ix86_unary_operator_ok (NOT, QImode, operands)" 10182 "@ 10183 not{b}\t%0 10184 not{l}\t%k0" 10185 [(set_attr "type" "negnot") 10186 (set_attr "mode" "QI,SI")]) 10187 10188(define_insn "*one_cmplqi2_2" 10189 [(set (reg FLAGS_REG) 10190 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")) 10191 (const_int 0))) 10192 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 10193 (not:QI (match_dup 1)))] 10194 "ix86_match_ccmode (insn, CCNOmode) 10195 && ix86_unary_operator_ok (NOT, QImode, operands)" 10196 "#" 10197 [(set_attr "type" "alu1") 10198 (set_attr "mode" "QI")]) 10199 10200(define_split 10201 [(set (match_operand 0 "flags_reg_operand" "") 10202 (match_operator 2 "compare_operator" 10203 [(not:QI (match_operand:QI 3 "nonimmediate_operand" "")) 10204 (const_int 0)])) 10205 (set (match_operand:QI 1 "nonimmediate_operand" "") 10206 (not:QI (match_dup 3)))] 10207 "ix86_match_ccmode (insn, CCNOmode)" 10208 [(parallel [(set (match_dup 0) 10209 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1)) 10210 (const_int 0)])) 10211 (set (match_dup 1) 10212 (xor:QI (match_dup 3) (const_int -1)))])] 10213 "") 10214 10215;; Arithmetic shift instructions 10216 10217;; DImode shifts are implemented using the i386 "shift double" opcode, 10218;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count 10219;; is variable, then the count is in %cl and the "imm" operand is dropped 10220;; from the assembler input. 10221;; 10222;; This instruction shifts the target reg/mem as usual, but instead of 10223;; shifting in zeros, bits are shifted in from reg operand. If the insn 10224;; is a left shift double, bits are taken from the high order bits of 10225;; reg, else if the insn is a shift right double, bits are taken from the 10226;; low order bits of reg. So if %eax is "1234" and %edx is "5678", 10227;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". 10228;; 10229;; Since sh[lr]d does not change the `reg' operand, that is done 10230;; separately, making all shifts emit pairs of shift double and normal 10231;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to 10232;; support a 63 bit shift, each shift where the count is in a reg expands 10233;; to a pair of shifts, a branch, a shift by 32 and a label. 10234;; 10235;; If the shift count is a constant, we need never emit more than one 10236;; shift pair, instead using moves and sign extension for counts greater 10237;; than 31. 10238 10239(define_expand "ashlti3" 10240 [(parallel [(set (match_operand:TI 0 "register_operand" "") 10241 (ashift:TI (match_operand:TI 1 "register_operand" "") 10242 (match_operand:QI 2 "nonmemory_operand" ""))) 10243 (clobber (reg:CC FLAGS_REG))])] 10244 "TARGET_64BIT" 10245{ 10246 if (! immediate_operand (operands[2], QImode)) 10247 { 10248 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2])); 10249 DONE; 10250 } 10251 ix86_expand_binary_operator (ASHIFT, TImode, operands); 10252 DONE; 10253}) 10254 10255(define_insn "ashlti3_1" 10256 [(set (match_operand:TI 0 "register_operand" "=r") 10257 (ashift:TI (match_operand:TI 1 "register_operand" "0") 10258 (match_operand:QI 2 "register_operand" "c"))) 10259 (clobber (match_scratch:DI 3 "=&r")) 10260 (clobber (reg:CC FLAGS_REG))] 10261 "TARGET_64BIT" 10262 "#" 10263 [(set_attr "type" "multi")]) 10264 10265(define_insn "*ashlti3_2" 10266 [(set (match_operand:TI 0 "register_operand" "=r") 10267 (ashift:TI (match_operand:TI 1 "register_operand" "0") 10268 (match_operand:QI 2 "immediate_operand" "O"))) 10269 (clobber (reg:CC FLAGS_REG))] 10270 "TARGET_64BIT" 10271 "#" 10272 [(set_attr "type" "multi")]) 10273 10274(define_split 10275 [(set (match_operand:TI 0 "register_operand" "") 10276 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "") 10277 (match_operand:QI 2 "register_operand" ""))) 10278 (clobber (match_scratch:DI 3 "")) 10279 (clobber (reg:CC FLAGS_REG))] 10280 "TARGET_64BIT && reload_completed" 10281 [(const_int 0)] 10282 "ix86_split_ashl (operands, operands[3], TImode); DONE;") 10283 10284(define_split 10285 [(set (match_operand:TI 0 "register_operand" "") 10286 (ashift:TI (match_operand:TI 1 "register_operand" "") 10287 (match_operand:QI 2 "immediate_operand" ""))) 10288 (clobber (reg:CC FLAGS_REG))] 10289 "TARGET_64BIT && reload_completed" 10290 [(const_int 0)] 10291 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;") 10292 10293(define_insn "x86_64_shld" 10294 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m") 10295 (ior:DI (ashift:DI (match_dup 0) 10296 (match_operand:QI 2 "nonmemory_operand" "J,c")) 10297 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r") 10298 (minus:QI (const_int 64) (match_dup 2))))) 10299 (clobber (reg:CC FLAGS_REG))] 10300 "TARGET_64BIT" 10301 "@ 10302 shld{q}\t{%2, %1, %0|%0, %1, %2} 10303 shld{q}\t{%s2%1, %0|%0, %1, %2}" 10304 [(set_attr "type" "ishift") 10305 (set_attr "prefix_0f" "1") 10306 (set_attr "mode" "DI") 10307 (set_attr "athlon_decode" "vector")]) 10308 10309(define_expand "x86_64_shift_adj" 10310 [(set (reg:CCZ FLAGS_REG) 10311 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "") 10312 (const_int 64)) 10313 (const_int 0))) 10314 (set (match_operand:DI 0 "register_operand" "") 10315 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10316 (match_operand:DI 1 "register_operand" "") 10317 (match_dup 0))) 10318 (set (match_dup 1) 10319 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10320 (match_operand:DI 3 "register_operand" "r") 10321 (match_dup 1)))] 10322 "TARGET_64BIT" 10323 "") 10324 10325(define_expand "ashldi3" 10326 [(set (match_operand:DI 0 "shiftdi_operand" "") 10327 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "") 10328 (match_operand:QI 2 "nonmemory_operand" "")))] 10329 "" 10330 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;") 10331 10332(define_insn "*ashldi3_1_rex64" 10333 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 10334 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l") 10335 (match_operand:QI 2 "nonmemory_operand" "cJ,M"))) 10336 (clobber (reg:CC FLAGS_REG))] 10337 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)" 10338{ 10339 switch (get_attr_type (insn)) 10340 { 10341 case TYPE_ALU: 10342 gcc_assert (operands[2] == const1_rtx); 10343 gcc_assert (rtx_equal_p (operands[0], operands[1])); 10344 return "add{q}\t{%0, %0|%0, %0}"; 10345 10346 case TYPE_LEA: 10347 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 10348 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3); 10349 operands[1] = gen_rtx_MULT (DImode, operands[1], 10350 GEN_INT (1 << INTVAL (operands[2]))); 10351 return "lea{q}\t{%a1, %0|%0, %a1}"; 10352 10353 default: 10354 if (REG_P (operands[2])) 10355 return "sal{q}\t{%b2, %0|%0, %b2}"; 10356 else if (operands[2] == const1_rtx 10357 && (TARGET_SHIFT1 || optimize_size)) 10358 return "sal{q}\t%0"; 10359 else 10360 return "sal{q}\t{%2, %0|%0, %2}"; 10361 } 10362} 10363 [(set (attr "type") 10364 (cond [(eq_attr "alternative" "1") 10365 (const_string "lea") 10366 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10367 (const_int 0)) 10368 (match_operand 0 "register_operand" "")) 10369 (match_operand 2 "const1_operand" "")) 10370 (const_string "alu") 10371 ] 10372 (const_string "ishift"))) 10373 (set_attr "mode" "DI")]) 10374 10375;; Convert lea to the lea pattern to avoid flags dependency. 10376(define_split 10377 [(set (match_operand:DI 0 "register_operand" "") 10378 (ashift:DI (match_operand:DI 1 "index_register_operand" "") 10379 (match_operand:QI 2 "immediate_operand" ""))) 10380 (clobber (reg:CC FLAGS_REG))] 10381 "TARGET_64BIT && reload_completed 10382 && true_regnum (operands[0]) != true_regnum (operands[1])" 10383 [(set (match_dup 0) 10384 (mult:DI (match_dup 1) 10385 (match_dup 2)))] 10386 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);") 10387 10388;; This pattern can't accept a variable shift count, since shifts by 10389;; zero don't affect the flags. We assume that shifts by constant 10390;; zero are optimized away. 10391(define_insn "*ashldi3_cmp_rex64" 10392 [(set (reg FLAGS_REG) 10393 (compare 10394 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0") 10395 (match_operand:QI 2 "immediate_operand" "e")) 10396 (const_int 0))) 10397 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 10398 (ashift:DI (match_dup 1) (match_dup 2)))] 10399 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 10400 && ix86_binary_operator_ok (ASHIFT, DImode, operands) 10401 && (optimize_size 10402 || !TARGET_PARTIAL_FLAG_REG_STALL 10403 || (operands[2] == const1_rtx 10404 && (TARGET_SHIFT1 10405 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 10406{ 10407 switch (get_attr_type (insn)) 10408 { 10409 case TYPE_ALU: 10410 gcc_assert (operands[2] == const1_rtx); 10411 return "add{q}\t{%0, %0|%0, %0}"; 10412 10413 default: 10414 if (REG_P (operands[2])) 10415 return "sal{q}\t{%b2, %0|%0, %b2}"; 10416 else if (operands[2] == const1_rtx 10417 && (TARGET_SHIFT1 || optimize_size)) 10418 return "sal{q}\t%0"; 10419 else 10420 return "sal{q}\t{%2, %0|%0, %2}"; 10421 } 10422} 10423 [(set (attr "type") 10424 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10425 (const_int 0)) 10426 (match_operand 0 "register_operand" "")) 10427 (match_operand 2 "const1_operand" "")) 10428 (const_string "alu") 10429 ] 10430 (const_string "ishift"))) 10431 (set_attr "mode" "DI")]) 10432 10433(define_insn "*ashldi3_cconly_rex64" 10434 [(set (reg FLAGS_REG) 10435 (compare 10436 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0") 10437 (match_operand:QI 2 "immediate_operand" "e")) 10438 (const_int 0))) 10439 (clobber (match_scratch:DI 0 "=r"))] 10440 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 10441 && ix86_binary_operator_ok (ASHIFT, DImode, operands) 10442 && (optimize_size 10443 || !TARGET_PARTIAL_FLAG_REG_STALL 10444 || (operands[2] == const1_rtx 10445 && (TARGET_SHIFT1 10446 || TARGET_DOUBLE_WITH_ADD)))" 10447{ 10448 switch (get_attr_type (insn)) 10449 { 10450 case TYPE_ALU: 10451 gcc_assert (operands[2] == const1_rtx); 10452 return "add{q}\t{%0, %0|%0, %0}"; 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 [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10466 (const_int 0)) 10467 (match_operand 0 "register_operand" "")) 10468 (match_operand 2 "const1_operand" "")) 10469 (const_string "alu") 10470 ] 10471 (const_string "ishift"))) 10472 (set_attr "mode" "DI")]) 10473 10474(define_insn "*ashldi3_1" 10475 [(set (match_operand:DI 0 "register_operand" "=&r,r") 10476 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0") 10477 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc"))) 10478 (clobber (reg:CC FLAGS_REG))] 10479 "!TARGET_64BIT" 10480 "#" 10481 [(set_attr "type" "multi")]) 10482 10483;; By default we don't ask for a scratch register, because when DImode 10484;; values are manipulated, registers are already at a premium. But if 10485;; we have one handy, we won't turn it away. 10486(define_peephole2 10487 [(match_scratch:SI 3 "r") 10488 (parallel [(set (match_operand:DI 0 "register_operand" "") 10489 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "") 10490 (match_operand:QI 2 "nonmemory_operand" ""))) 10491 (clobber (reg:CC FLAGS_REG))]) 10492 (match_dup 3)] 10493 "!TARGET_64BIT && TARGET_CMOVE" 10494 [(const_int 0)] 10495 "ix86_split_ashl (operands, operands[3], DImode); DONE;") 10496 10497(define_split 10498 [(set (match_operand:DI 0 "register_operand" "") 10499 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "") 10500 (match_operand:QI 2 "nonmemory_operand" ""))) 10501 (clobber (reg:CC FLAGS_REG))] 10502 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) 10503 ? flow2_completed : reload_completed)" 10504 [(const_int 0)] 10505 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;") 10506 10507(define_insn "x86_shld_1" 10508 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m") 10509 (ior:SI (ashift:SI (match_dup 0) 10510 (match_operand:QI 2 "nonmemory_operand" "I,c")) 10511 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") 10512 (minus:QI (const_int 32) (match_dup 2))))) 10513 (clobber (reg:CC FLAGS_REG))] 10514 "" 10515 "@ 10516 shld{l}\t{%2, %1, %0|%0, %1, %2} 10517 shld{l}\t{%s2%1, %0|%0, %1, %2}" 10518 [(set_attr "type" "ishift") 10519 (set_attr "prefix_0f" "1") 10520 (set_attr "mode" "SI") 10521 (set_attr "pent_pair" "np") 10522 (set_attr "athlon_decode" "vector")]) 10523 10524(define_expand "x86_shift_adj_1" 10525 [(set (reg:CCZ FLAGS_REG) 10526 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "") 10527 (const_int 32)) 10528 (const_int 0))) 10529 (set (match_operand:SI 0 "register_operand" "") 10530 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10531 (match_operand:SI 1 "register_operand" "") 10532 (match_dup 0))) 10533 (set (match_dup 1) 10534 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10535 (match_operand:SI 3 "register_operand" "r") 10536 (match_dup 1)))] 10537 "TARGET_CMOVE" 10538 "") 10539 10540(define_expand "x86_shift_adj_2" 10541 [(use (match_operand:SI 0 "register_operand" "")) 10542 (use (match_operand:SI 1 "register_operand" "")) 10543 (use (match_operand:QI 2 "register_operand" ""))] 10544 "" 10545{ 10546 rtx label = gen_label_rtx (); 10547 rtx tmp; 10548 10549 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32))); 10550 10551 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 10552 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 10553 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 10554 gen_rtx_LABEL_REF (VOIDmode, label), 10555 pc_rtx); 10556 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 10557 JUMP_LABEL (tmp) = label; 10558 10559 emit_move_insn (operands[0], operands[1]); 10560 ix86_expand_clear (operands[1]); 10561 10562 emit_label (label); 10563 LABEL_NUSES (label) = 1; 10564 10565 DONE; 10566}) 10567 10568(define_expand "ashlsi3" 10569 [(set (match_operand:SI 0 "nonimmediate_operand" "") 10570 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "") 10571 (match_operand:QI 2 "nonmemory_operand" ""))) 10572 (clobber (reg:CC FLAGS_REG))] 10573 "" 10574 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;") 10575 10576(define_insn "*ashlsi3_1" 10577 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 10578 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l") 10579 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 10580 (clobber (reg:CC FLAGS_REG))] 10581 "ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10582{ 10583 switch (get_attr_type (insn)) 10584 { 10585 case TYPE_ALU: 10586 gcc_assert (operands[2] == const1_rtx); 10587 gcc_assert (rtx_equal_p (operands[0], operands[1])); 10588 return "add{l}\t{%0, %0|%0, %0}"; 10589 10590 case TYPE_LEA: 10591 return "#"; 10592 10593 default: 10594 if (REG_P (operands[2])) 10595 return "sal{l}\t{%b2, %0|%0, %b2}"; 10596 else if (operands[2] == const1_rtx 10597 && (TARGET_SHIFT1 || optimize_size)) 10598 return "sal{l}\t%0"; 10599 else 10600 return "sal{l}\t{%2, %0|%0, %2}"; 10601 } 10602} 10603 [(set (attr "type") 10604 (cond [(eq_attr "alternative" "1") 10605 (const_string "lea") 10606 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10607 (const_int 0)) 10608 (match_operand 0 "register_operand" "")) 10609 (match_operand 2 "const1_operand" "")) 10610 (const_string "alu") 10611 ] 10612 (const_string "ishift"))) 10613 (set_attr "mode" "SI")]) 10614 10615;; Convert lea to the lea pattern to avoid flags dependency. 10616(define_split 10617 [(set (match_operand 0 "register_operand" "") 10618 (ashift (match_operand 1 "index_register_operand" "") 10619 (match_operand:QI 2 "const_int_operand" ""))) 10620 (clobber (reg:CC FLAGS_REG))] 10621 "reload_completed 10622 && true_regnum (operands[0]) != true_regnum (operands[1]) 10623 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4" 10624 [(const_int 0)] 10625{ 10626 rtx pat; 10627 enum machine_mode mode = GET_MODE (operands[0]); 10628 10629 if (GET_MODE_SIZE (mode) < 4) 10630 operands[0] = gen_lowpart (SImode, operands[0]); 10631 if (mode != Pmode) 10632 operands[1] = gen_lowpart (Pmode, operands[1]); 10633 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode); 10634 10635 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]); 10636 if (Pmode != SImode) 10637 pat = gen_rtx_SUBREG (SImode, pat, 0); 10638 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 10639 DONE; 10640}) 10641 10642;; Rare case of shifting RSP is handled by generating move and shift 10643(define_split 10644 [(set (match_operand 0 "register_operand" "") 10645 (ashift (match_operand 1 "register_operand" "") 10646 (match_operand:QI 2 "const_int_operand" ""))) 10647 (clobber (reg:CC FLAGS_REG))] 10648 "reload_completed 10649 && true_regnum (operands[0]) != true_regnum (operands[1])" 10650 [(const_int 0)] 10651{ 10652 rtx pat, clob; 10653 emit_move_insn (operands[0], operands[1]); 10654 pat = gen_rtx_SET (VOIDmode, operands[0], 10655 gen_rtx_ASHIFT (GET_MODE (operands[0]), 10656 operands[0], operands[2])); 10657 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); 10658 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob))); 10659 DONE; 10660}) 10661 10662(define_insn "*ashlsi3_1_zext" 10663 [(set (match_operand:DI 0 "register_operand" "=r,r") 10664 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l") 10665 (match_operand:QI 2 "nonmemory_operand" "cI,M")))) 10666 (clobber (reg:CC FLAGS_REG))] 10667 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10668{ 10669 switch (get_attr_type (insn)) 10670 { 10671 case TYPE_ALU: 10672 gcc_assert (operands[2] == const1_rtx); 10673 return "add{l}\t{%k0, %k0|%k0, %k0}"; 10674 10675 case TYPE_LEA: 10676 return "#"; 10677 10678 default: 10679 if (REG_P (operands[2])) 10680 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 10681 else if (operands[2] == const1_rtx 10682 && (TARGET_SHIFT1 || optimize_size)) 10683 return "sal{l}\t%k0"; 10684 else 10685 return "sal{l}\t{%2, %k0|%k0, %2}"; 10686 } 10687} 10688 [(set (attr "type") 10689 (cond [(eq_attr "alternative" "1") 10690 (const_string "lea") 10691 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10692 (const_int 0)) 10693 (match_operand 2 "const1_operand" "")) 10694 (const_string "alu") 10695 ] 10696 (const_string "ishift"))) 10697 (set_attr "mode" "SI")]) 10698 10699;; Convert lea to the lea pattern to avoid flags dependency. 10700(define_split 10701 [(set (match_operand:DI 0 "register_operand" "") 10702 (zero_extend:DI (ashift (match_operand 1 "register_operand" "") 10703 (match_operand:QI 2 "const_int_operand" "")))) 10704 (clobber (reg:CC FLAGS_REG))] 10705 "TARGET_64BIT && reload_completed 10706 && true_regnum (operands[0]) != true_regnum (operands[1])" 10707 [(set (match_dup 0) (zero_extend:DI 10708 (subreg:SI (mult:SI (match_dup 1) 10709 (match_dup 2)) 0)))] 10710{ 10711 operands[1] = gen_lowpart (Pmode, operands[1]); 10712 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode); 10713}) 10714 10715;; This pattern can't accept a variable shift count, since shifts by 10716;; zero don't affect the flags. We assume that shifts by constant 10717;; zero are optimized away. 10718(define_insn "*ashlsi3_cmp" 10719 [(set (reg FLAGS_REG) 10720 (compare 10721 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0") 10722 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10723 (const_int 0))) 10724 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 10725 (ashift:SI (match_dup 1) (match_dup 2)))] 10726 "ix86_match_ccmode (insn, CCGOCmode) 10727 && ix86_binary_operator_ok (ASHIFT, SImode, operands) 10728 && (optimize_size 10729 || !TARGET_PARTIAL_FLAG_REG_STALL 10730 || (operands[2] == const1_rtx 10731 && (TARGET_SHIFT1 10732 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 10733{ 10734 switch (get_attr_type (insn)) 10735 { 10736 case TYPE_ALU: 10737 gcc_assert (operands[2] == const1_rtx); 10738 return "add{l}\t{%0, %0|%0, %0}"; 10739 10740 default: 10741 if (REG_P (operands[2])) 10742 return "sal{l}\t{%b2, %0|%0, %b2}"; 10743 else if (operands[2] == const1_rtx 10744 && (TARGET_SHIFT1 || optimize_size)) 10745 return "sal{l}\t%0"; 10746 else 10747 return "sal{l}\t{%2, %0|%0, %2}"; 10748 } 10749} 10750 [(set (attr "type") 10751 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10752 (const_int 0)) 10753 (match_operand 0 "register_operand" "")) 10754 (match_operand 2 "const1_operand" "")) 10755 (const_string "alu") 10756 ] 10757 (const_string "ishift"))) 10758 (set_attr "mode" "SI")]) 10759 10760(define_insn "*ashlsi3_cconly" 10761 [(set (reg FLAGS_REG) 10762 (compare 10763 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0") 10764 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10765 (const_int 0))) 10766 (clobber (match_scratch:SI 0 "=r"))] 10767 "ix86_match_ccmode (insn, CCGOCmode) 10768 && ix86_binary_operator_ok (ASHIFT, SImode, operands) 10769 && (optimize_size 10770 || !TARGET_PARTIAL_FLAG_REG_STALL 10771 || (operands[2] == const1_rtx 10772 && (TARGET_SHIFT1 10773 || TARGET_DOUBLE_WITH_ADD)))" 10774{ 10775 switch (get_attr_type (insn)) 10776 { 10777 case TYPE_ALU: 10778 gcc_assert (operands[2] == const1_rtx); 10779 return "add{l}\t{%0, %0|%0, %0}"; 10780 10781 default: 10782 if (REG_P (operands[2])) 10783 return "sal{l}\t{%b2, %0|%0, %b2}"; 10784 else if (operands[2] == const1_rtx 10785 && (TARGET_SHIFT1 || optimize_size)) 10786 return "sal{l}\t%0"; 10787 else 10788 return "sal{l}\t{%2, %0|%0, %2}"; 10789 } 10790} 10791 [(set (attr "type") 10792 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10793 (const_int 0)) 10794 (match_operand 0 "register_operand" "")) 10795 (match_operand 2 "const1_operand" "")) 10796 (const_string "alu") 10797 ] 10798 (const_string "ishift"))) 10799 (set_attr "mode" "SI")]) 10800 10801(define_insn "*ashlsi3_cmp_zext" 10802 [(set (reg FLAGS_REG) 10803 (compare 10804 (ashift:SI (match_operand:SI 1 "register_operand" "0") 10805 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10806 (const_int 0))) 10807 (set (match_operand:DI 0 "register_operand" "=r") 10808 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 10809 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 10810 && ix86_binary_operator_ok (ASHIFT, SImode, operands) 10811 && (optimize_size 10812 || !TARGET_PARTIAL_FLAG_REG_STALL 10813 || (operands[2] == const1_rtx 10814 && (TARGET_SHIFT1 10815 || TARGET_DOUBLE_WITH_ADD)))" 10816{ 10817 switch (get_attr_type (insn)) 10818 { 10819 case TYPE_ALU: 10820 gcc_assert (operands[2] == const1_rtx); 10821 return "add{l}\t{%k0, %k0|%k0, %k0}"; 10822 10823 default: 10824 if (REG_P (operands[2])) 10825 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 10826 else if (operands[2] == const1_rtx 10827 && (TARGET_SHIFT1 || optimize_size)) 10828 return "sal{l}\t%k0"; 10829 else 10830 return "sal{l}\t{%2, %k0|%k0, %2}"; 10831 } 10832} 10833 [(set (attr "type") 10834 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10835 (const_int 0)) 10836 (match_operand 2 "const1_operand" "")) 10837 (const_string "alu") 10838 ] 10839 (const_string "ishift"))) 10840 (set_attr "mode" "SI")]) 10841 10842(define_expand "ashlhi3" 10843 [(set (match_operand:HI 0 "nonimmediate_operand" "") 10844 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "") 10845 (match_operand:QI 2 "nonmemory_operand" ""))) 10846 (clobber (reg:CC FLAGS_REG))] 10847 "TARGET_HIMODE_MATH" 10848 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;") 10849 10850(define_insn "*ashlhi3_1_lea" 10851 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 10852 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l") 10853 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 10854 (clobber (reg:CC FLAGS_REG))] 10855 "!TARGET_PARTIAL_REG_STALL 10856 && ix86_binary_operator_ok (ASHIFT, HImode, operands)" 10857{ 10858 switch (get_attr_type (insn)) 10859 { 10860 case TYPE_LEA: 10861 return "#"; 10862 case TYPE_ALU: 10863 gcc_assert (operands[2] == const1_rtx); 10864 return "add{w}\t{%0, %0|%0, %0}"; 10865 10866 default: 10867 if (REG_P (operands[2])) 10868 return "sal{w}\t{%b2, %0|%0, %b2}"; 10869 else if (operands[2] == const1_rtx 10870 && (TARGET_SHIFT1 || optimize_size)) 10871 return "sal{w}\t%0"; 10872 else 10873 return "sal{w}\t{%2, %0|%0, %2}"; 10874 } 10875} 10876 [(set (attr "type") 10877 (cond [(eq_attr "alternative" "1") 10878 (const_string "lea") 10879 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10880 (const_int 0)) 10881 (match_operand 0 "register_operand" "")) 10882 (match_operand 2 "const1_operand" "")) 10883 (const_string "alu") 10884 ] 10885 (const_string "ishift"))) 10886 (set_attr "mode" "HI,SI")]) 10887 10888(define_insn "*ashlhi3_1" 10889 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10890 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") 10891 (match_operand:QI 2 "nonmemory_operand" "cI"))) 10892 (clobber (reg:CC FLAGS_REG))] 10893 "TARGET_PARTIAL_REG_STALL 10894 && ix86_binary_operator_ok (ASHIFT, HImode, operands)" 10895{ 10896 switch (get_attr_type (insn)) 10897 { 10898 case TYPE_ALU: 10899 gcc_assert (operands[2] == const1_rtx); 10900 return "add{w}\t{%0, %0|%0, %0}"; 10901 10902 default: 10903 if (REG_P (operands[2])) 10904 return "sal{w}\t{%b2, %0|%0, %b2}"; 10905 else if (operands[2] == const1_rtx 10906 && (TARGET_SHIFT1 || optimize_size)) 10907 return "sal{w}\t%0"; 10908 else 10909 return "sal{w}\t{%2, %0|%0, %2}"; 10910 } 10911} 10912 [(set (attr "type") 10913 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10914 (const_int 0)) 10915 (match_operand 0 "register_operand" "")) 10916 (match_operand 2 "const1_operand" "")) 10917 (const_string "alu") 10918 ] 10919 (const_string "ishift"))) 10920 (set_attr "mode" "HI")]) 10921 10922;; This pattern can't accept a variable shift count, since shifts by 10923;; zero don't affect the flags. We assume that shifts by constant 10924;; zero are optimized away. 10925(define_insn "*ashlhi3_cmp" 10926 [(set (reg FLAGS_REG) 10927 (compare 10928 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") 10929 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10930 (const_int 0))) 10931 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10932 (ashift:HI (match_dup 1) (match_dup 2)))] 10933 "ix86_match_ccmode (insn, CCGOCmode) 10934 && ix86_binary_operator_ok (ASHIFT, HImode, operands) 10935 && (optimize_size 10936 || !TARGET_PARTIAL_FLAG_REG_STALL 10937 || (operands[2] == const1_rtx 10938 && (TARGET_SHIFT1 10939 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 10940{ 10941 switch (get_attr_type (insn)) 10942 { 10943 case TYPE_ALU: 10944 gcc_assert (operands[2] == const1_rtx); 10945 return "add{w}\t{%0, %0|%0, %0}"; 10946 10947 default: 10948 if (REG_P (operands[2])) 10949 return "sal{w}\t{%b2, %0|%0, %b2}"; 10950 else if (operands[2] == const1_rtx 10951 && (TARGET_SHIFT1 || optimize_size)) 10952 return "sal{w}\t%0"; 10953 else 10954 return "sal{w}\t{%2, %0|%0, %2}"; 10955 } 10956} 10957 [(set (attr "type") 10958 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10959 (const_int 0)) 10960 (match_operand 0 "register_operand" "")) 10961 (match_operand 2 "const1_operand" "")) 10962 (const_string "alu") 10963 ] 10964 (const_string "ishift"))) 10965 (set_attr "mode" "HI")]) 10966 10967(define_insn "*ashlhi3_cconly" 10968 [(set (reg FLAGS_REG) 10969 (compare 10970 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") 10971 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10972 (const_int 0))) 10973 (clobber (match_scratch:HI 0 "=r"))] 10974 "ix86_match_ccmode (insn, CCGOCmode) 10975 && ix86_binary_operator_ok (ASHIFT, HImode, operands) 10976 && (optimize_size 10977 || !TARGET_PARTIAL_FLAG_REG_STALL 10978 || (operands[2] == const1_rtx 10979 && (TARGET_SHIFT1 10980 || TARGET_DOUBLE_WITH_ADD)))" 10981{ 10982 switch (get_attr_type (insn)) 10983 { 10984 case TYPE_ALU: 10985 gcc_assert (operands[2] == const1_rtx); 10986 return "add{w}\t{%0, %0|%0, %0}"; 10987 10988 default: 10989 if (REG_P (operands[2])) 10990 return "sal{w}\t{%b2, %0|%0, %b2}"; 10991 else if (operands[2] == const1_rtx 10992 && (TARGET_SHIFT1 || optimize_size)) 10993 return "sal{w}\t%0"; 10994 else 10995 return "sal{w}\t{%2, %0|%0, %2}"; 10996 } 10997} 10998 [(set (attr "type") 10999 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11000 (const_int 0)) 11001 (match_operand 0 "register_operand" "")) 11002 (match_operand 2 "const1_operand" "")) 11003 (const_string "alu") 11004 ] 11005 (const_string "ishift"))) 11006 (set_attr "mode" "HI")]) 11007 11008(define_expand "ashlqi3" 11009 [(set (match_operand:QI 0 "nonimmediate_operand" "") 11010 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "") 11011 (match_operand:QI 2 "nonmemory_operand" ""))) 11012 (clobber (reg:CC FLAGS_REG))] 11013 "TARGET_QIMODE_MATH" 11014 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;") 11015 11016;; %%% Potential partial reg stall on alternative 2. What to do? 11017 11018(define_insn "*ashlqi3_1_lea" 11019 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r") 11020 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l") 11021 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M"))) 11022 (clobber (reg:CC FLAGS_REG))] 11023 "!TARGET_PARTIAL_REG_STALL 11024 && ix86_binary_operator_ok (ASHIFT, QImode, operands)" 11025{ 11026 switch (get_attr_type (insn)) 11027 { 11028 case TYPE_LEA: 11029 return "#"; 11030 case TYPE_ALU: 11031 gcc_assert (operands[2] == const1_rtx); 11032 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) 11033 return "add{l}\t{%k0, %k0|%k0, %k0}"; 11034 else 11035 return "add{b}\t{%0, %0|%0, %0}"; 11036 11037 default: 11038 if (REG_P (operands[2])) 11039 { 11040 if (get_attr_mode (insn) == MODE_SI) 11041 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 11042 else 11043 return "sal{b}\t{%b2, %0|%0, %b2}"; 11044 } 11045 else if (operands[2] == const1_rtx 11046 && (TARGET_SHIFT1 || optimize_size)) 11047 { 11048 if (get_attr_mode (insn) == MODE_SI) 11049 return "sal{l}\t%0"; 11050 else 11051 return "sal{b}\t%0"; 11052 } 11053 else 11054 { 11055 if (get_attr_mode (insn) == MODE_SI) 11056 return "sal{l}\t{%2, %k0|%k0, %2}"; 11057 else 11058 return "sal{b}\t{%2, %0|%0, %2}"; 11059 } 11060 } 11061} 11062 [(set (attr "type") 11063 (cond [(eq_attr "alternative" "2") 11064 (const_string "lea") 11065 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11066 (const_int 0)) 11067 (match_operand 0 "register_operand" "")) 11068 (match_operand 2 "const1_operand" "")) 11069 (const_string "alu") 11070 ] 11071 (const_string "ishift"))) 11072 (set_attr "mode" "QI,SI,SI")]) 11073 11074(define_insn "*ashlqi3_1" 11075 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") 11076 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 11077 (match_operand:QI 2 "nonmemory_operand" "cI,cI"))) 11078 (clobber (reg:CC FLAGS_REG))] 11079 "TARGET_PARTIAL_REG_STALL 11080 && ix86_binary_operator_ok (ASHIFT, QImode, operands)" 11081{ 11082 switch (get_attr_type (insn)) 11083 { 11084 case TYPE_ALU: 11085 gcc_assert (operands[2] == const1_rtx); 11086 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) 11087 return "add{l}\t{%k0, %k0|%k0, %k0}"; 11088 else 11089 return "add{b}\t{%0, %0|%0, %0}"; 11090 11091 default: 11092 if (REG_P (operands[2])) 11093 { 11094 if (get_attr_mode (insn) == MODE_SI) 11095 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 11096 else 11097 return "sal{b}\t{%b2, %0|%0, %b2}"; 11098 } 11099 else if (operands[2] == const1_rtx 11100 && (TARGET_SHIFT1 || optimize_size)) 11101 { 11102 if (get_attr_mode (insn) == MODE_SI) 11103 return "sal{l}\t%0"; 11104 else 11105 return "sal{b}\t%0"; 11106 } 11107 else 11108 { 11109 if (get_attr_mode (insn) == MODE_SI) 11110 return "sal{l}\t{%2, %k0|%k0, %2}"; 11111 else 11112 return "sal{b}\t{%2, %0|%0, %2}"; 11113 } 11114 } 11115} 11116 [(set (attr "type") 11117 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11118 (const_int 0)) 11119 (match_operand 0 "register_operand" "")) 11120 (match_operand 2 "const1_operand" "")) 11121 (const_string "alu") 11122 ] 11123 (const_string "ishift"))) 11124 (set_attr "mode" "QI,SI")]) 11125 11126;; This pattern can't accept a variable shift count, since shifts by 11127;; zero don't affect the flags. We assume that shifts by constant 11128;; zero are optimized away. 11129(define_insn "*ashlqi3_cmp" 11130 [(set (reg FLAGS_REG) 11131 (compare 11132 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11133 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11134 (const_int 0))) 11135 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11136 (ashift:QI (match_dup 1) (match_dup 2)))] 11137 "ix86_match_ccmode (insn, CCGOCmode) 11138 && ix86_binary_operator_ok (ASHIFT, QImode, operands) 11139 && (optimize_size 11140 || !TARGET_PARTIAL_FLAG_REG_STALL 11141 || (operands[2] == const1_rtx 11142 && (TARGET_SHIFT1 11143 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 11144{ 11145 switch (get_attr_type (insn)) 11146 { 11147 case TYPE_ALU: 11148 gcc_assert (operands[2] == const1_rtx); 11149 return "add{b}\t{%0, %0|%0, %0}"; 11150 11151 default: 11152 if (REG_P (operands[2])) 11153 return "sal{b}\t{%b2, %0|%0, %b2}"; 11154 else if (operands[2] == const1_rtx 11155 && (TARGET_SHIFT1 || optimize_size)) 11156 return "sal{b}\t%0"; 11157 else 11158 return "sal{b}\t{%2, %0|%0, %2}"; 11159 } 11160} 11161 [(set (attr "type") 11162 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11163 (const_int 0)) 11164 (match_operand 0 "register_operand" "")) 11165 (match_operand 2 "const1_operand" "")) 11166 (const_string "alu") 11167 ] 11168 (const_string "ishift"))) 11169 (set_attr "mode" "QI")]) 11170 11171(define_insn "*ashlqi3_cconly" 11172 [(set (reg FLAGS_REG) 11173 (compare 11174 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11175 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11176 (const_int 0))) 11177 (clobber (match_scratch:QI 0 "=q"))] 11178 "ix86_match_ccmode (insn, CCGOCmode) 11179 && ix86_binary_operator_ok (ASHIFT, QImode, operands) 11180 && (optimize_size 11181 || !TARGET_PARTIAL_FLAG_REG_STALL 11182 || (operands[2] == const1_rtx 11183 && (TARGET_SHIFT1 11184 || TARGET_DOUBLE_WITH_ADD)))" 11185{ 11186 switch (get_attr_type (insn)) 11187 { 11188 case TYPE_ALU: 11189 gcc_assert (operands[2] == const1_rtx); 11190 return "add{b}\t{%0, %0|%0, %0}"; 11191 11192 default: 11193 if (REG_P (operands[2])) 11194 return "sal{b}\t{%b2, %0|%0, %b2}"; 11195 else if (operands[2] == const1_rtx 11196 && (TARGET_SHIFT1 || optimize_size)) 11197 return "sal{b}\t%0"; 11198 else 11199 return "sal{b}\t{%2, %0|%0, %2}"; 11200 } 11201} 11202 [(set (attr "type") 11203 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11204 (const_int 0)) 11205 (match_operand 0 "register_operand" "")) 11206 (match_operand 2 "const1_operand" "")) 11207 (const_string "alu") 11208 ] 11209 (const_string "ishift"))) 11210 (set_attr "mode" "QI")]) 11211 11212;; See comment above `ashldi3' about how this works. 11213 11214(define_expand "ashrti3" 11215 [(parallel [(set (match_operand:TI 0 "register_operand" "") 11216 (ashiftrt:TI (match_operand:TI 1 "register_operand" "") 11217 (match_operand:QI 2 "nonmemory_operand" ""))) 11218 (clobber (reg:CC FLAGS_REG))])] 11219 "TARGET_64BIT" 11220{ 11221 if (! immediate_operand (operands[2], QImode)) 11222 { 11223 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2])); 11224 DONE; 11225 } 11226 ix86_expand_binary_operator (ASHIFTRT, TImode, operands); 11227 DONE; 11228}) 11229 11230(define_insn "ashrti3_1" 11231 [(set (match_operand:TI 0 "register_operand" "=r") 11232 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0") 11233 (match_operand:QI 2 "register_operand" "c"))) 11234 (clobber (match_scratch:DI 3 "=&r")) 11235 (clobber (reg:CC FLAGS_REG))] 11236 "TARGET_64BIT" 11237 "#" 11238 [(set_attr "type" "multi")]) 11239 11240(define_insn "*ashrti3_2" 11241 [(set (match_operand:TI 0 "register_operand" "=r") 11242 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0") 11243 (match_operand:QI 2 "immediate_operand" "O"))) 11244 (clobber (reg:CC FLAGS_REG))] 11245 "TARGET_64BIT" 11246 "#" 11247 [(set_attr "type" "multi")]) 11248 11249(define_split 11250 [(set (match_operand:TI 0 "register_operand" "") 11251 (ashiftrt:TI (match_operand:TI 1 "register_operand" "") 11252 (match_operand:QI 2 "register_operand" ""))) 11253 (clobber (match_scratch:DI 3 "")) 11254 (clobber (reg:CC FLAGS_REG))] 11255 "TARGET_64BIT && reload_completed" 11256 [(const_int 0)] 11257 "ix86_split_ashr (operands, operands[3], TImode); DONE;") 11258 11259(define_split 11260 [(set (match_operand:TI 0 "register_operand" "") 11261 (ashiftrt:TI (match_operand:TI 1 "register_operand" "") 11262 (match_operand:QI 2 "immediate_operand" ""))) 11263 (clobber (reg:CC FLAGS_REG))] 11264 "TARGET_64BIT && reload_completed" 11265 [(const_int 0)] 11266 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;") 11267 11268(define_insn "x86_64_shrd" 11269 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m") 11270 (ior:DI (ashiftrt:DI (match_dup 0) 11271 (match_operand:QI 2 "nonmemory_operand" "J,c")) 11272 (ashift:DI (match_operand:DI 1 "register_operand" "r,r") 11273 (minus:QI (const_int 64) (match_dup 2))))) 11274 (clobber (reg:CC FLAGS_REG))] 11275 "TARGET_64BIT" 11276 "@ 11277 shrd{q}\t{%2, %1, %0|%0, %1, %2} 11278 shrd{q}\t{%s2%1, %0|%0, %1, %2}" 11279 [(set_attr "type" "ishift") 11280 (set_attr "prefix_0f" "1") 11281 (set_attr "mode" "DI") 11282 (set_attr "athlon_decode" "vector")]) 11283 11284(define_expand "ashrdi3" 11285 [(set (match_operand:DI 0 "shiftdi_operand" "") 11286 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") 11287 (match_operand:QI 2 "nonmemory_operand" "")))] 11288 "" 11289 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;") 11290 11291(define_insn "*ashrdi3_63_rex64" 11292 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm") 11293 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0") 11294 (match_operand:DI 2 "const_int_operand" "i,i"))) 11295 (clobber (reg:CC FLAGS_REG))] 11296 "TARGET_64BIT && INTVAL (operands[2]) == 63 11297 && (TARGET_USE_CLTD || optimize_size) 11298 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11299 "@ 11300 {cqto|cqo} 11301 sar{q}\t{%2, %0|%0, %2}" 11302 [(set_attr "type" "imovx,ishift") 11303 (set_attr "prefix_0f" "0,*") 11304 (set_attr "length_immediate" "0,*") 11305 (set_attr "modrm" "0,1") 11306 (set_attr "mode" "DI")]) 11307 11308(define_insn "*ashrdi3_1_one_bit_rex64" 11309 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11310 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11311 (match_operand:QI 2 "const1_operand" ""))) 11312 (clobber (reg:CC FLAGS_REG))] 11313 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands) 11314 && (TARGET_SHIFT1 || optimize_size)" 11315 "sar{q}\t%0" 11316 [(set_attr "type" "ishift") 11317 (set (attr "length") 11318 (if_then_else (match_operand:DI 0 "register_operand" "") 11319 (const_string "2") 11320 (const_string "*")))]) 11321 11322(define_insn "*ashrdi3_1_rex64" 11323 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 11324 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 11325 (match_operand:QI 2 "nonmemory_operand" "J,c"))) 11326 (clobber (reg:CC FLAGS_REG))] 11327 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11328 "@ 11329 sar{q}\t{%2, %0|%0, %2} 11330 sar{q}\t{%b2, %0|%0, %b2}" 11331 [(set_attr "type" "ishift") 11332 (set_attr "mode" "DI")]) 11333 11334;; This pattern can't accept a variable shift count, since shifts by 11335;; zero don't affect the flags. We assume that shifts by constant 11336;; zero are optimized away. 11337(define_insn "*ashrdi3_one_bit_cmp_rex64" 11338 [(set (reg FLAGS_REG) 11339 (compare 11340 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11341 (match_operand:QI 2 "const1_operand" "")) 11342 (const_int 0))) 11343 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11344 (ashiftrt:DI (match_dup 1) (match_dup 2)))] 11345 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11346 && (TARGET_SHIFT1 || optimize_size) 11347 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11348 "sar{q}\t%0" 11349 [(set_attr "type" "ishift") 11350 (set (attr "length") 11351 (if_then_else (match_operand:DI 0 "register_operand" "") 11352 (const_string "2") 11353 (const_string "*")))]) 11354 11355(define_insn "*ashrdi3_one_bit_cconly_rex64" 11356 [(set (reg FLAGS_REG) 11357 (compare 11358 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11359 (match_operand:QI 2 "const1_operand" "")) 11360 (const_int 0))) 11361 (clobber (match_scratch:DI 0 "=r"))] 11362 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11363 && (TARGET_SHIFT1 || optimize_size) 11364 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11365 "sar{q}\t%0" 11366 [(set_attr "type" "ishift") 11367 (set_attr "length" "2")]) 11368 11369;; This pattern can't accept a variable shift count, since shifts by 11370;; zero don't affect the flags. We assume that shifts by constant 11371;; zero are optimized away. 11372(define_insn "*ashrdi3_cmp_rex64" 11373 [(set (reg FLAGS_REG) 11374 (compare 11375 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11376 (match_operand:QI 2 "const_int_operand" "n")) 11377 (const_int 0))) 11378 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11379 (ashiftrt:DI (match_dup 1) (match_dup 2)))] 11380 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11381 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands) 11382 && (optimize_size 11383 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11384 "sar{q}\t{%2, %0|%0, %2}" 11385 [(set_attr "type" "ishift") 11386 (set_attr "mode" "DI")]) 11387 11388(define_insn "*ashrdi3_cconly_rex64" 11389 [(set (reg FLAGS_REG) 11390 (compare 11391 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11392 (match_operand:QI 2 "const_int_operand" "n")) 11393 (const_int 0))) 11394 (clobber (match_scratch:DI 0 "=r"))] 11395 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11396 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands) 11397 && (optimize_size 11398 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11399 "sar{q}\t{%2, %0|%0, %2}" 11400 [(set_attr "type" "ishift") 11401 (set_attr "mode" "DI")]) 11402 11403(define_insn "*ashrdi3_1" 11404 [(set (match_operand:DI 0 "register_operand" "=r") 11405 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") 11406 (match_operand:QI 2 "nonmemory_operand" "Jc"))) 11407 (clobber (reg:CC FLAGS_REG))] 11408 "!TARGET_64BIT" 11409 "#" 11410 [(set_attr "type" "multi")]) 11411 11412;; By default we don't ask for a scratch register, because when DImode 11413;; values are manipulated, registers are already at a premium. But if 11414;; we have one handy, we won't turn it away. 11415(define_peephole2 11416 [(match_scratch:SI 3 "r") 11417 (parallel [(set (match_operand:DI 0 "register_operand" "") 11418 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 11419 (match_operand:QI 2 "nonmemory_operand" ""))) 11420 (clobber (reg:CC FLAGS_REG))]) 11421 (match_dup 3)] 11422 "!TARGET_64BIT && TARGET_CMOVE" 11423 [(const_int 0)] 11424 "ix86_split_ashr (operands, operands[3], DImode); DONE;") 11425 11426(define_split 11427 [(set (match_operand:DI 0 "register_operand" "") 11428 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 11429 (match_operand:QI 2 "nonmemory_operand" ""))) 11430 (clobber (reg:CC FLAGS_REG))] 11431 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) 11432 ? flow2_completed : reload_completed)" 11433 [(const_int 0)] 11434 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;") 11435 11436(define_insn "x86_shrd_1" 11437 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m") 11438 (ior:SI (ashiftrt:SI (match_dup 0) 11439 (match_operand:QI 2 "nonmemory_operand" "I,c")) 11440 (ashift:SI (match_operand:SI 1 "register_operand" "r,r") 11441 (minus:QI (const_int 32) (match_dup 2))))) 11442 (clobber (reg:CC FLAGS_REG))] 11443 "" 11444 "@ 11445 shrd{l}\t{%2, %1, %0|%0, %1, %2} 11446 shrd{l}\t{%s2%1, %0|%0, %1, %2}" 11447 [(set_attr "type" "ishift") 11448 (set_attr "prefix_0f" "1") 11449 (set_attr "pent_pair" "np") 11450 (set_attr "mode" "SI")]) 11451 11452(define_expand "x86_shift_adj_3" 11453 [(use (match_operand:SI 0 "register_operand" "")) 11454 (use (match_operand:SI 1 "register_operand" "")) 11455 (use (match_operand:QI 2 "register_operand" ""))] 11456 "" 11457{ 11458 rtx label = gen_label_rtx (); 11459 rtx tmp; 11460 11461 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32))); 11462 11463 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 11464 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 11465 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 11466 gen_rtx_LABEL_REF (VOIDmode, label), 11467 pc_rtx); 11468 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 11469 JUMP_LABEL (tmp) = label; 11470 11471 emit_move_insn (operands[0], operands[1]); 11472 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31))); 11473 11474 emit_label (label); 11475 LABEL_NUSES (label) = 1; 11476 11477 DONE; 11478}) 11479 11480(define_insn "ashrsi3_31" 11481 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm") 11482 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0") 11483 (match_operand:SI 2 "const_int_operand" "i,i"))) 11484 (clobber (reg:CC FLAGS_REG))] 11485 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size) 11486 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11487 "@ 11488 {cltd|cdq} 11489 sar{l}\t{%2, %0|%0, %2}" 11490 [(set_attr "type" "imovx,ishift") 11491 (set_attr "prefix_0f" "0,*") 11492 (set_attr "length_immediate" "0,*") 11493 (set_attr "modrm" "0,1") 11494 (set_attr "mode" "SI")]) 11495 11496(define_insn "*ashrsi3_31_zext" 11497 [(set (match_operand:DI 0 "register_operand" "=*d,r") 11498 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0") 11499 (match_operand:SI 2 "const_int_operand" "i,i")))) 11500 (clobber (reg:CC FLAGS_REG))] 11501 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size) 11502 && INTVAL (operands[2]) == 31 11503 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11504 "@ 11505 {cltd|cdq} 11506 sar{l}\t{%2, %k0|%k0, %2}" 11507 [(set_attr "type" "imovx,ishift") 11508 (set_attr "prefix_0f" "0,*") 11509 (set_attr "length_immediate" "0,*") 11510 (set_attr "modrm" "0,1") 11511 (set_attr "mode" "SI")]) 11512 11513(define_expand "ashrsi3" 11514 [(set (match_operand:SI 0 "nonimmediate_operand" "") 11515 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") 11516 (match_operand:QI 2 "nonmemory_operand" ""))) 11517 (clobber (reg:CC FLAGS_REG))] 11518 "" 11519 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;") 11520 11521(define_insn "*ashrsi3_1_one_bit" 11522 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 11523 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11524 (match_operand:QI 2 "const1_operand" ""))) 11525 (clobber (reg:CC FLAGS_REG))] 11526 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11527 && (TARGET_SHIFT1 || optimize_size)" 11528 "sar{l}\t%0" 11529 [(set_attr "type" "ishift") 11530 (set (attr "length") 11531 (if_then_else (match_operand:SI 0 "register_operand" "") 11532 (const_string "2") 11533 (const_string "*")))]) 11534 11535(define_insn "*ashrsi3_1_one_bit_zext" 11536 [(set (match_operand:DI 0 "register_operand" "=r") 11537 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 11538 (match_operand:QI 2 "const1_operand" "")))) 11539 (clobber (reg:CC FLAGS_REG))] 11540 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11541 && (TARGET_SHIFT1 || optimize_size)" 11542 "sar{l}\t%k0" 11543 [(set_attr "type" "ishift") 11544 (set_attr "length" "2")]) 11545 11546(define_insn "*ashrsi3_1" 11547 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 11548 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 11549 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 11550 (clobber (reg:CC FLAGS_REG))] 11551 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11552 "@ 11553 sar{l}\t{%2, %0|%0, %2} 11554 sar{l}\t{%b2, %0|%0, %b2}" 11555 [(set_attr "type" "ishift") 11556 (set_attr "mode" "SI")]) 11557 11558(define_insn "*ashrsi3_1_zext" 11559 [(set (match_operand:DI 0 "register_operand" "=r,r") 11560 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0") 11561 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 11562 (clobber (reg:CC FLAGS_REG))] 11563 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11564 "@ 11565 sar{l}\t{%2, %k0|%k0, %2} 11566 sar{l}\t{%b2, %k0|%k0, %b2}" 11567 [(set_attr "type" "ishift") 11568 (set_attr "mode" "SI")]) 11569 11570;; This pattern can't accept a variable shift count, since shifts by 11571;; zero don't affect the flags. We assume that shifts by constant 11572;; zero are optimized away. 11573(define_insn "*ashrsi3_one_bit_cmp" 11574 [(set (reg FLAGS_REG) 11575 (compare 11576 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11577 (match_operand:QI 2 "const1_operand" "")) 11578 (const_int 0))) 11579 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 11580 (ashiftrt:SI (match_dup 1) (match_dup 2)))] 11581 "ix86_match_ccmode (insn, CCGOCmode) 11582 && (TARGET_SHIFT1 || optimize_size) 11583 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11584 "sar{l}\t%0" 11585 [(set_attr "type" "ishift") 11586 (set (attr "length") 11587 (if_then_else (match_operand:SI 0 "register_operand" "") 11588 (const_string "2") 11589 (const_string "*")))]) 11590 11591(define_insn "*ashrsi3_one_bit_cconly" 11592 [(set (reg FLAGS_REG) 11593 (compare 11594 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11595 (match_operand:QI 2 "const1_operand" "")) 11596 (const_int 0))) 11597 (clobber (match_scratch:SI 0 "=r"))] 11598 "ix86_match_ccmode (insn, CCGOCmode) 11599 && (TARGET_SHIFT1 || optimize_size) 11600 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11601 "sar{l}\t%0" 11602 [(set_attr "type" "ishift") 11603 (set_attr "length" "2")]) 11604 11605(define_insn "*ashrsi3_one_bit_cmp_zext" 11606 [(set (reg FLAGS_REG) 11607 (compare 11608 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 11609 (match_operand:QI 2 "const1_operand" "")) 11610 (const_int 0))) 11611 (set (match_operand:DI 0 "register_operand" "=r") 11612 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))] 11613 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 11614 && (TARGET_SHIFT1 || optimize_size) 11615 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11616 "sar{l}\t%k0" 11617 [(set_attr "type" "ishift") 11618 (set_attr "length" "2")]) 11619 11620;; This pattern can't accept a variable shift count, since shifts by 11621;; zero don't affect the flags. We assume that shifts by constant 11622;; zero are optimized away. 11623(define_insn "*ashrsi3_cmp" 11624 [(set (reg FLAGS_REG) 11625 (compare 11626 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11627 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11628 (const_int 0))) 11629 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 11630 (ashiftrt:SI (match_dup 1) (match_dup 2)))] 11631 "ix86_match_ccmode (insn, CCGOCmode) 11632 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11633 && (optimize_size 11634 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11635 "sar{l}\t{%2, %0|%0, %2}" 11636 [(set_attr "type" "ishift") 11637 (set_attr "mode" "SI")]) 11638 11639(define_insn "*ashrsi3_cconly" 11640 [(set (reg FLAGS_REG) 11641 (compare 11642 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11643 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11644 (const_int 0))) 11645 (clobber (match_scratch:SI 0 "=r"))] 11646 "ix86_match_ccmode (insn, CCGOCmode) 11647 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11648 && (optimize_size 11649 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11650 "sar{l}\t{%2, %0|%0, %2}" 11651 [(set_attr "type" "ishift") 11652 (set_attr "mode" "SI")]) 11653 11654(define_insn "*ashrsi3_cmp_zext" 11655 [(set (reg FLAGS_REG) 11656 (compare 11657 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 11658 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11659 (const_int 0))) 11660 (set (match_operand:DI 0 "register_operand" "=r") 11661 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))] 11662 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11663 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11664 && (optimize_size 11665 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11666 "sar{l}\t{%2, %k0|%k0, %2}" 11667 [(set_attr "type" "ishift") 11668 (set_attr "mode" "SI")]) 11669 11670(define_expand "ashrhi3" 11671 [(set (match_operand:HI 0 "nonimmediate_operand" "") 11672 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") 11673 (match_operand:QI 2 "nonmemory_operand" ""))) 11674 (clobber (reg:CC FLAGS_REG))] 11675 "TARGET_HIMODE_MATH" 11676 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;") 11677 11678(define_insn "*ashrhi3_1_one_bit" 11679 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 11680 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11681 (match_operand:QI 2 "const1_operand" ""))) 11682 (clobber (reg:CC FLAGS_REG))] 11683 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands) 11684 && (TARGET_SHIFT1 || optimize_size)" 11685 "sar{w}\t%0" 11686 [(set_attr "type" "ishift") 11687 (set (attr "length") 11688 (if_then_else (match_operand 0 "register_operand" "") 11689 (const_string "2") 11690 (const_string "*")))]) 11691 11692(define_insn "*ashrhi3_1" 11693 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 11694 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 11695 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 11696 (clobber (reg:CC FLAGS_REG))] 11697 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" 11698 "@ 11699 sar{w}\t{%2, %0|%0, %2} 11700 sar{w}\t{%b2, %0|%0, %b2}" 11701 [(set_attr "type" "ishift") 11702 (set_attr "mode" "HI")]) 11703 11704;; This pattern can't accept a variable shift count, since shifts by 11705;; zero don't affect the flags. We assume that shifts by constant 11706;; zero are optimized away. 11707(define_insn "*ashrhi3_one_bit_cmp" 11708 [(set (reg FLAGS_REG) 11709 (compare 11710 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11711 (match_operand:QI 2 "const1_operand" "")) 11712 (const_int 0))) 11713 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 11714 (ashiftrt:HI (match_dup 1) (match_dup 2)))] 11715 "ix86_match_ccmode (insn, CCGOCmode) 11716 && (TARGET_SHIFT1 || optimize_size) 11717 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" 11718 "sar{w}\t%0" 11719 [(set_attr "type" "ishift") 11720 (set (attr "length") 11721 (if_then_else (match_operand 0 "register_operand" "") 11722 (const_string "2") 11723 (const_string "*")))]) 11724 11725(define_insn "*ashrhi3_one_bit_cconly" 11726 [(set (reg FLAGS_REG) 11727 (compare 11728 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11729 (match_operand:QI 2 "const1_operand" "")) 11730 (const_int 0))) 11731 (clobber (match_scratch:HI 0 "=r"))] 11732 "ix86_match_ccmode (insn, CCGOCmode) 11733 && (TARGET_SHIFT1 || optimize_size) 11734 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" 11735 "sar{w}\t%0" 11736 [(set_attr "type" "ishift") 11737 (set_attr "length" "2")]) 11738 11739;; This pattern can't accept a variable shift count, since shifts by 11740;; zero don't affect the flags. We assume that shifts by constant 11741;; zero are optimized away. 11742(define_insn "*ashrhi3_cmp" 11743 [(set (reg FLAGS_REG) 11744 (compare 11745 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11746 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11747 (const_int 0))) 11748 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 11749 (ashiftrt:HI (match_dup 1) (match_dup 2)))] 11750 "ix86_match_ccmode (insn, CCGOCmode) 11751 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands) 11752 && (optimize_size 11753 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11754 "sar{w}\t{%2, %0|%0, %2}" 11755 [(set_attr "type" "ishift") 11756 (set_attr "mode" "HI")]) 11757 11758(define_insn "*ashrhi3_cconly" 11759 [(set (reg FLAGS_REG) 11760 (compare 11761 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11762 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11763 (const_int 0))) 11764 (clobber (match_scratch:HI 0 "=r"))] 11765 "ix86_match_ccmode (insn, CCGOCmode) 11766 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands) 11767 && (optimize_size 11768 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11769 "sar{w}\t{%2, %0|%0, %2}" 11770 [(set_attr "type" "ishift") 11771 (set_attr "mode" "HI")]) 11772 11773(define_expand "ashrqi3" 11774 [(set (match_operand:QI 0 "nonimmediate_operand" "") 11775 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "") 11776 (match_operand:QI 2 "nonmemory_operand" ""))) 11777 (clobber (reg:CC FLAGS_REG))] 11778 "TARGET_QIMODE_MATH" 11779 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;") 11780 11781(define_insn "*ashrqi3_1_one_bit" 11782 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11783 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11784 (match_operand:QI 2 "const1_operand" ""))) 11785 (clobber (reg:CC FLAGS_REG))] 11786 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 11787 && (TARGET_SHIFT1 || optimize_size)" 11788 "sar{b}\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 "*ashrqi3_1_one_bit_slp" 11796 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 11797 (ashiftrt:QI (match_dup 0) 11798 (match_operand:QI 1 "const1_operand" ""))) 11799 (clobber (reg:CC FLAGS_REG))] 11800 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 11801 && (! TARGET_PARTIAL_REG_STALL || optimize_size) 11802 && (TARGET_SHIFT1 || optimize_size)" 11803 "sar{b}\t%0" 11804 [(set_attr "type" "ishift1") 11805 (set (attr "length") 11806 (if_then_else (match_operand 0 "register_operand" "") 11807 (const_string "2") 11808 (const_string "*")))]) 11809 11810(define_insn "*ashrqi3_1" 11811 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 11812 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 11813 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 11814 (clobber (reg:CC FLAGS_REG))] 11815 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" 11816 "@ 11817 sar{b}\t{%2, %0|%0, %2} 11818 sar{b}\t{%b2, %0|%0, %b2}" 11819 [(set_attr "type" "ishift") 11820 (set_attr "mode" "QI")]) 11821 11822(define_insn "*ashrqi3_1_slp" 11823 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 11824 (ashiftrt:QI (match_dup 0) 11825 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 11826 (clobber (reg:CC FLAGS_REG))] 11827 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 11828 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 11829 "@ 11830 sar{b}\t{%1, %0|%0, %1} 11831 sar{b}\t{%b1, %0|%0, %b1}" 11832 [(set_attr "type" "ishift1") 11833 (set_attr "mode" "QI")]) 11834 11835;; This pattern can't accept a variable shift count, since shifts by 11836;; zero don't affect the flags. We assume that shifts by constant 11837;; zero are optimized away. 11838(define_insn "*ashrqi3_one_bit_cmp" 11839 [(set (reg FLAGS_REG) 11840 (compare 11841 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11842 (match_operand:QI 2 "const1_operand" "I")) 11843 (const_int 0))) 11844 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11845 (ashiftrt:QI (match_dup 1) (match_dup 2)))] 11846 "ix86_match_ccmode (insn, CCGOCmode) 11847 && (TARGET_SHIFT1 || optimize_size) 11848 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" 11849 "sar{b}\t%0" 11850 [(set_attr "type" "ishift") 11851 (set (attr "length") 11852 (if_then_else (match_operand 0 "register_operand" "") 11853 (const_string "2") 11854 (const_string "*")))]) 11855 11856(define_insn "*ashrqi3_one_bit_cconly" 11857 [(set (reg FLAGS_REG) 11858 (compare 11859 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11860 (match_operand:QI 2 "const1_operand" "I")) 11861 (const_int 0))) 11862 (clobber (match_scratch:QI 0 "=q"))] 11863 "ix86_match_ccmode (insn, CCGOCmode) 11864 && (TARGET_SHIFT1 || optimize_size) 11865 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" 11866 "sar{b}\t%0" 11867 [(set_attr "type" "ishift") 11868 (set_attr "length" "2")]) 11869 11870;; This pattern can't accept a variable shift count, since shifts by 11871;; zero don't affect the flags. We assume that shifts by constant 11872;; zero are optimized away. 11873(define_insn "*ashrqi3_cmp" 11874 [(set (reg FLAGS_REG) 11875 (compare 11876 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11877 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11878 (const_int 0))) 11879 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11880 (ashiftrt:QI (match_dup 1) (match_dup 2)))] 11881 "ix86_match_ccmode (insn, CCGOCmode) 11882 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 11883 && (optimize_size 11884 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11885 "sar{b}\t{%2, %0|%0, %2}" 11886 [(set_attr "type" "ishift") 11887 (set_attr "mode" "QI")]) 11888 11889(define_insn "*ashrqi3_cconly" 11890 [(set (reg FLAGS_REG) 11891 (compare 11892 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11893 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11894 (const_int 0))) 11895 (clobber (match_scratch:QI 0 "=q"))] 11896 "ix86_match_ccmode (insn, CCGOCmode) 11897 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 11898 && (optimize_size 11899 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11900 "sar{b}\t{%2, %0|%0, %2}" 11901 [(set_attr "type" "ishift") 11902 (set_attr "mode" "QI")]) 11903 11904 11905;; Logical shift instructions 11906 11907;; See comment above `ashldi3' about how this works. 11908 11909(define_expand "lshrti3" 11910 [(parallel [(set (match_operand:TI 0 "register_operand" "") 11911 (lshiftrt:TI (match_operand:TI 1 "register_operand" "") 11912 (match_operand:QI 2 "nonmemory_operand" ""))) 11913 (clobber (reg:CC FLAGS_REG))])] 11914 "TARGET_64BIT" 11915{ 11916 if (! immediate_operand (operands[2], QImode)) 11917 { 11918 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2])); 11919 DONE; 11920 } 11921 ix86_expand_binary_operator (LSHIFTRT, TImode, operands); 11922 DONE; 11923}) 11924 11925(define_insn "lshrti3_1" 11926 [(set (match_operand:TI 0 "register_operand" "=r") 11927 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0") 11928 (match_operand:QI 2 "register_operand" "c"))) 11929 (clobber (match_scratch:DI 3 "=&r")) 11930 (clobber (reg:CC FLAGS_REG))] 11931 "TARGET_64BIT" 11932 "#" 11933 [(set_attr "type" "multi")]) 11934 11935(define_insn "*lshrti3_2" 11936 [(set (match_operand:TI 0 "register_operand" "=r") 11937 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0") 11938 (match_operand:QI 2 "immediate_operand" "O"))) 11939 (clobber (reg:CC FLAGS_REG))] 11940 "TARGET_64BIT" 11941 "#" 11942 [(set_attr "type" "multi")]) 11943 11944(define_split 11945 [(set (match_operand:TI 0 "register_operand" "") 11946 (lshiftrt:TI (match_operand:TI 1 "register_operand" "") 11947 (match_operand:QI 2 "register_operand" ""))) 11948 (clobber (match_scratch:DI 3 "")) 11949 (clobber (reg:CC FLAGS_REG))] 11950 "TARGET_64BIT && reload_completed" 11951 [(const_int 0)] 11952 "ix86_split_lshr (operands, operands[3], TImode); DONE;") 11953 11954(define_split 11955 [(set (match_operand:TI 0 "register_operand" "") 11956 (lshiftrt:TI (match_operand:TI 1 "register_operand" "") 11957 (match_operand:QI 2 "immediate_operand" ""))) 11958 (clobber (reg:CC FLAGS_REG))] 11959 "TARGET_64BIT && reload_completed" 11960 [(const_int 0)] 11961 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;") 11962 11963(define_expand "lshrdi3" 11964 [(set (match_operand:DI 0 "shiftdi_operand" "") 11965 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") 11966 (match_operand:QI 2 "nonmemory_operand" "")))] 11967 "" 11968 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;") 11969 11970(define_insn "*lshrdi3_1_one_bit_rex64" 11971 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11972 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11973 (match_operand:QI 2 "const1_operand" ""))) 11974 (clobber (reg:CC FLAGS_REG))] 11975 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 11976 && (TARGET_SHIFT1 || optimize_size)" 11977 "shr{q}\t%0" 11978 [(set_attr "type" "ishift") 11979 (set (attr "length") 11980 (if_then_else (match_operand:DI 0 "register_operand" "") 11981 (const_string "2") 11982 (const_string "*")))]) 11983 11984(define_insn "*lshrdi3_1_rex64" 11985 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 11986 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 11987 (match_operand:QI 2 "nonmemory_operand" "J,c"))) 11988 (clobber (reg:CC FLAGS_REG))] 11989 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 11990 "@ 11991 shr{q}\t{%2, %0|%0, %2} 11992 shr{q}\t{%b2, %0|%0, %b2}" 11993 [(set_attr "type" "ishift") 11994 (set_attr "mode" "DI")]) 11995 11996;; This pattern can't accept a variable shift count, since shifts by 11997;; zero don't affect the flags. We assume that shifts by constant 11998;; zero are optimized away. 11999(define_insn "*lshrdi3_cmp_one_bit_rex64" 12000 [(set (reg FLAGS_REG) 12001 (compare 12002 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12003 (match_operand:QI 2 "const1_operand" "")) 12004 (const_int 0))) 12005 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12006 (lshiftrt:DI (match_dup 1) (match_dup 2)))] 12007 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12008 && (TARGET_SHIFT1 || optimize_size) 12009 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12010 "shr{q}\t%0" 12011 [(set_attr "type" "ishift") 12012 (set (attr "length") 12013 (if_then_else (match_operand:DI 0 "register_operand" "") 12014 (const_string "2") 12015 (const_string "*")))]) 12016 12017(define_insn "*lshrdi3_cconly_one_bit_rex64" 12018 [(set (reg FLAGS_REG) 12019 (compare 12020 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12021 (match_operand:QI 2 "const1_operand" "")) 12022 (const_int 0))) 12023 (clobber (match_scratch:DI 0 "=r"))] 12024 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12025 && (TARGET_SHIFT1 || optimize_size) 12026 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12027 "shr{q}\t%0" 12028 [(set_attr "type" "ishift") 12029 (set_attr "length" "2")]) 12030 12031;; This pattern can't accept a variable shift count, since shifts by 12032;; zero don't affect the flags. We assume that shifts by constant 12033;; zero are optimized away. 12034(define_insn "*lshrdi3_cmp_rex64" 12035 [(set (reg FLAGS_REG) 12036 (compare 12037 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12038 (match_operand:QI 2 "const_int_operand" "e")) 12039 (const_int 0))) 12040 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12041 (lshiftrt:DI (match_dup 1) (match_dup 2)))] 12042 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12043 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12044 && (optimize_size 12045 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12046 "shr{q}\t{%2, %0|%0, %2}" 12047 [(set_attr "type" "ishift") 12048 (set_attr "mode" "DI")]) 12049 12050(define_insn "*lshrdi3_cconly_rex64" 12051 [(set (reg FLAGS_REG) 12052 (compare 12053 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12054 (match_operand:QI 2 "const_int_operand" "e")) 12055 (const_int 0))) 12056 (clobber (match_scratch:DI 0 "=r"))] 12057 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12058 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12059 && (optimize_size 12060 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12061 "shr{q}\t{%2, %0|%0, %2}" 12062 [(set_attr "type" "ishift") 12063 (set_attr "mode" "DI")]) 12064 12065(define_insn "*lshrdi3_1" 12066 [(set (match_operand:DI 0 "register_operand" "=r") 12067 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") 12068 (match_operand:QI 2 "nonmemory_operand" "Jc"))) 12069 (clobber (reg:CC FLAGS_REG))] 12070 "!TARGET_64BIT" 12071 "#" 12072 [(set_attr "type" "multi")]) 12073 12074;; By default we don't ask for a scratch register, because when DImode 12075;; values are manipulated, registers are already at a premium. But if 12076;; we have one handy, we won't turn it away. 12077(define_peephole2 12078 [(match_scratch:SI 3 "r") 12079 (parallel [(set (match_operand:DI 0 "register_operand" "") 12080 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 12081 (match_operand:QI 2 "nonmemory_operand" ""))) 12082 (clobber (reg:CC FLAGS_REG))]) 12083 (match_dup 3)] 12084 "!TARGET_64BIT && TARGET_CMOVE" 12085 [(const_int 0)] 12086 "ix86_split_lshr (operands, operands[3], DImode); DONE;") 12087 12088(define_split 12089 [(set (match_operand:DI 0 "register_operand" "") 12090 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 12091 (match_operand:QI 2 "nonmemory_operand" ""))) 12092 (clobber (reg:CC FLAGS_REG))] 12093 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) 12094 ? flow2_completed : reload_completed)" 12095 [(const_int 0)] 12096 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;") 12097 12098(define_expand "lshrsi3" 12099 [(set (match_operand:SI 0 "nonimmediate_operand" "") 12100 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") 12101 (match_operand:QI 2 "nonmemory_operand" ""))) 12102 (clobber (reg:CC FLAGS_REG))] 12103 "" 12104 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;") 12105 12106(define_insn "*lshrsi3_1_one_bit" 12107 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12108 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12109 (match_operand:QI 2 "const1_operand" ""))) 12110 (clobber (reg:CC FLAGS_REG))] 12111 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12112 && (TARGET_SHIFT1 || optimize_size)" 12113 "shr{l}\t%0" 12114 [(set_attr "type" "ishift") 12115 (set (attr "length") 12116 (if_then_else (match_operand:SI 0 "register_operand" "") 12117 (const_string "2") 12118 (const_string "*")))]) 12119 12120(define_insn "*lshrsi3_1_one_bit_zext" 12121 [(set (match_operand:DI 0 "register_operand" "=r") 12122 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0")) 12123 (match_operand:QI 2 "const1_operand" ""))) 12124 (clobber (reg:CC FLAGS_REG))] 12125 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12126 && (TARGET_SHIFT1 || optimize_size)" 12127 "shr{l}\t%k0" 12128 [(set_attr "type" "ishift") 12129 (set_attr "length" "2")]) 12130 12131(define_insn "*lshrsi3_1" 12132 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 12133 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12134 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12135 (clobber (reg:CC FLAGS_REG))] 12136 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12137 "@ 12138 shr{l}\t{%2, %0|%0, %2} 12139 shr{l}\t{%b2, %0|%0, %b2}" 12140 [(set_attr "type" "ishift") 12141 (set_attr "mode" "SI")]) 12142 12143(define_insn "*lshrsi3_1_zext" 12144 [(set (match_operand:DI 0 "register_operand" "=r,r") 12145 (zero_extend:DI 12146 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12147 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 12148 (clobber (reg:CC FLAGS_REG))] 12149 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12150 "@ 12151 shr{l}\t{%2, %k0|%k0, %2} 12152 shr{l}\t{%b2, %k0|%k0, %b2}" 12153 [(set_attr "type" "ishift") 12154 (set_attr "mode" "SI")]) 12155 12156;; This pattern can't accept a variable shift count, since shifts by 12157;; zero don't affect the flags. We assume that shifts by constant 12158;; zero are optimized away. 12159(define_insn "*lshrsi3_one_bit_cmp" 12160 [(set (reg FLAGS_REG) 12161 (compare 12162 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12163 (match_operand:QI 2 "const1_operand" "")) 12164 (const_int 0))) 12165 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12166 (lshiftrt:SI (match_dup 1) (match_dup 2)))] 12167 "ix86_match_ccmode (insn, CCGOCmode) 12168 && (TARGET_SHIFT1 || optimize_size) 12169 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12170 "shr{l}\t%0" 12171 [(set_attr "type" "ishift") 12172 (set (attr "length") 12173 (if_then_else (match_operand:SI 0 "register_operand" "") 12174 (const_string "2") 12175 (const_string "*")))]) 12176 12177(define_insn "*lshrsi3_one_bit_cconly" 12178 [(set (reg FLAGS_REG) 12179 (compare 12180 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12181 (match_operand:QI 2 "const1_operand" "")) 12182 (const_int 0))) 12183 (clobber (match_scratch:SI 0 "=r"))] 12184 "ix86_match_ccmode (insn, CCGOCmode) 12185 && (TARGET_SHIFT1 || optimize_size) 12186 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12187 "shr{l}\t%0" 12188 [(set_attr "type" "ishift") 12189 (set_attr "length" "2")]) 12190 12191(define_insn "*lshrsi3_cmp_one_bit_zext" 12192 [(set (reg FLAGS_REG) 12193 (compare 12194 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 12195 (match_operand:QI 2 "const1_operand" "")) 12196 (const_int 0))) 12197 (set (match_operand:DI 0 "register_operand" "=r") 12198 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 12199 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12200 && (TARGET_SHIFT1 || optimize_size) 12201 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12202 "shr{l}\t%k0" 12203 [(set_attr "type" "ishift") 12204 (set_attr "length" "2")]) 12205 12206;; This pattern can't accept a variable shift count, since shifts by 12207;; zero don't affect the flags. We assume that shifts by constant 12208;; zero are optimized away. 12209(define_insn "*lshrsi3_cmp" 12210 [(set (reg FLAGS_REG) 12211 (compare 12212 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12213 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12214 (const_int 0))) 12215 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12216 (lshiftrt:SI (match_dup 1) (match_dup 2)))] 12217 "ix86_match_ccmode (insn, CCGOCmode) 12218 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12219 && (optimize_size 12220 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12221 "shr{l}\t{%2, %0|%0, %2}" 12222 [(set_attr "type" "ishift") 12223 (set_attr "mode" "SI")]) 12224 12225(define_insn "*lshrsi3_cconly" 12226 [(set (reg FLAGS_REG) 12227 (compare 12228 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12229 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12230 (const_int 0))) 12231 (clobber (match_scratch:SI 0 "=r"))] 12232 "ix86_match_ccmode (insn, CCGOCmode) 12233 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12234 && (optimize_size 12235 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12236 "shr{l}\t{%2, %0|%0, %2}" 12237 [(set_attr "type" "ishift") 12238 (set_attr "mode" "SI")]) 12239 12240(define_insn "*lshrsi3_cmp_zext" 12241 [(set (reg FLAGS_REG) 12242 (compare 12243 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 12244 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12245 (const_int 0))) 12246 (set (match_operand:DI 0 "register_operand" "=r") 12247 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 12248 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12249 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12250 && (optimize_size 12251 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12252 "shr{l}\t{%2, %k0|%k0, %2}" 12253 [(set_attr "type" "ishift") 12254 (set_attr "mode" "SI")]) 12255 12256(define_expand "lshrhi3" 12257 [(set (match_operand:HI 0 "nonimmediate_operand" "") 12258 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") 12259 (match_operand:QI 2 "nonmemory_operand" ""))) 12260 (clobber (reg:CC FLAGS_REG))] 12261 "TARGET_HIMODE_MATH" 12262 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;") 12263 12264(define_insn "*lshrhi3_1_one_bit" 12265 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12266 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12267 (match_operand:QI 2 "const1_operand" ""))) 12268 (clobber (reg:CC FLAGS_REG))] 12269 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12270 && (TARGET_SHIFT1 || optimize_size)" 12271 "shr{w}\t%0" 12272 [(set_attr "type" "ishift") 12273 (set (attr "length") 12274 (if_then_else (match_operand 0 "register_operand" "") 12275 (const_string "2") 12276 (const_string "*")))]) 12277 12278(define_insn "*lshrhi3_1" 12279 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 12280 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 12281 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12282 (clobber (reg:CC FLAGS_REG))] 12283 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12284 "@ 12285 shr{w}\t{%2, %0|%0, %2} 12286 shr{w}\t{%b2, %0|%0, %b2}" 12287 [(set_attr "type" "ishift") 12288 (set_attr "mode" "HI")]) 12289 12290;; This pattern can't accept a variable shift count, since shifts by 12291;; zero don't affect the flags. We assume that shifts by constant 12292;; zero are optimized away. 12293(define_insn "*lshrhi3_one_bit_cmp" 12294 [(set (reg FLAGS_REG) 12295 (compare 12296 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12297 (match_operand:QI 2 "const1_operand" "")) 12298 (const_int 0))) 12299 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12300 (lshiftrt:HI (match_dup 1) (match_dup 2)))] 12301 "ix86_match_ccmode (insn, CCGOCmode) 12302 && (TARGET_SHIFT1 || optimize_size) 12303 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12304 "shr{w}\t%0" 12305 [(set_attr "type" "ishift") 12306 (set (attr "length") 12307 (if_then_else (match_operand:SI 0 "register_operand" "") 12308 (const_string "2") 12309 (const_string "*")))]) 12310 12311(define_insn "*lshrhi3_one_bit_cconly" 12312 [(set (reg FLAGS_REG) 12313 (compare 12314 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12315 (match_operand:QI 2 "const1_operand" "")) 12316 (const_int 0))) 12317 (clobber (match_scratch:HI 0 "=r"))] 12318 "ix86_match_ccmode (insn, CCGOCmode) 12319 && (TARGET_SHIFT1 || optimize_size) 12320 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12321 "shr{w}\t%0" 12322 [(set_attr "type" "ishift") 12323 (set_attr "length" "2")]) 12324 12325;; This pattern can't accept a variable shift count, since shifts by 12326;; zero don't affect the flags. We assume that shifts by constant 12327;; zero are optimized away. 12328(define_insn "*lshrhi3_cmp" 12329 [(set (reg FLAGS_REG) 12330 (compare 12331 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12332 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12333 (const_int 0))) 12334 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12335 (lshiftrt:HI (match_dup 1) (match_dup 2)))] 12336 "ix86_match_ccmode (insn, CCGOCmode) 12337 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12338 && (optimize_size 12339 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12340 "shr{w}\t{%2, %0|%0, %2}" 12341 [(set_attr "type" "ishift") 12342 (set_attr "mode" "HI")]) 12343 12344(define_insn "*lshrhi3_cconly" 12345 [(set (reg FLAGS_REG) 12346 (compare 12347 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12348 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12349 (const_int 0))) 12350 (clobber (match_scratch:HI 0 "=r"))] 12351 "ix86_match_ccmode (insn, CCGOCmode) 12352 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12353 && (optimize_size 12354 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12355 "shr{w}\t{%2, %0|%0, %2}" 12356 [(set_attr "type" "ishift") 12357 (set_attr "mode" "HI")]) 12358 12359(define_expand "lshrqi3" 12360 [(set (match_operand:QI 0 "nonimmediate_operand" "") 12361 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "") 12362 (match_operand:QI 2 "nonmemory_operand" ""))) 12363 (clobber (reg:CC FLAGS_REG))] 12364 "TARGET_QIMODE_MATH" 12365 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;") 12366 12367(define_insn "*lshrqi3_1_one_bit" 12368 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12369 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12370 (match_operand:QI 2 "const1_operand" ""))) 12371 (clobber (reg:CC FLAGS_REG))] 12372 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands) 12373 && (TARGET_SHIFT1 || optimize_size)" 12374 "shr{b}\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 "*lshrqi3_1_one_bit_slp" 12382 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 12383 (lshiftrt:QI (match_dup 0) 12384 (match_operand:QI 1 "const1_operand" ""))) 12385 (clobber (reg:CC FLAGS_REG))] 12386 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12387 && (TARGET_SHIFT1 || optimize_size)" 12388 "shr{b}\t%0" 12389 [(set_attr "type" "ishift1") 12390 (set (attr "length") 12391 (if_then_else (match_operand 0 "register_operand" "") 12392 (const_string "2") 12393 (const_string "*")))]) 12394 12395(define_insn "*lshrqi3_1" 12396 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 12397 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 12398 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12399 (clobber (reg:CC FLAGS_REG))] 12400 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" 12401 "@ 12402 shr{b}\t{%2, %0|%0, %2} 12403 shr{b}\t{%b2, %0|%0, %b2}" 12404 [(set_attr "type" "ishift") 12405 (set_attr "mode" "QI")]) 12406 12407(define_insn "*lshrqi3_1_slp" 12408 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 12409 (lshiftrt:QI (match_dup 0) 12410 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 12411 (clobber (reg:CC FLAGS_REG))] 12412 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12413 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 12414 "@ 12415 shr{b}\t{%1, %0|%0, %1} 12416 shr{b}\t{%b1, %0|%0, %b1}" 12417 [(set_attr "type" "ishift1") 12418 (set_attr "mode" "QI")]) 12419 12420;; This pattern can't accept a variable shift count, since shifts by 12421;; zero don't affect the flags. We assume that shifts by constant 12422;; zero are optimized away. 12423(define_insn "*lshrqi2_one_bit_cmp" 12424 [(set (reg FLAGS_REG) 12425 (compare 12426 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12427 (match_operand:QI 2 "const1_operand" "")) 12428 (const_int 0))) 12429 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12430 (lshiftrt:QI (match_dup 1) (match_dup 2)))] 12431 "ix86_match_ccmode (insn, CCGOCmode) 12432 && (TARGET_SHIFT1 || optimize_size) 12433 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" 12434 "shr{b}\t%0" 12435 [(set_attr "type" "ishift") 12436 (set (attr "length") 12437 (if_then_else (match_operand:SI 0 "register_operand" "") 12438 (const_string "2") 12439 (const_string "*")))]) 12440 12441(define_insn "*lshrqi2_one_bit_cconly" 12442 [(set (reg FLAGS_REG) 12443 (compare 12444 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12445 (match_operand:QI 2 "const1_operand" "")) 12446 (const_int 0))) 12447 (clobber (match_scratch:QI 0 "=q"))] 12448 "ix86_match_ccmode (insn, CCGOCmode) 12449 && (TARGET_SHIFT1 || optimize_size) 12450 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" 12451 "shr{b}\t%0" 12452 [(set_attr "type" "ishift") 12453 (set_attr "length" "2")]) 12454 12455;; This pattern can't accept a variable shift count, since shifts by 12456;; zero don't affect the flags. We assume that shifts by constant 12457;; zero are optimized away. 12458(define_insn "*lshrqi2_cmp" 12459 [(set (reg FLAGS_REG) 12460 (compare 12461 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12462 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12463 (const_int 0))) 12464 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12465 (lshiftrt:QI (match_dup 1) (match_dup 2)))] 12466 "ix86_match_ccmode (insn, CCGOCmode) 12467 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands) 12468 && (optimize_size 12469 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12470 "shr{b}\t{%2, %0|%0, %2}" 12471 [(set_attr "type" "ishift") 12472 (set_attr "mode" "QI")]) 12473 12474(define_insn "*lshrqi2_cconly" 12475 [(set (reg FLAGS_REG) 12476 (compare 12477 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12478 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12479 (const_int 0))) 12480 (clobber (match_scratch:QI 0 "=q"))] 12481 "ix86_match_ccmode (insn, CCGOCmode) 12482 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands) 12483 && (optimize_size 12484 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12485 "shr{b}\t{%2, %0|%0, %2}" 12486 [(set_attr "type" "ishift") 12487 (set_attr "mode" "QI")]) 12488 12489;; Rotate instructions 12490 12491(define_expand "rotldi3" 12492 [(set (match_operand:DI 0 "shiftdi_operand" "") 12493 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "") 12494 (match_operand:QI 2 "nonmemory_operand" ""))) 12495 (clobber (reg:CC FLAGS_REG))] 12496 "" 12497{ 12498 if (TARGET_64BIT) 12499 { 12500 ix86_expand_binary_operator (ROTATE, DImode, operands); 12501 DONE; 12502 } 12503 if (!const_1_to_31_operand (operands[2], VOIDmode)) 12504 FAIL; 12505 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2])); 12506 DONE; 12507}) 12508 12509;; Implement rotation using two double-precision shift instructions 12510;; and a scratch register. 12511(define_insn_and_split "ix86_rotldi3" 12512 [(set (match_operand:DI 0 "register_operand" "=r") 12513 (rotate:DI (match_operand:DI 1 "register_operand" "0") 12514 (match_operand:QI 2 "const_1_to_31_operand" "I"))) 12515 (clobber (reg:CC FLAGS_REG)) 12516 (clobber (match_scratch:SI 3 "=&r"))] 12517 "!TARGET_64BIT" 12518 "" 12519 "&& reload_completed" 12520 [(set (match_dup 3) (match_dup 4)) 12521 (parallel 12522 [(set (match_dup 4) 12523 (ior:SI (ashift:SI (match_dup 4) (match_dup 2)) 12524 (lshiftrt:SI (match_dup 5) 12525 (minus:QI (const_int 32) (match_dup 2))))) 12526 (clobber (reg:CC FLAGS_REG))]) 12527 (parallel 12528 [(set (match_dup 5) 12529 (ior:SI (ashift:SI (match_dup 5) (match_dup 2)) 12530 (lshiftrt:SI (match_dup 3) 12531 (minus:QI (const_int 32) (match_dup 2))))) 12532 (clobber (reg:CC FLAGS_REG))])] 12533 "split_di (operands, 1, operands + 4, operands + 5);") 12534 12535(define_insn "*rotlsi3_1_one_bit_rex64" 12536 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12537 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12538 (match_operand:QI 2 "const1_operand" ""))) 12539 (clobber (reg:CC FLAGS_REG))] 12540 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands) 12541 && (TARGET_SHIFT1 || optimize_size)" 12542 "rol{q}\t%0" 12543 [(set_attr "type" "rotate") 12544 (set (attr "length") 12545 (if_then_else (match_operand:DI 0 "register_operand" "") 12546 (const_string "2") 12547 (const_string "*")))]) 12548 12549(define_insn "*rotldi3_1_rex64" 12550 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 12551 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 12552 (match_operand:QI 2 "nonmemory_operand" "e,c"))) 12553 (clobber (reg:CC FLAGS_REG))] 12554 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)" 12555 "@ 12556 rol{q}\t{%2, %0|%0, %2} 12557 rol{q}\t{%b2, %0|%0, %b2}" 12558 [(set_attr "type" "rotate") 12559 (set_attr "mode" "DI")]) 12560 12561(define_expand "rotlsi3" 12562 [(set (match_operand:SI 0 "nonimmediate_operand" "") 12563 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "") 12564 (match_operand:QI 2 "nonmemory_operand" ""))) 12565 (clobber (reg:CC FLAGS_REG))] 12566 "" 12567 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;") 12568 12569(define_insn "*rotlsi3_1_one_bit" 12570 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12571 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12572 (match_operand:QI 2 "const1_operand" ""))) 12573 (clobber (reg:CC FLAGS_REG))] 12574 "ix86_binary_operator_ok (ROTATE, SImode, operands) 12575 && (TARGET_SHIFT1 || optimize_size)" 12576 "rol{l}\t%0" 12577 [(set_attr "type" "rotate") 12578 (set (attr "length") 12579 (if_then_else (match_operand:SI 0 "register_operand" "") 12580 (const_string "2") 12581 (const_string "*")))]) 12582 12583(define_insn "*rotlsi3_1_one_bit_zext" 12584 [(set (match_operand:DI 0 "register_operand" "=r") 12585 (zero_extend:DI 12586 (rotate:SI (match_operand:SI 1 "register_operand" "0") 12587 (match_operand:QI 2 "const1_operand" "")))) 12588 (clobber (reg:CC FLAGS_REG))] 12589 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands) 12590 && (TARGET_SHIFT1 || optimize_size)" 12591 "rol{l}\t%k0" 12592 [(set_attr "type" "rotate") 12593 (set_attr "length" "2")]) 12594 12595(define_insn "*rotlsi3_1" 12596 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 12597 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12598 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12599 (clobber (reg:CC FLAGS_REG))] 12600 "ix86_binary_operator_ok (ROTATE, SImode, operands)" 12601 "@ 12602 rol{l}\t{%2, %0|%0, %2} 12603 rol{l}\t{%b2, %0|%0, %b2}" 12604 [(set_attr "type" "rotate") 12605 (set_attr "mode" "SI")]) 12606 12607(define_insn "*rotlsi3_1_zext" 12608 [(set (match_operand:DI 0 "register_operand" "=r,r") 12609 (zero_extend:DI 12610 (rotate:SI (match_operand:SI 1 "register_operand" "0,0") 12611 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 12612 (clobber (reg:CC FLAGS_REG))] 12613 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)" 12614 "@ 12615 rol{l}\t{%2, %k0|%k0, %2} 12616 rol{l}\t{%b2, %k0|%k0, %b2}" 12617 [(set_attr "type" "rotate") 12618 (set_attr "mode" "SI")]) 12619 12620(define_expand "rotlhi3" 12621 [(set (match_operand:HI 0 "nonimmediate_operand" "") 12622 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "") 12623 (match_operand:QI 2 "nonmemory_operand" ""))) 12624 (clobber (reg:CC FLAGS_REG))] 12625 "TARGET_HIMODE_MATH" 12626 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;") 12627 12628(define_insn "*rotlhi3_1_one_bit" 12629 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12630 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12631 (match_operand:QI 2 "const1_operand" ""))) 12632 (clobber (reg:CC FLAGS_REG))] 12633 "ix86_binary_operator_ok (ROTATE, HImode, operands) 12634 && (TARGET_SHIFT1 || optimize_size)" 12635 "rol{w}\t%0" 12636 [(set_attr "type" "rotate") 12637 (set (attr "length") 12638 (if_then_else (match_operand 0 "register_operand" "") 12639 (const_string "2") 12640 (const_string "*")))]) 12641 12642(define_insn "*rotlhi3_1" 12643 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 12644 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 12645 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12646 (clobber (reg:CC FLAGS_REG))] 12647 "ix86_binary_operator_ok (ROTATE, HImode, operands)" 12648 "@ 12649 rol{w}\t{%2, %0|%0, %2} 12650 rol{w}\t{%b2, %0|%0, %b2}" 12651 [(set_attr "type" "rotate") 12652 (set_attr "mode" "HI")]) 12653 12654(define_expand "rotlqi3" 12655 [(set (match_operand:QI 0 "nonimmediate_operand" "") 12656 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "") 12657 (match_operand:QI 2 "nonmemory_operand" ""))) 12658 (clobber (reg:CC FLAGS_REG))] 12659 "TARGET_QIMODE_MATH" 12660 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;") 12661 12662(define_insn "*rotlqi3_1_one_bit_slp" 12663 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 12664 (rotate:QI (match_dup 0) 12665 (match_operand:QI 1 "const1_operand" ""))) 12666 (clobber (reg:CC FLAGS_REG))] 12667 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12668 && (TARGET_SHIFT1 || optimize_size)" 12669 "rol{b}\t%0" 12670 [(set_attr "type" "rotate1") 12671 (set (attr "length") 12672 (if_then_else (match_operand 0 "register_operand" "") 12673 (const_string "2") 12674 (const_string "*")))]) 12675 12676(define_insn "*rotlqi3_1_one_bit" 12677 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12678 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12679 (match_operand:QI 2 "const1_operand" ""))) 12680 (clobber (reg:CC FLAGS_REG))] 12681 "ix86_binary_operator_ok (ROTATE, QImode, operands) 12682 && (TARGET_SHIFT1 || optimize_size)" 12683 "rol{b}\t%0" 12684 [(set_attr "type" "rotate") 12685 (set (attr "length") 12686 (if_then_else (match_operand 0 "register_operand" "") 12687 (const_string "2") 12688 (const_string "*")))]) 12689 12690(define_insn "*rotlqi3_1_slp" 12691 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 12692 (rotate:QI (match_dup 0) 12693 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 12694 (clobber (reg:CC FLAGS_REG))] 12695 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12696 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 12697 "@ 12698 rol{b}\t{%1, %0|%0, %1} 12699 rol{b}\t{%b1, %0|%0, %b1}" 12700 [(set_attr "type" "rotate1") 12701 (set_attr "mode" "QI")]) 12702 12703(define_insn "*rotlqi3_1" 12704 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 12705 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 12706 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12707 (clobber (reg:CC FLAGS_REG))] 12708 "ix86_binary_operator_ok (ROTATE, QImode, operands)" 12709 "@ 12710 rol{b}\t{%2, %0|%0, %2} 12711 rol{b}\t{%b2, %0|%0, %b2}" 12712 [(set_attr "type" "rotate") 12713 (set_attr "mode" "QI")]) 12714 12715(define_expand "rotrdi3" 12716 [(set (match_operand:DI 0 "shiftdi_operand" "") 12717 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "") 12718 (match_operand:QI 2 "nonmemory_operand" ""))) 12719 (clobber (reg:CC FLAGS_REG))] 12720 "" 12721{ 12722 if (TARGET_64BIT) 12723 { 12724 ix86_expand_binary_operator (ROTATERT, DImode, operands); 12725 DONE; 12726 } 12727 if (!const_1_to_31_operand (operands[2], VOIDmode)) 12728 FAIL; 12729 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2])); 12730 DONE; 12731}) 12732 12733;; Implement rotation using two double-precision shift instructions 12734;; and a scratch register. 12735(define_insn_and_split "ix86_rotrdi3" 12736 [(set (match_operand:DI 0 "register_operand" "=r") 12737 (rotatert:DI (match_operand:DI 1 "register_operand" "0") 12738 (match_operand:QI 2 "const_1_to_31_operand" "I"))) 12739 (clobber (reg:CC FLAGS_REG)) 12740 (clobber (match_scratch:SI 3 "=&r"))] 12741 "!TARGET_64BIT" 12742 "" 12743 "&& reload_completed" 12744 [(set (match_dup 3) (match_dup 4)) 12745 (parallel 12746 [(set (match_dup 4) 12747 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2)) 12748 (ashift:SI (match_dup 5) 12749 (minus:QI (const_int 32) (match_dup 2))))) 12750 (clobber (reg:CC FLAGS_REG))]) 12751 (parallel 12752 [(set (match_dup 5) 12753 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2)) 12754 (ashift:SI (match_dup 3) 12755 (minus:QI (const_int 32) (match_dup 2))))) 12756 (clobber (reg:CC FLAGS_REG))])] 12757 "split_di (operands, 1, operands + 4, operands + 5);") 12758 12759(define_insn "*rotrdi3_1_one_bit_rex64" 12760 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12761 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12762 (match_operand:QI 2 "const1_operand" ""))) 12763 (clobber (reg:CC FLAGS_REG))] 12764 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands) 12765 && (TARGET_SHIFT1 || optimize_size)" 12766 "ror{q}\t%0" 12767 [(set_attr "type" "rotate") 12768 (set (attr "length") 12769 (if_then_else (match_operand:DI 0 "register_operand" "") 12770 (const_string "2") 12771 (const_string "*")))]) 12772 12773(define_insn "*rotrdi3_1_rex64" 12774 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 12775 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 12776 (match_operand:QI 2 "nonmemory_operand" "J,c"))) 12777 (clobber (reg:CC FLAGS_REG))] 12778 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)" 12779 "@ 12780 ror{q}\t{%2, %0|%0, %2} 12781 ror{q}\t{%b2, %0|%0, %b2}" 12782 [(set_attr "type" "rotate") 12783 (set_attr "mode" "DI")]) 12784 12785(define_expand "rotrsi3" 12786 [(set (match_operand:SI 0 "nonimmediate_operand" "") 12787 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "") 12788 (match_operand:QI 2 "nonmemory_operand" ""))) 12789 (clobber (reg:CC FLAGS_REG))] 12790 "" 12791 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;") 12792 12793(define_insn "*rotrsi3_1_one_bit" 12794 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12795 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12796 (match_operand:QI 2 "const1_operand" ""))) 12797 (clobber (reg:CC FLAGS_REG))] 12798 "ix86_binary_operator_ok (ROTATERT, SImode, operands) 12799 && (TARGET_SHIFT1 || optimize_size)" 12800 "ror{l}\t%0" 12801 [(set_attr "type" "rotate") 12802 (set (attr "length") 12803 (if_then_else (match_operand:SI 0 "register_operand" "") 12804 (const_string "2") 12805 (const_string "*")))]) 12806 12807(define_insn "*rotrsi3_1_one_bit_zext" 12808 [(set (match_operand:DI 0 "register_operand" "=r") 12809 (zero_extend:DI 12810 (rotatert:SI (match_operand:SI 1 "register_operand" "0") 12811 (match_operand:QI 2 "const1_operand" "")))) 12812 (clobber (reg:CC FLAGS_REG))] 12813 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands) 12814 && (TARGET_SHIFT1 || optimize_size)" 12815 "ror{l}\t%k0" 12816 [(set_attr "type" "rotate") 12817 (set (attr "length") 12818 (if_then_else (match_operand:SI 0 "register_operand" "") 12819 (const_string "2") 12820 (const_string "*")))]) 12821 12822(define_insn "*rotrsi3_1" 12823 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 12824 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12825 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12826 (clobber (reg:CC FLAGS_REG))] 12827 "ix86_binary_operator_ok (ROTATERT, SImode, operands)" 12828 "@ 12829 ror{l}\t{%2, %0|%0, %2} 12830 ror{l}\t{%b2, %0|%0, %b2}" 12831 [(set_attr "type" "rotate") 12832 (set_attr "mode" "SI")]) 12833 12834(define_insn "*rotrsi3_1_zext" 12835 [(set (match_operand:DI 0 "register_operand" "=r,r") 12836 (zero_extend:DI 12837 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0") 12838 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 12839 (clobber (reg:CC FLAGS_REG))] 12840 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)" 12841 "@ 12842 ror{l}\t{%2, %k0|%k0, %2} 12843 ror{l}\t{%b2, %k0|%k0, %b2}" 12844 [(set_attr "type" "rotate") 12845 (set_attr "mode" "SI")]) 12846 12847(define_expand "rotrhi3" 12848 [(set (match_operand:HI 0 "nonimmediate_operand" "") 12849 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "") 12850 (match_operand:QI 2 "nonmemory_operand" ""))) 12851 (clobber (reg:CC FLAGS_REG))] 12852 "TARGET_HIMODE_MATH" 12853 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;") 12854 12855(define_insn "*rotrhi3_one_bit" 12856 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12857 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12858 (match_operand:QI 2 "const1_operand" ""))) 12859 (clobber (reg:CC FLAGS_REG))] 12860 "ix86_binary_operator_ok (ROTATERT, HImode, operands) 12861 && (TARGET_SHIFT1 || optimize_size)" 12862 "ror{w}\t%0" 12863 [(set_attr "type" "rotate") 12864 (set (attr "length") 12865 (if_then_else (match_operand 0 "register_operand" "") 12866 (const_string "2") 12867 (const_string "*")))]) 12868 12869(define_insn "*rotrhi3" 12870 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 12871 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 12872 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12873 (clobber (reg:CC FLAGS_REG))] 12874 "ix86_binary_operator_ok (ROTATERT, HImode, operands)" 12875 "@ 12876 ror{w}\t{%2, %0|%0, %2} 12877 ror{w}\t{%b2, %0|%0, %b2}" 12878 [(set_attr "type" "rotate") 12879 (set_attr "mode" "HI")]) 12880 12881(define_expand "rotrqi3" 12882 [(set (match_operand:QI 0 "nonimmediate_operand" "") 12883 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "") 12884 (match_operand:QI 2 "nonmemory_operand" ""))) 12885 (clobber (reg:CC FLAGS_REG))] 12886 "TARGET_QIMODE_MATH" 12887 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;") 12888 12889(define_insn "*rotrqi3_1_one_bit" 12890 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12891 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12892 (match_operand:QI 2 "const1_operand" ""))) 12893 (clobber (reg:CC FLAGS_REG))] 12894 "ix86_binary_operator_ok (ROTATERT, QImode, operands) 12895 && (TARGET_SHIFT1 || optimize_size)" 12896 "ror{b}\t%0" 12897 [(set_attr "type" "rotate") 12898 (set (attr "length") 12899 (if_then_else (match_operand 0 "register_operand" "") 12900 (const_string "2") 12901 (const_string "*")))]) 12902 12903(define_insn "*rotrqi3_1_one_bit_slp" 12904 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 12905 (rotatert:QI (match_dup 0) 12906 (match_operand:QI 1 "const1_operand" ""))) 12907 (clobber (reg:CC FLAGS_REG))] 12908 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12909 && (TARGET_SHIFT1 || optimize_size)" 12910 "ror{b}\t%0" 12911 [(set_attr "type" "rotate1") 12912 (set (attr "length") 12913 (if_then_else (match_operand 0 "register_operand" "") 12914 (const_string "2") 12915 (const_string "*")))]) 12916 12917(define_insn "*rotrqi3_1" 12918 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 12919 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 12920 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12921 (clobber (reg:CC FLAGS_REG))] 12922 "ix86_binary_operator_ok (ROTATERT, QImode, operands)" 12923 "@ 12924 ror{b}\t{%2, %0|%0, %2} 12925 ror{b}\t{%b2, %0|%0, %b2}" 12926 [(set_attr "type" "rotate") 12927 (set_attr "mode" "QI")]) 12928 12929(define_insn "*rotrqi3_1_slp" 12930 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 12931 (rotatert:QI (match_dup 0) 12932 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 12933 (clobber (reg:CC FLAGS_REG))] 12934 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12935 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 12936 "@ 12937 ror{b}\t{%1, %0|%0, %1} 12938 ror{b}\t{%b1, %0|%0, %b1}" 12939 [(set_attr "type" "rotate1") 12940 (set_attr "mode" "QI")]) 12941 12942;; Bit set / bit test instructions 12943 12944(define_expand "extv" 12945 [(set (match_operand:SI 0 "register_operand" "") 12946 (sign_extract:SI (match_operand:SI 1 "register_operand" "") 12947 (match_operand:SI 2 "const8_operand" "") 12948 (match_operand:SI 3 "const8_operand" "")))] 12949 "" 12950{ 12951 /* Handle extractions from %ah et al. */ 12952 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 12953 FAIL; 12954 12955 /* From mips.md: extract_bit_field doesn't verify that our source 12956 matches the predicate, so check it again here. */ 12957 if (! ext_register_operand (operands[1], VOIDmode)) 12958 FAIL; 12959}) 12960 12961(define_expand "extzv" 12962 [(set (match_operand:SI 0 "register_operand" "") 12963 (zero_extract:SI (match_operand 1 "ext_register_operand" "") 12964 (match_operand:SI 2 "const8_operand" "") 12965 (match_operand:SI 3 "const8_operand" "")))] 12966 "" 12967{ 12968 /* Handle extractions from %ah et al. */ 12969 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 12970 FAIL; 12971 12972 /* From mips.md: extract_bit_field doesn't verify that our source 12973 matches the predicate, so check it again here. */ 12974 if (! ext_register_operand (operands[1], VOIDmode)) 12975 FAIL; 12976}) 12977 12978(define_expand "insv" 12979 [(set (zero_extract (match_operand 0 "ext_register_operand" "") 12980 (match_operand 1 "const8_operand" "") 12981 (match_operand 2 "const8_operand" "")) 12982 (match_operand 3 "register_operand" ""))] 12983 "" 12984{ 12985 /* Handle insertions to %ah et al. */ 12986 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8) 12987 FAIL; 12988 12989 /* From mips.md: insert_bit_field doesn't verify that our source 12990 matches the predicate, so check it again here. */ 12991 if (! ext_register_operand (operands[0], VOIDmode)) 12992 FAIL; 12993 12994 if (TARGET_64BIT) 12995 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3])); 12996 else 12997 emit_insn (gen_movsi_insv_1 (operands[0], operands[3])); 12998 12999 DONE; 13000}) 13001 13002;; %%% bts, btr, btc, bt. 13003;; In general these instructions are *slow* when applied to memory, 13004;; since they enforce atomic operation. When applied to registers, 13005;; it depends on the cpu implementation. They're never faster than 13006;; the corresponding and/ior/xor operations, so with 32-bit there's 13007;; no point. But in 64-bit, we can't hold the relevant immediates 13008;; within the instruction itself, so operating on bits in the high 13009;; 32-bits of a register becomes easier. 13010;; 13011;; These are slow on Nocona, but fast on Athlon64. We do require the use 13012;; of btrq and btcq for corner cases of post-reload expansion of absdf and 13013;; negdf respectively, so they can never be disabled entirely. 13014 13015(define_insn "*btsq" 13016 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 13017 (const_int 1) 13018 (match_operand:DI 1 "const_0_to_63_operand" "")) 13019 (const_int 1)) 13020 (clobber (reg:CC FLAGS_REG))] 13021 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 13022 "bts{q} %1,%0" 13023 [(set_attr "type" "alu1")]) 13024 13025(define_insn "*btrq" 13026 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 13027 (const_int 1) 13028 (match_operand:DI 1 "const_0_to_63_operand" "")) 13029 (const_int 0)) 13030 (clobber (reg:CC FLAGS_REG))] 13031 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 13032 "btr{q} %1,%0" 13033 [(set_attr "type" "alu1")]) 13034 13035(define_insn "*btcq" 13036 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 13037 (const_int 1) 13038 (match_operand:DI 1 "const_0_to_63_operand" "")) 13039 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) 13040 (clobber (reg:CC FLAGS_REG))] 13041 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 13042 "btc{q} %1,%0" 13043 [(set_attr "type" "alu1")]) 13044 13045;; Allow Nocona to avoid these instructions if a register is available. 13046 13047(define_peephole2 13048 [(match_scratch:DI 2 "r") 13049 (parallel [(set (zero_extract:DI 13050 (match_operand:DI 0 "register_operand" "") 13051 (const_int 1) 13052 (match_operand:DI 1 "const_0_to_63_operand" "")) 13053 (const_int 1)) 13054 (clobber (reg:CC FLAGS_REG))])] 13055 "TARGET_64BIT && !TARGET_USE_BT" 13056 [(const_int 0)] 13057{ 13058 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 13059 rtx op1; 13060 13061 if (HOST_BITS_PER_WIDE_INT >= 64) 13062 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13063 else if (i < HOST_BITS_PER_WIDE_INT) 13064 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13065 else 13066 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 13067 13068 op1 = immed_double_const (lo, hi, DImode); 13069 if (i >= 31) 13070 { 13071 emit_move_insn (operands[2], op1); 13072 op1 = operands[2]; 13073 } 13074 13075 emit_insn (gen_iordi3 (operands[0], operands[0], op1)); 13076 DONE; 13077}) 13078 13079(define_peephole2 13080 [(match_scratch:DI 2 "r") 13081 (parallel [(set (zero_extract:DI 13082 (match_operand:DI 0 "register_operand" "") 13083 (const_int 1) 13084 (match_operand:DI 1 "const_0_to_63_operand" "")) 13085 (const_int 0)) 13086 (clobber (reg:CC FLAGS_REG))])] 13087 "TARGET_64BIT && !TARGET_USE_BT" 13088 [(const_int 0)] 13089{ 13090 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 13091 rtx op1; 13092 13093 if (HOST_BITS_PER_WIDE_INT >= 64) 13094 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13095 else if (i < HOST_BITS_PER_WIDE_INT) 13096 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13097 else 13098 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 13099 13100 op1 = immed_double_const (~lo, ~hi, DImode); 13101 if (i >= 32) 13102 { 13103 emit_move_insn (operands[2], op1); 13104 op1 = operands[2]; 13105 } 13106 13107 emit_insn (gen_anddi3 (operands[0], operands[0], op1)); 13108 DONE; 13109}) 13110 13111(define_peephole2 13112 [(match_scratch:DI 2 "r") 13113 (parallel [(set (zero_extract:DI 13114 (match_operand:DI 0 "register_operand" "") 13115 (const_int 1) 13116 (match_operand:DI 1 "const_0_to_63_operand" "")) 13117 (not:DI (zero_extract:DI 13118 (match_dup 0) (const_int 1) (match_dup 1)))) 13119 (clobber (reg:CC FLAGS_REG))])] 13120 "TARGET_64BIT && !TARGET_USE_BT" 13121 [(const_int 0)] 13122{ 13123 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 13124 rtx op1; 13125 13126 if (HOST_BITS_PER_WIDE_INT >= 64) 13127 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13128 else if (i < HOST_BITS_PER_WIDE_INT) 13129 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13130 else 13131 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 13132 13133 op1 = immed_double_const (lo, hi, DImode); 13134 if (i >= 31) 13135 { 13136 emit_move_insn (operands[2], op1); 13137 op1 = operands[2]; 13138 } 13139 13140 emit_insn (gen_xordi3 (operands[0], operands[0], op1)); 13141 DONE; 13142}) 13143 13144;; Store-flag instructions. 13145 13146;; For all sCOND expanders, also expand the compare or test insn that 13147;; generates cc0. Generate an equality comparison if `seq' or `sne'. 13148 13149;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way 13150;; to avoid partial register stalls. Otherwise do things the setcc+movzx 13151;; way, which can later delete the movzx if only QImode is needed. 13152 13153(define_expand "seq" 13154 [(set (match_operand:QI 0 "register_operand" "") 13155 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))] 13156 "" 13157 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;") 13158 13159(define_expand "sne" 13160 [(set (match_operand:QI 0 "register_operand" "") 13161 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))] 13162 "" 13163 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;") 13164 13165(define_expand "sgt" 13166 [(set (match_operand:QI 0 "register_operand" "") 13167 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13168 "" 13169 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;") 13170 13171(define_expand "sgtu" 13172 [(set (match_operand:QI 0 "register_operand" "") 13173 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13174 "" 13175 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;") 13176 13177(define_expand "slt" 13178 [(set (match_operand:QI 0 "register_operand" "") 13179 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13180 "" 13181 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;") 13182 13183(define_expand "sltu" 13184 [(set (match_operand:QI 0 "register_operand" "") 13185 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13186 "" 13187 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;") 13188 13189(define_expand "sge" 13190 [(set (match_operand:QI 0 "register_operand" "") 13191 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))] 13192 "" 13193 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;") 13194 13195(define_expand "sgeu" 13196 [(set (match_operand:QI 0 "register_operand" "") 13197 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13198 "" 13199 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;") 13200 13201(define_expand "sle" 13202 [(set (match_operand:QI 0 "register_operand" "") 13203 (le:QI (reg:CC FLAGS_REG) (const_int 0)))] 13204 "" 13205 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;") 13206 13207(define_expand "sleu" 13208 [(set (match_operand:QI 0 "register_operand" "") 13209 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13210 "" 13211 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;") 13212 13213(define_expand "sunordered" 13214 [(set (match_operand:QI 0 "register_operand" "") 13215 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))] 13216 "TARGET_80387 || TARGET_SSE" 13217 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;") 13218 13219(define_expand "sordered" 13220 [(set (match_operand:QI 0 "register_operand" "") 13221 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))] 13222 "TARGET_80387" 13223 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;") 13224 13225(define_expand "suneq" 13226 [(set (match_operand:QI 0 "register_operand" "") 13227 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))] 13228 "TARGET_80387 || TARGET_SSE" 13229 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;") 13230 13231(define_expand "sunge" 13232 [(set (match_operand:QI 0 "register_operand" "") 13233 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))] 13234 "TARGET_80387 || TARGET_SSE" 13235 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;") 13236 13237(define_expand "sungt" 13238 [(set (match_operand:QI 0 "register_operand" "") 13239 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13240 "TARGET_80387 || TARGET_SSE" 13241 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;") 13242 13243(define_expand "sunle" 13244 [(set (match_operand:QI 0 "register_operand" "") 13245 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))] 13246 "TARGET_80387 || TARGET_SSE" 13247 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;") 13248 13249(define_expand "sunlt" 13250 [(set (match_operand:QI 0 "register_operand" "") 13251 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13252 "TARGET_80387 || TARGET_SSE" 13253 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;") 13254 13255(define_expand "sltgt" 13256 [(set (match_operand:QI 0 "register_operand" "") 13257 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13258 "TARGET_80387 || TARGET_SSE" 13259 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;") 13260 13261(define_insn "*setcc_1" 13262 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 13263 (match_operator:QI 1 "ix86_comparison_operator" 13264 [(reg FLAGS_REG) (const_int 0)]))] 13265 "" 13266 "set%C1\t%0" 13267 [(set_attr "type" "setcc") 13268 (set_attr "mode" "QI")]) 13269 13270(define_insn "*setcc_2" 13271 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 13272 (match_operator:QI 1 "ix86_comparison_operator" 13273 [(reg FLAGS_REG) (const_int 0)]))] 13274 "" 13275 "set%C1\t%0" 13276 [(set_attr "type" "setcc") 13277 (set_attr "mode" "QI")]) 13278 13279;; In general it is not safe to assume too much about CCmode registers, 13280;; so simplify-rtx stops when it sees a second one. Under certain 13281;; conditions this is safe on x86, so help combine not create 13282;; 13283;; seta %al 13284;; testb %al, %al 13285;; sete %al 13286 13287(define_split 13288 [(set (match_operand:QI 0 "nonimmediate_operand" "") 13289 (ne:QI (match_operator 1 "ix86_comparison_operator" 13290 [(reg FLAGS_REG) (const_int 0)]) 13291 (const_int 0)))] 13292 "" 13293 [(set (match_dup 0) (match_dup 1))] 13294{ 13295 PUT_MODE (operands[1], QImode); 13296}) 13297 13298(define_split 13299 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 13300 (ne:QI (match_operator 1 "ix86_comparison_operator" 13301 [(reg FLAGS_REG) (const_int 0)]) 13302 (const_int 0)))] 13303 "" 13304 [(set (match_dup 0) (match_dup 1))] 13305{ 13306 PUT_MODE (operands[1], QImode); 13307}) 13308 13309(define_split 13310 [(set (match_operand:QI 0 "nonimmediate_operand" "") 13311 (eq:QI (match_operator 1 "ix86_comparison_operator" 13312 [(reg FLAGS_REG) (const_int 0)]) 13313 (const_int 0)))] 13314 "" 13315 [(set (match_dup 0) (match_dup 1))] 13316{ 13317 rtx new_op1 = copy_rtx (operands[1]); 13318 operands[1] = new_op1; 13319 PUT_MODE (new_op1, QImode); 13320 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), 13321 GET_MODE (XEXP (new_op1, 0)))); 13322 13323 /* Make sure that (a) the CCmode we have for the flags is strong 13324 enough for the reversed compare or (b) we have a valid FP compare. */ 13325 if (! ix86_comparison_operator (new_op1, VOIDmode)) 13326 FAIL; 13327}) 13328 13329(define_split 13330 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 13331 (eq:QI (match_operator 1 "ix86_comparison_operator" 13332 [(reg FLAGS_REG) (const_int 0)]) 13333 (const_int 0)))] 13334 "" 13335 [(set (match_dup 0) (match_dup 1))] 13336{ 13337 rtx new_op1 = copy_rtx (operands[1]); 13338 operands[1] = new_op1; 13339 PUT_MODE (new_op1, QImode); 13340 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), 13341 GET_MODE (XEXP (new_op1, 0)))); 13342 13343 /* Make sure that (a) the CCmode we have for the flags is strong 13344 enough for the reversed compare or (b) we have a valid FP compare. */ 13345 if (! ix86_comparison_operator (new_op1, VOIDmode)) 13346 FAIL; 13347}) 13348 13349;; The SSE store flag instructions saves 0 or 0xffffffff to the result. 13350;; subsequent logical operations are used to imitate conditional moves. 13351;; 0xffffffff is NaN, but not in normalized form, so we can't represent 13352;; it directly. 13353 13354(define_insn "*sse_setccsf" 13355 [(set (match_operand:SF 0 "register_operand" "=x") 13356 (match_operator:SF 1 "sse_comparison_operator" 13357 [(match_operand:SF 2 "register_operand" "0") 13358 (match_operand:SF 3 "nonimmediate_operand" "xm")]))] 13359 "TARGET_SSE" 13360 "cmp%D1ss\t{%3, %0|%0, %3}" 13361 [(set_attr "type" "ssecmp") 13362 (set_attr "mode" "SF")]) 13363 13364(define_insn "*sse_setccdf" 13365 [(set (match_operand:DF 0 "register_operand" "=Y") 13366 (match_operator:DF 1 "sse_comparison_operator" 13367 [(match_operand:DF 2 "register_operand" "0") 13368 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))] 13369 "TARGET_SSE2" 13370 "cmp%D1sd\t{%3, %0|%0, %3}" 13371 [(set_attr "type" "ssecmp") 13372 (set_attr "mode" "DF")]) 13373 13374;; Basic conditional jump instructions. 13375;; We ignore the overflow flag for signed branch instructions. 13376 13377;; For all bCOND expanders, also expand the compare or test insn that 13378;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'. 13379 13380(define_expand "beq" 13381 [(set (pc) 13382 (if_then_else (match_dup 1) 13383 (label_ref (match_operand 0 "" "")) 13384 (pc)))] 13385 "" 13386 "ix86_expand_branch (EQ, operands[0]); DONE;") 13387 13388(define_expand "bne" 13389 [(set (pc) 13390 (if_then_else (match_dup 1) 13391 (label_ref (match_operand 0 "" "")) 13392 (pc)))] 13393 "" 13394 "ix86_expand_branch (NE, operands[0]); DONE;") 13395 13396(define_expand "bgt" 13397 [(set (pc) 13398 (if_then_else (match_dup 1) 13399 (label_ref (match_operand 0 "" "")) 13400 (pc)))] 13401 "" 13402 "ix86_expand_branch (GT, operands[0]); DONE;") 13403 13404(define_expand "bgtu" 13405 [(set (pc) 13406 (if_then_else (match_dup 1) 13407 (label_ref (match_operand 0 "" "")) 13408 (pc)))] 13409 "" 13410 "ix86_expand_branch (GTU, operands[0]); DONE;") 13411 13412(define_expand "blt" 13413 [(set (pc) 13414 (if_then_else (match_dup 1) 13415 (label_ref (match_operand 0 "" "")) 13416 (pc)))] 13417 "" 13418 "ix86_expand_branch (LT, operands[0]); DONE;") 13419 13420(define_expand "bltu" 13421 [(set (pc) 13422 (if_then_else (match_dup 1) 13423 (label_ref (match_operand 0 "" "")) 13424 (pc)))] 13425 "" 13426 "ix86_expand_branch (LTU, operands[0]); DONE;") 13427 13428(define_expand "bge" 13429 [(set (pc) 13430 (if_then_else (match_dup 1) 13431 (label_ref (match_operand 0 "" "")) 13432 (pc)))] 13433 "" 13434 "ix86_expand_branch (GE, operands[0]); DONE;") 13435 13436(define_expand "bgeu" 13437 [(set (pc) 13438 (if_then_else (match_dup 1) 13439 (label_ref (match_operand 0 "" "")) 13440 (pc)))] 13441 "" 13442 "ix86_expand_branch (GEU, operands[0]); DONE;") 13443 13444(define_expand "ble" 13445 [(set (pc) 13446 (if_then_else (match_dup 1) 13447 (label_ref (match_operand 0 "" "")) 13448 (pc)))] 13449 "" 13450 "ix86_expand_branch (LE, operands[0]); DONE;") 13451 13452(define_expand "bleu" 13453 [(set (pc) 13454 (if_then_else (match_dup 1) 13455 (label_ref (match_operand 0 "" "")) 13456 (pc)))] 13457 "" 13458 "ix86_expand_branch (LEU, operands[0]); DONE;") 13459 13460(define_expand "bunordered" 13461 [(set (pc) 13462 (if_then_else (match_dup 1) 13463 (label_ref (match_operand 0 "" "")) 13464 (pc)))] 13465 "TARGET_80387 || TARGET_SSE_MATH" 13466 "ix86_expand_branch (UNORDERED, operands[0]); DONE;") 13467 13468(define_expand "bordered" 13469 [(set (pc) 13470 (if_then_else (match_dup 1) 13471 (label_ref (match_operand 0 "" "")) 13472 (pc)))] 13473 "TARGET_80387 || TARGET_SSE_MATH" 13474 "ix86_expand_branch (ORDERED, operands[0]); DONE;") 13475 13476(define_expand "buneq" 13477 [(set (pc) 13478 (if_then_else (match_dup 1) 13479 (label_ref (match_operand 0 "" "")) 13480 (pc)))] 13481 "TARGET_80387 || TARGET_SSE_MATH" 13482 "ix86_expand_branch (UNEQ, operands[0]); DONE;") 13483 13484(define_expand "bunge" 13485 [(set (pc) 13486 (if_then_else (match_dup 1) 13487 (label_ref (match_operand 0 "" "")) 13488 (pc)))] 13489 "TARGET_80387 || TARGET_SSE_MATH" 13490 "ix86_expand_branch (UNGE, operands[0]); DONE;") 13491 13492(define_expand "bungt" 13493 [(set (pc) 13494 (if_then_else (match_dup 1) 13495 (label_ref (match_operand 0 "" "")) 13496 (pc)))] 13497 "TARGET_80387 || TARGET_SSE_MATH" 13498 "ix86_expand_branch (UNGT, operands[0]); DONE;") 13499 13500(define_expand "bunle" 13501 [(set (pc) 13502 (if_then_else (match_dup 1) 13503 (label_ref (match_operand 0 "" "")) 13504 (pc)))] 13505 "TARGET_80387 || TARGET_SSE_MATH" 13506 "ix86_expand_branch (UNLE, operands[0]); DONE;") 13507 13508(define_expand "bunlt" 13509 [(set (pc) 13510 (if_then_else (match_dup 1) 13511 (label_ref (match_operand 0 "" "")) 13512 (pc)))] 13513 "TARGET_80387 || TARGET_SSE_MATH" 13514 "ix86_expand_branch (UNLT, operands[0]); DONE;") 13515 13516(define_expand "bltgt" 13517 [(set (pc) 13518 (if_then_else (match_dup 1) 13519 (label_ref (match_operand 0 "" "")) 13520 (pc)))] 13521 "TARGET_80387 || TARGET_SSE_MATH" 13522 "ix86_expand_branch (LTGT, operands[0]); DONE;") 13523 13524(define_insn "*jcc_1" 13525 [(set (pc) 13526 (if_then_else (match_operator 1 "ix86_comparison_operator" 13527 [(reg FLAGS_REG) (const_int 0)]) 13528 (label_ref (match_operand 0 "" "")) 13529 (pc)))] 13530 "" 13531 "%+j%C1\t%l0" 13532 [(set_attr "type" "ibr") 13533 (set_attr "modrm" "0") 13534 (set (attr "length") 13535 (if_then_else (and (ge (minus (match_dup 0) (pc)) 13536 (const_int -126)) 13537 (lt (minus (match_dup 0) (pc)) 13538 (const_int 128))) 13539 (const_int 2) 13540 (const_int 6)))]) 13541 13542(define_insn "*jcc_2" 13543 [(set (pc) 13544 (if_then_else (match_operator 1 "ix86_comparison_operator" 13545 [(reg FLAGS_REG) (const_int 0)]) 13546 (pc) 13547 (label_ref (match_operand 0 "" ""))))] 13548 "" 13549 "%+j%c1\t%l0" 13550 [(set_attr "type" "ibr") 13551 (set_attr "modrm" "0") 13552 (set (attr "length") 13553 (if_then_else (and (ge (minus (match_dup 0) (pc)) 13554 (const_int -126)) 13555 (lt (minus (match_dup 0) (pc)) 13556 (const_int 128))) 13557 (const_int 2) 13558 (const_int 6)))]) 13559 13560;; In general it is not safe to assume too much about CCmode registers, 13561;; so simplify-rtx stops when it sees a second one. Under certain 13562;; conditions this is safe on x86, so help combine not create 13563;; 13564;; seta %al 13565;; testb %al, %al 13566;; je Lfoo 13567 13568(define_split 13569 [(set (pc) 13570 (if_then_else (ne (match_operator 0 "ix86_comparison_operator" 13571 [(reg FLAGS_REG) (const_int 0)]) 13572 (const_int 0)) 13573 (label_ref (match_operand 1 "" "")) 13574 (pc)))] 13575 "" 13576 [(set (pc) 13577 (if_then_else (match_dup 0) 13578 (label_ref (match_dup 1)) 13579 (pc)))] 13580{ 13581 PUT_MODE (operands[0], VOIDmode); 13582}) 13583 13584(define_split 13585 [(set (pc) 13586 (if_then_else (eq (match_operator 0 "ix86_comparison_operator" 13587 [(reg FLAGS_REG) (const_int 0)]) 13588 (const_int 0)) 13589 (label_ref (match_operand 1 "" "")) 13590 (pc)))] 13591 "" 13592 [(set (pc) 13593 (if_then_else (match_dup 0) 13594 (label_ref (match_dup 1)) 13595 (pc)))] 13596{ 13597 rtx new_op0 = copy_rtx (operands[0]); 13598 operands[0] = new_op0; 13599 PUT_MODE (new_op0, VOIDmode); 13600 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0), 13601 GET_MODE (XEXP (new_op0, 0)))); 13602 13603 /* Make sure that (a) the CCmode we have for the flags is strong 13604 enough for the reversed compare or (b) we have a valid FP compare. */ 13605 if (! ix86_comparison_operator (new_op0, VOIDmode)) 13606 FAIL; 13607}) 13608 13609;; Define combination compare-and-branch fp compare instructions to use 13610;; during early optimization. Splitting the operation apart early makes 13611;; for bad code when we want to reverse the operation. 13612 13613(define_insn "*fp_jcc_1_mixed" 13614 [(set (pc) 13615 (if_then_else (match_operator 0 "comparison_operator" 13616 [(match_operand 1 "register_operand" "f,x") 13617 (match_operand 2 "nonimmediate_operand" "f,xm")]) 13618 (label_ref (match_operand 3 "" "")) 13619 (pc))) 13620 (clobber (reg:CCFP FPSR_REG)) 13621 (clobber (reg:CCFP FLAGS_REG))] 13622 "TARGET_MIX_SSE_I387 13623 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13624 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13625 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13626 "#") 13627 13628(define_insn "*fp_jcc_1_sse" 13629 [(set (pc) 13630 (if_then_else (match_operator 0 "comparison_operator" 13631 [(match_operand 1 "register_operand" "x") 13632 (match_operand 2 "nonimmediate_operand" "xm")]) 13633 (label_ref (match_operand 3 "" "")) 13634 (pc))) 13635 (clobber (reg:CCFP FPSR_REG)) 13636 (clobber (reg:CCFP FLAGS_REG))] 13637 "TARGET_SSE_MATH 13638 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13639 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13640 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13641 "#") 13642 13643(define_insn "*fp_jcc_1_387" 13644 [(set (pc) 13645 (if_then_else (match_operator 0 "comparison_operator" 13646 [(match_operand 1 "register_operand" "f") 13647 (match_operand 2 "register_operand" "f")]) 13648 (label_ref (match_operand 3 "" "")) 13649 (pc))) 13650 (clobber (reg:CCFP FPSR_REG)) 13651 (clobber (reg:CCFP FLAGS_REG))] 13652 "TARGET_CMOVE && TARGET_80387 13653 && FLOAT_MODE_P (GET_MODE (operands[1])) 13654 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13655 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13656 "#") 13657 13658(define_insn "*fp_jcc_2_mixed" 13659 [(set (pc) 13660 (if_then_else (match_operator 0 "comparison_operator" 13661 [(match_operand 1 "register_operand" "f,x") 13662 (match_operand 2 "nonimmediate_operand" "f,xm")]) 13663 (pc) 13664 (label_ref (match_operand 3 "" "")))) 13665 (clobber (reg:CCFP FPSR_REG)) 13666 (clobber (reg:CCFP FLAGS_REG))] 13667 "TARGET_MIX_SSE_I387 13668 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13669 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13670 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13671 "#") 13672 13673(define_insn "*fp_jcc_2_sse" 13674 [(set (pc) 13675 (if_then_else (match_operator 0 "comparison_operator" 13676 [(match_operand 1 "register_operand" "x") 13677 (match_operand 2 "nonimmediate_operand" "xm")]) 13678 (pc) 13679 (label_ref (match_operand 3 "" "")))) 13680 (clobber (reg:CCFP FPSR_REG)) 13681 (clobber (reg:CCFP FLAGS_REG))] 13682 "TARGET_SSE_MATH 13683 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13684 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13685 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13686 "#") 13687 13688(define_insn "*fp_jcc_2_387" 13689 [(set (pc) 13690 (if_then_else (match_operator 0 "comparison_operator" 13691 [(match_operand 1 "register_operand" "f") 13692 (match_operand 2 "register_operand" "f")]) 13693 (pc) 13694 (label_ref (match_operand 3 "" "")))) 13695 (clobber (reg:CCFP FPSR_REG)) 13696 (clobber (reg:CCFP FLAGS_REG))] 13697 "TARGET_CMOVE && TARGET_80387 13698 && FLOAT_MODE_P (GET_MODE (operands[1])) 13699 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13700 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13701 "#") 13702 13703(define_insn "*fp_jcc_3_387" 13704 [(set (pc) 13705 (if_then_else (match_operator 0 "comparison_operator" 13706 [(match_operand 1 "register_operand" "f") 13707 (match_operand 2 "nonimmediate_operand" "fm")]) 13708 (label_ref (match_operand 3 "" "")) 13709 (pc))) 13710 (clobber (reg:CCFP FPSR_REG)) 13711 (clobber (reg:CCFP FLAGS_REG)) 13712 (clobber (match_scratch:HI 4 "=a"))] 13713 "TARGET_80387 13714 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) 13715 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13716 && !ix86_use_fcomi_compare (GET_CODE (operands[0])) 13717 && SELECT_CC_MODE (GET_CODE (operands[0]), 13718 operands[1], operands[2]) == CCFPmode 13719 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13720 "#") 13721 13722(define_insn "*fp_jcc_4_387" 13723 [(set (pc) 13724 (if_then_else (match_operator 0 "comparison_operator" 13725 [(match_operand 1 "register_operand" "f") 13726 (match_operand 2 "nonimmediate_operand" "fm")]) 13727 (pc) 13728 (label_ref (match_operand 3 "" "")))) 13729 (clobber (reg:CCFP FPSR_REG)) 13730 (clobber (reg:CCFP FLAGS_REG)) 13731 (clobber (match_scratch:HI 4 "=a"))] 13732 "TARGET_80387 13733 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) 13734 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13735 && !ix86_use_fcomi_compare (GET_CODE (operands[0])) 13736 && SELECT_CC_MODE (GET_CODE (operands[0]), 13737 operands[1], operands[2]) == CCFPmode 13738 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13739 "#") 13740 13741(define_insn "*fp_jcc_5_387" 13742 [(set (pc) 13743 (if_then_else (match_operator 0 "comparison_operator" 13744 [(match_operand 1 "register_operand" "f") 13745 (match_operand 2 "register_operand" "f")]) 13746 (label_ref (match_operand 3 "" "")) 13747 (pc))) 13748 (clobber (reg:CCFP FPSR_REG)) 13749 (clobber (reg:CCFP FLAGS_REG)) 13750 (clobber (match_scratch:HI 4 "=a"))] 13751 "TARGET_80387 13752 && FLOAT_MODE_P (GET_MODE (operands[1])) 13753 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13754 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13755 "#") 13756 13757(define_insn "*fp_jcc_6_387" 13758 [(set (pc) 13759 (if_then_else (match_operator 0 "comparison_operator" 13760 [(match_operand 1 "register_operand" "f") 13761 (match_operand 2 "register_operand" "f")]) 13762 (pc) 13763 (label_ref (match_operand 3 "" "")))) 13764 (clobber (reg:CCFP FPSR_REG)) 13765 (clobber (reg:CCFP FLAGS_REG)) 13766 (clobber (match_scratch:HI 4 "=a"))] 13767 "TARGET_80387 13768 && FLOAT_MODE_P (GET_MODE (operands[1])) 13769 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13770 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13771 "#") 13772 13773(define_insn "*fp_jcc_7_387" 13774 [(set (pc) 13775 (if_then_else (match_operator 0 "comparison_operator" 13776 [(match_operand 1 "register_operand" "f") 13777 (match_operand 2 "const0_operand" "X")]) 13778 (label_ref (match_operand 3 "" "")) 13779 (pc))) 13780 (clobber (reg:CCFP FPSR_REG)) 13781 (clobber (reg:CCFP FLAGS_REG)) 13782 (clobber (match_scratch:HI 4 "=a"))] 13783 "TARGET_80387 13784 && FLOAT_MODE_P (GET_MODE (operands[1])) 13785 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13786 && !ix86_use_fcomi_compare (GET_CODE (operands[0])) 13787 && SELECT_CC_MODE (GET_CODE (operands[0]), 13788 operands[1], operands[2]) == CCFPmode 13789 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13790 "#") 13791 13792;; The order of operands in *fp_jcc_8_387 is forced by combine in 13793;; simplify_comparison () function. Float operator is treated as RTX_OBJ 13794;; with a precedence over other operators and is always put in the first 13795;; place. Swap condition and operands to match ficom instruction. 13796 13797(define_insn "*fp_jcc_8<mode>_387" 13798 [(set (pc) 13799 (if_then_else (match_operator 0 "comparison_operator" 13800 [(match_operator 1 "float_operator" 13801 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")]) 13802 (match_operand 3 "register_operand" "f,f")]) 13803 (label_ref (match_operand 4 "" "")) 13804 (pc))) 13805 (clobber (reg:CCFP FPSR_REG)) 13806 (clobber (reg:CCFP FLAGS_REG)) 13807 (clobber (match_scratch:HI 5 "=a,a"))] 13808 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 13809 && FLOAT_MODE_P (GET_MODE (operands[3])) 13810 && GET_MODE (operands[1]) == GET_MODE (operands[3]) 13811 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0]))) 13812 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode 13813 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))" 13814 "#") 13815 13816(define_split 13817 [(set (pc) 13818 (if_then_else (match_operator 0 "comparison_operator" 13819 [(match_operand 1 "register_operand" "") 13820 (match_operand 2 "nonimmediate_operand" "")]) 13821 (match_operand 3 "" "") 13822 (match_operand 4 "" ""))) 13823 (clobber (reg:CCFP FPSR_REG)) 13824 (clobber (reg:CCFP FLAGS_REG))] 13825 "reload_completed" 13826 [(const_int 0)] 13827{ 13828 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 13829 operands[3], operands[4], NULL_RTX, NULL_RTX); 13830 DONE; 13831}) 13832 13833(define_split 13834 [(set (pc) 13835 (if_then_else (match_operator 0 "comparison_operator" 13836 [(match_operand 1 "register_operand" "") 13837 (match_operand 2 "general_operand" "")]) 13838 (match_operand 3 "" "") 13839 (match_operand 4 "" ""))) 13840 (clobber (reg:CCFP FPSR_REG)) 13841 (clobber (reg:CCFP FLAGS_REG)) 13842 (clobber (match_scratch:HI 5 "=a"))] 13843 "reload_completed" 13844 [(const_int 0)] 13845{ 13846 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 13847 operands[3], operands[4], operands[5], NULL_RTX); 13848 DONE; 13849}) 13850 13851(define_split 13852 [(set (pc) 13853 (if_then_else (match_operator 0 "comparison_operator" 13854 [(match_operator 1 "float_operator" 13855 [(match_operand:X87MODEI12 2 "memory_operand" "")]) 13856 (match_operand 3 "register_operand" "")]) 13857 (match_operand 4 "" "") 13858 (match_operand 5 "" ""))) 13859 (clobber (reg:CCFP FPSR_REG)) 13860 (clobber (reg:CCFP FLAGS_REG)) 13861 (clobber (match_scratch:HI 6 "=a"))] 13862 "reload_completed" 13863 [(const_int 0)] 13864{ 13865 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]); 13866 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), 13867 operands[3], operands[7], 13868 operands[4], operands[5], operands[6], NULL_RTX); 13869 DONE; 13870}) 13871 13872;; %%% Kill this when reload knows how to do it. 13873(define_split 13874 [(set (pc) 13875 (if_then_else (match_operator 0 "comparison_operator" 13876 [(match_operator 1 "float_operator" 13877 [(match_operand:X87MODEI12 2 "register_operand" "")]) 13878 (match_operand 3 "register_operand" "")]) 13879 (match_operand 4 "" "") 13880 (match_operand 5 "" ""))) 13881 (clobber (reg:CCFP FPSR_REG)) 13882 (clobber (reg:CCFP FLAGS_REG)) 13883 (clobber (match_scratch:HI 6 "=a"))] 13884 "reload_completed" 13885 [(const_int 0)] 13886{ 13887 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); 13888 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]); 13889 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), 13890 operands[3], operands[7], 13891 operands[4], operands[5], operands[6], operands[2]); 13892 DONE; 13893}) 13894 13895;; Unconditional and other jump instructions 13896 13897(define_insn "jump" 13898 [(set (pc) 13899 (label_ref (match_operand 0 "" "")))] 13900 "" 13901 "jmp\t%l0" 13902 [(set_attr "type" "ibr") 13903 (set (attr "length") 13904 (if_then_else (and (ge (minus (match_dup 0) (pc)) 13905 (const_int -126)) 13906 (lt (minus (match_dup 0) (pc)) 13907 (const_int 128))) 13908 (const_int 2) 13909 (const_int 5))) 13910 (set_attr "modrm" "0")]) 13911 13912(define_expand "indirect_jump" 13913 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))] 13914 "" 13915 "") 13916 13917(define_insn "*indirect_jump" 13918 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))] 13919 "!TARGET_64BIT" 13920 "jmp\t%A0" 13921 [(set_attr "type" "ibr") 13922 (set_attr "length_immediate" "0")]) 13923 13924(define_insn "*indirect_jump_rtx64" 13925 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))] 13926 "TARGET_64BIT" 13927 "jmp\t%A0" 13928 [(set_attr "type" "ibr") 13929 (set_attr "length_immediate" "0")]) 13930 13931(define_expand "tablejump" 13932 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm")) 13933 (use (label_ref (match_operand 1 "" "")))])] 13934 "" 13935{ 13936 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit) 13937 relative. Convert the relative address to an absolute address. */ 13938 if (flag_pic) 13939 { 13940 rtx op0, op1; 13941 enum rtx_code code; 13942 13943 if (TARGET_64BIT) 13944 { 13945 code = PLUS; 13946 op0 = operands[0]; 13947 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]); 13948 } 13949 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA) 13950 { 13951 code = PLUS; 13952 op0 = operands[0]; 13953 op1 = pic_offset_table_rtx; 13954 } 13955 else 13956 { 13957 code = MINUS; 13958 op0 = pic_offset_table_rtx; 13959 op1 = operands[0]; 13960 } 13961 13962 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0, 13963 OPTAB_DIRECT); 13964 } 13965}) 13966 13967(define_insn "*tablejump_1" 13968 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm")) 13969 (use (label_ref (match_operand 1 "" "")))] 13970 "!TARGET_64BIT" 13971 "jmp\t%A0" 13972 [(set_attr "type" "ibr") 13973 (set_attr "length_immediate" "0")]) 13974 13975(define_insn "*tablejump_1_rtx64" 13976 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm")) 13977 (use (label_ref (match_operand 1 "" "")))] 13978 "TARGET_64BIT" 13979 "jmp\t%A0" 13980 [(set_attr "type" "ibr") 13981 (set_attr "length_immediate" "0")]) 13982 13983;; Convert setcc + movzbl to xor + setcc if operands don't overlap. 13984 13985(define_peephole2 13986 [(set (reg FLAGS_REG) (match_operand 0 "" "")) 13987 (set (match_operand:QI 1 "register_operand" "") 13988 (match_operator:QI 2 "ix86_comparison_operator" 13989 [(reg FLAGS_REG) (const_int 0)])) 13990 (set (match_operand 3 "q_regs_operand" "") 13991 (zero_extend (match_dup 1)))] 13992 "(peep2_reg_dead_p (3, operands[1]) 13993 || operands_match_p (operands[1], operands[3])) 13994 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 13995 [(set (match_dup 4) (match_dup 0)) 13996 (set (strict_low_part (match_dup 5)) 13997 (match_dup 2))] 13998{ 13999 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 14000 operands[5] = gen_lowpart (QImode, operands[3]); 14001 ix86_expand_clear (operands[3]); 14002}) 14003 14004;; Similar, but match zero_extendhisi2_and, which adds a clobber. 14005 14006(define_peephole2 14007 [(set (reg FLAGS_REG) (match_operand 0 "" "")) 14008 (set (match_operand:QI 1 "register_operand" "") 14009 (match_operator:QI 2 "ix86_comparison_operator" 14010 [(reg FLAGS_REG) (const_int 0)])) 14011 (parallel [(set (match_operand 3 "q_regs_operand" "") 14012 (zero_extend (match_dup 1))) 14013 (clobber (reg:CC FLAGS_REG))])] 14014 "(peep2_reg_dead_p (3, operands[1]) 14015 || operands_match_p (operands[1], operands[3])) 14016 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 14017 [(set (match_dup 4) (match_dup 0)) 14018 (set (strict_low_part (match_dup 5)) 14019 (match_dup 2))] 14020{ 14021 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 14022 operands[5] = gen_lowpart (QImode, operands[3]); 14023 ix86_expand_clear (operands[3]); 14024}) 14025 14026;; Call instructions. 14027 14028;; The predicates normally associated with named expanders are not properly 14029;; checked for calls. This is a bug in the generic code, but it isn't that 14030;; easy to fix. Ignore it for now and be prepared to fix things up. 14031 14032;; Call subroutine returning no value. 14033 14034(define_expand "call_pop" 14035 [(parallel [(call (match_operand:QI 0 "" "") 14036 (match_operand:SI 1 "" "")) 14037 (set (reg:SI SP_REG) 14038 (plus:SI (reg:SI SP_REG) 14039 (match_operand:SI 3 "" "")))])] 14040 "!TARGET_64BIT" 14041{ 14042 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0); 14043 DONE; 14044}) 14045 14046(define_insn "*call_pop_0" 14047 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" "")) 14048 (match_operand:SI 1 "" "")) 14049 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 14050 (match_operand:SI 2 "immediate_operand" "")))] 14051 "!TARGET_64BIT" 14052{ 14053 if (SIBLING_CALL_P (insn)) 14054 return "jmp\t%P0"; 14055 else 14056 return "call\t%P0"; 14057} 14058 [(set_attr "type" "call")]) 14059 14060(define_insn "*call_pop_1" 14061 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm")) 14062 (match_operand:SI 1 "" "")) 14063 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 14064 (match_operand:SI 2 "immediate_operand" "i")))] 14065 "!TARGET_64BIT" 14066{ 14067 if (constant_call_address_operand (operands[0], Pmode)) 14068 { 14069 if (SIBLING_CALL_P (insn)) 14070 return "jmp\t%P0"; 14071 else 14072 return "call\t%P0"; 14073 } 14074 if (SIBLING_CALL_P (insn)) 14075 return "jmp\t%A0"; 14076 else 14077 return "call\t%A0"; 14078} 14079 [(set_attr "type" "call")]) 14080 14081(define_expand "call" 14082 [(call (match_operand:QI 0 "" "") 14083 (match_operand 1 "" "")) 14084 (use (match_operand 2 "" ""))] 14085 "" 14086{ 14087 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0); 14088 DONE; 14089}) 14090 14091(define_expand "sibcall" 14092 [(call (match_operand:QI 0 "" "") 14093 (match_operand 1 "" "")) 14094 (use (match_operand 2 "" ""))] 14095 "" 14096{ 14097 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1); 14098 DONE; 14099}) 14100 14101(define_insn "*call_0" 14102 [(call (mem:QI (match_operand 0 "constant_call_address_operand" "")) 14103 (match_operand 1 "" ""))] 14104 "" 14105{ 14106 if (SIBLING_CALL_P (insn)) 14107 return "jmp\t%P0"; 14108 else 14109 return "call\t%P0"; 14110} 14111 [(set_attr "type" "call")]) 14112 14113(define_insn "*call_1" 14114 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm")) 14115 (match_operand 1 "" ""))] 14116 "!SIBLING_CALL_P (insn) && !TARGET_64BIT" 14117{ 14118 if (constant_call_address_operand (operands[0], Pmode)) 14119 return "call\t%P0"; 14120 return "call\t%A0"; 14121} 14122 [(set_attr "type" "call")]) 14123 14124(define_insn "*sibcall_1" 14125 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a")) 14126 (match_operand 1 "" ""))] 14127 "SIBLING_CALL_P (insn) && !TARGET_64BIT" 14128{ 14129 if (constant_call_address_operand (operands[0], Pmode)) 14130 return "jmp\t%P0"; 14131 return "jmp\t%A0"; 14132} 14133 [(set_attr "type" "call")]) 14134 14135(define_insn "*call_1_rex64" 14136 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm")) 14137 (match_operand 1 "" ""))] 14138 "!SIBLING_CALL_P (insn) && TARGET_64BIT" 14139{ 14140 if (constant_call_address_operand (operands[0], Pmode)) 14141 return "call\t%P0"; 14142 return "call\t%A0"; 14143} 14144 [(set_attr "type" "call")]) 14145 14146(define_insn "*sibcall_1_rex64" 14147 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" "")) 14148 (match_operand 1 "" ""))] 14149 "SIBLING_CALL_P (insn) && TARGET_64BIT" 14150 "jmp\t%P0" 14151 [(set_attr "type" "call")]) 14152 14153(define_insn "*sibcall_1_rex64_v" 14154 [(call (mem:QI (reg:DI 40)) 14155 (match_operand 0 "" ""))] 14156 "SIBLING_CALL_P (insn) && TARGET_64BIT" 14157 "jmp\t*%%r11" 14158 [(set_attr "type" "call")]) 14159 14160 14161;; Call subroutine, returning value in operand 0 14162 14163(define_expand "call_value_pop" 14164 [(parallel [(set (match_operand 0 "" "") 14165 (call (match_operand:QI 1 "" "") 14166 (match_operand:SI 2 "" ""))) 14167 (set (reg:SI SP_REG) 14168 (plus:SI (reg:SI SP_REG) 14169 (match_operand:SI 4 "" "")))])] 14170 "!TARGET_64BIT" 14171{ 14172 ix86_expand_call (operands[0], operands[1], operands[2], 14173 operands[3], operands[4], 0); 14174 DONE; 14175}) 14176 14177(define_expand "call_value" 14178 [(set (match_operand 0 "" "") 14179 (call (match_operand:QI 1 "" "") 14180 (match_operand:SI 2 "" ""))) 14181 (use (match_operand:SI 3 "" ""))] 14182 ;; Operand 2 not used on the i386. 14183 "" 14184{ 14185 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0); 14186 DONE; 14187}) 14188 14189(define_expand "sibcall_value" 14190 [(set (match_operand 0 "" "") 14191 (call (match_operand:QI 1 "" "") 14192 (match_operand:SI 2 "" ""))) 14193 (use (match_operand:SI 3 "" ""))] 14194 ;; Operand 2 not used on the i386. 14195 "" 14196{ 14197 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1); 14198 DONE; 14199}) 14200 14201;; Call subroutine returning any type. 14202 14203(define_expand "untyped_call" 14204 [(parallel [(call (match_operand 0 "" "") 14205 (const_int 0)) 14206 (match_operand 1 "" "") 14207 (match_operand 2 "" "")])] 14208 "" 14209{ 14210 int i; 14211 14212 /* In order to give reg-stack an easier job in validating two 14213 coprocessor registers as containing a possible return value, 14214 simply pretend the untyped call returns a complex long double 14215 value. */ 14216 14217 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387 14218 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL), 14219 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1), 14220 NULL, 0); 14221 14222 for (i = 0; i < XVECLEN (operands[2], 0); i++) 14223 { 14224 rtx set = XVECEXP (operands[2], 0, i); 14225 emit_move_insn (SET_DEST (set), SET_SRC (set)); 14226 } 14227 14228 /* The optimizer does not know that the call sets the function value 14229 registers we stored in the result block. We avoid problems by 14230 claiming that all hard registers are used and clobbered at this 14231 point. */ 14232 emit_insn (gen_blockage (const0_rtx)); 14233 14234 DONE; 14235}) 14236 14237;; Prologue and epilogue instructions 14238 14239;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 14240;; all of memory. This blocks insns from being moved across this point. 14241 14242(define_insn "blockage" 14243 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)] 14244 "" 14245 "" 14246 [(set_attr "length" "0")]) 14247 14248;; Insn emitted into the body of a function to return from a function. 14249;; This is only done if the function's epilogue is known to be simple. 14250;; See comments for ix86_can_use_return_insn_p in i386.c. 14251 14252(define_expand "return" 14253 [(return)] 14254 "ix86_can_use_return_insn_p ()" 14255{ 14256 if (current_function_pops_args) 14257 { 14258 rtx popc = GEN_INT (current_function_pops_args); 14259 emit_jump_insn (gen_return_pop_internal (popc)); 14260 DONE; 14261 } 14262}) 14263 14264(define_insn "return_internal" 14265 [(return)] 14266 "reload_completed" 14267 "ret" 14268 [(set_attr "length" "1") 14269 (set_attr "length_immediate" "0") 14270 (set_attr "modrm" "0")]) 14271 14272;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET 14273;; instruction Athlon and K8 have. 14274 14275(define_insn "return_internal_long" 14276 [(return) 14277 (unspec [(const_int 0)] UNSPEC_REP)] 14278 "reload_completed" 14279 "rep {;} ret" 14280 [(set_attr "length" "1") 14281 (set_attr "length_immediate" "0") 14282 (set_attr "prefix_rep" "1") 14283 (set_attr "modrm" "0")]) 14284 14285(define_insn "return_pop_internal" 14286 [(return) 14287 (use (match_operand:SI 0 "const_int_operand" ""))] 14288 "reload_completed" 14289 "ret\t%0" 14290 [(set_attr "length" "3") 14291 (set_attr "length_immediate" "2") 14292 (set_attr "modrm" "0")]) 14293 14294(define_insn "return_indirect_internal" 14295 [(return) 14296 (use (match_operand:SI 0 "register_operand" "r"))] 14297 "reload_completed" 14298 "jmp\t%A0" 14299 [(set_attr "type" "ibr") 14300 (set_attr "length_immediate" "0")]) 14301 14302(define_insn "nop" 14303 [(const_int 0)] 14304 "" 14305 "nop" 14306 [(set_attr "length" "1") 14307 (set_attr "length_immediate" "0") 14308 (set_attr "modrm" "0")]) 14309 14310;; Align to 16-byte boundary, max skip in op0. Used to avoid 14311;; branch prediction penalty for the third jump in a 16-byte 14312;; block on K8. 14313 14314(define_insn "align" 14315 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)] 14316 "" 14317{ 14318#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN 14319 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0])); 14320#else 14321 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that. 14322 The align insn is used to avoid 3 jump instructions in the row to improve 14323 branch prediction and the benefits hardly outweigh the cost of extra 8 14324 nops on the average inserted by full alignment pseudo operation. */ 14325#endif 14326 return ""; 14327} 14328 [(set_attr "length" "16")]) 14329 14330(define_expand "prologue" 14331 [(const_int 1)] 14332 "" 14333 "ix86_expand_prologue (); DONE;") 14334 14335(define_insn "set_got" 14336 [(set (match_operand:SI 0 "register_operand" "=r") 14337 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 14338 (clobber (reg:CC FLAGS_REG))] 14339 "!TARGET_64BIT" 14340 { return output_set_got (operands[0], NULL_RTX); } 14341 [(set_attr "type" "multi") 14342 (set_attr "length" "12")]) 14343 14344(define_insn "set_got_labelled" 14345 [(set (match_operand:SI 0 "register_operand" "=r") 14346 (unspec:SI [(label_ref (match_operand 1 "" ""))] 14347 UNSPEC_SET_GOT)) 14348 (clobber (reg:CC FLAGS_REG))] 14349 "!TARGET_64BIT" 14350 { return output_set_got (operands[0], operands[1]); } 14351 [(set_attr "type" "multi") 14352 (set_attr "length" "12")]) 14353 14354(define_insn "set_got_rex64" 14355 [(set (match_operand:DI 0 "register_operand" "=r") 14356 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))] 14357 "TARGET_64BIT" 14358 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0" 14359 [(set_attr "type" "lea") 14360 (set_attr "length" "6")]) 14361 14362(define_expand "epilogue" 14363 [(const_int 1)] 14364 "" 14365 "ix86_expand_epilogue (1); DONE;") 14366 14367(define_expand "sibcall_epilogue" 14368 [(const_int 1)] 14369 "" 14370 "ix86_expand_epilogue (0); DONE;") 14371 14372(define_expand "eh_return" 14373 [(use (match_operand 0 "register_operand" ""))] 14374 "" 14375{ 14376 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0]; 14377 14378 /* Tricky bit: we write the address of the handler to which we will 14379 be returning into someone else's stack frame, one word below the 14380 stack address we wish to restore. */ 14381 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa); 14382 tmp = plus_constant (tmp, -UNITS_PER_WORD); 14383 tmp = gen_rtx_MEM (Pmode, tmp); 14384 emit_move_insn (tmp, ra); 14385 14386 if (Pmode == SImode) 14387 emit_jump_insn (gen_eh_return_si (sa)); 14388 else 14389 emit_jump_insn (gen_eh_return_di (sa)); 14390 emit_barrier (); 14391 DONE; 14392}) 14393 14394(define_insn_and_split "eh_return_si" 14395 [(set (pc) 14396 (unspec [(match_operand:SI 0 "register_operand" "c")] 14397 UNSPEC_EH_RETURN))] 14398 "!TARGET_64BIT" 14399 "#" 14400 "reload_completed" 14401 [(const_int 1)] 14402 "ix86_expand_epilogue (2); DONE;") 14403 14404(define_insn_and_split "eh_return_di" 14405 [(set (pc) 14406 (unspec [(match_operand:DI 0 "register_operand" "c")] 14407 UNSPEC_EH_RETURN))] 14408 "TARGET_64BIT" 14409 "#" 14410 "reload_completed" 14411 [(const_int 1)] 14412 "ix86_expand_epilogue (2); DONE;") 14413 14414(define_insn "leave" 14415 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4))) 14416 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG))) 14417 (clobber (mem:BLK (scratch)))] 14418 "!TARGET_64BIT" 14419 "leave" 14420 [(set_attr "type" "leave")]) 14421 14422(define_insn "leave_rex64" 14423 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8))) 14424 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG))) 14425 (clobber (mem:BLK (scratch)))] 14426 "TARGET_64BIT" 14427 "leave" 14428 [(set_attr "type" "leave")]) 14429 14430(define_expand "ffssi2" 14431 [(parallel 14432 [(set (match_operand:SI 0 "register_operand" "") 14433 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" ""))) 14434 (clobber (match_scratch:SI 2 "")) 14435 (clobber (reg:CC FLAGS_REG))])] 14436 "" 14437 "") 14438 14439(define_insn_and_split "*ffs_cmove" 14440 [(set (match_operand:SI 0 "register_operand" "=r") 14441 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 14442 (clobber (match_scratch:SI 2 "=&r")) 14443 (clobber (reg:CC FLAGS_REG))] 14444 "TARGET_CMOVE" 14445 "#" 14446 "&& reload_completed" 14447 [(set (match_dup 2) (const_int -1)) 14448 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0))) 14449 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 14450 (set (match_dup 0) (if_then_else:SI 14451 (eq (reg:CCZ FLAGS_REG) (const_int 0)) 14452 (match_dup 2) 14453 (match_dup 0))) 14454 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 14455 (clobber (reg:CC FLAGS_REG))])] 14456 "") 14457 14458(define_insn_and_split "*ffs_no_cmove" 14459 [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 14460 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 14461 (clobber (match_scratch:SI 2 "=&q")) 14462 (clobber (reg:CC FLAGS_REG))] 14463 "" 14464 "#" 14465 "reload_completed" 14466 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0))) 14467 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 14468 (set (strict_low_part (match_dup 3)) 14469 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0))) 14470 (parallel [(set (match_dup 2) (neg:SI (match_dup 2))) 14471 (clobber (reg:CC FLAGS_REG))]) 14472 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2))) 14473 (clobber (reg:CC FLAGS_REG))]) 14474 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 14475 (clobber (reg:CC FLAGS_REG))])] 14476{ 14477 operands[3] = gen_lowpart (QImode, operands[2]); 14478 ix86_expand_clear (operands[2]); 14479}) 14480 14481(define_insn "*ffssi_1" 14482 [(set (reg:CCZ FLAGS_REG) 14483 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm") 14484 (const_int 0))) 14485 (set (match_operand:SI 0 "register_operand" "=r") 14486 (ctz:SI (match_dup 1)))] 14487 "" 14488 "bsf{l}\t{%1, %0|%0, %1}" 14489 [(set_attr "prefix_0f" "1")]) 14490 14491(define_expand "ffsdi2" 14492 [(parallel 14493 [(set (match_operand:DI 0 "register_operand" "") 14494 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" ""))) 14495 (clobber (match_scratch:DI 2 "")) 14496 (clobber (reg:CC FLAGS_REG))])] 14497 "TARGET_64BIT && TARGET_CMOVE" 14498 "") 14499 14500(define_insn_and_split "*ffs_rex64" 14501 [(set (match_operand:DI 0 "register_operand" "=r") 14502 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))) 14503 (clobber (match_scratch:DI 2 "=&r")) 14504 (clobber (reg:CC FLAGS_REG))] 14505 "TARGET_64BIT && TARGET_CMOVE" 14506 "#" 14507 "&& reload_completed" 14508 [(set (match_dup 2) (const_int -1)) 14509 (parallel [(set (reg:CCZ FLAGS_REG) 14510 (compare:CCZ (match_dup 1) (const_int 0))) 14511 (set (match_dup 0) (ctz:DI (match_dup 1)))]) 14512 (set (match_dup 0) (if_then_else:DI 14513 (eq (reg:CCZ FLAGS_REG) (const_int 0)) 14514 (match_dup 2) 14515 (match_dup 0))) 14516 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1))) 14517 (clobber (reg:CC FLAGS_REG))])] 14518 "") 14519 14520(define_insn "*ffsdi_1" 14521 [(set (reg:CCZ FLAGS_REG) 14522 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm") 14523 (const_int 0))) 14524 (set (match_operand:DI 0 "register_operand" "=r") 14525 (ctz:DI (match_dup 1)))] 14526 "TARGET_64BIT" 14527 "bsf{q}\t{%1, %0|%0, %1}" 14528 [(set_attr "prefix_0f" "1")]) 14529 14530(define_insn "ctzsi2" 14531 [(set (match_operand:SI 0 "register_operand" "=r") 14532 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 14533 (clobber (reg:CC FLAGS_REG))] 14534 "" 14535 "bsf{l}\t{%1, %0|%0, %1}" 14536 [(set_attr "prefix_0f" "1")]) 14537 14538(define_insn "ctzdi2" 14539 [(set (match_operand:DI 0 "register_operand" "=r") 14540 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))) 14541 (clobber (reg:CC FLAGS_REG))] 14542 "TARGET_64BIT" 14543 "bsf{q}\t{%1, %0|%0, %1}" 14544 [(set_attr "prefix_0f" "1")]) 14545 14546(define_expand "clzsi2" 14547 [(parallel 14548 [(set (match_operand:SI 0 "register_operand" "") 14549 (minus:SI (const_int 31) 14550 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))) 14551 (clobber (reg:CC FLAGS_REG))]) 14552 (parallel 14553 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31))) 14554 (clobber (reg:CC FLAGS_REG))])] 14555 "" 14556 "") 14557 14558(define_insn "*bsr" 14559 [(set (match_operand:SI 0 "register_operand" "=r") 14560 (minus:SI (const_int 31) 14561 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))) 14562 (clobber (reg:CC FLAGS_REG))] 14563 "" 14564 "bsr{l}\t{%1, %0|%0, %1}" 14565 [(set_attr "prefix_0f" "1")]) 14566 14567(define_expand "clzdi2" 14568 [(parallel 14569 [(set (match_operand:DI 0 "register_operand" "") 14570 (minus:DI (const_int 63) 14571 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))) 14572 (clobber (reg:CC FLAGS_REG))]) 14573 (parallel 14574 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63))) 14575 (clobber (reg:CC FLAGS_REG))])] 14576 "TARGET_64BIT" 14577 "") 14578 14579(define_insn "*bsr_rex64" 14580 [(set (match_operand:DI 0 "register_operand" "=r") 14581 (minus:DI (const_int 63) 14582 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) 14583 (clobber (reg:CC FLAGS_REG))] 14584 "TARGET_64BIT" 14585 "bsr{q}\t{%1, %0|%0, %1}" 14586 [(set_attr "prefix_0f" "1")]) 14587 14588;; Thread-local storage patterns for ELF. 14589;; 14590;; Note that these code sequences must appear exactly as shown 14591;; in order to allow linker relaxation. 14592 14593(define_insn "*tls_global_dynamic_32_gnu" 14594 [(set (match_operand:SI 0 "register_operand" "=a") 14595 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14596 (match_operand:SI 2 "tls_symbolic_operand" "") 14597 (match_operand:SI 3 "call_insn_operand" "")] 14598 UNSPEC_TLS_GD)) 14599 (clobber (match_scratch:SI 4 "=d")) 14600 (clobber (match_scratch:SI 5 "=c")) 14601 (clobber (reg:CC FLAGS_REG))] 14602 "!TARGET_64BIT && TARGET_GNU_TLS" 14603 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3" 14604 [(set_attr "type" "multi") 14605 (set_attr "length" "12")]) 14606 14607(define_insn "*tls_global_dynamic_32_sun" 14608 [(set (match_operand:SI 0 "register_operand" "=a") 14609 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14610 (match_operand:SI 2 "tls_symbolic_operand" "") 14611 (match_operand:SI 3 "call_insn_operand" "")] 14612 UNSPEC_TLS_GD)) 14613 (clobber (match_scratch:SI 4 "=d")) 14614 (clobber (match_scratch:SI 5 "=c")) 14615 (clobber (reg:CC FLAGS_REG))] 14616 "!TARGET_64BIT && TARGET_SUN_TLS" 14617 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]} 14618 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop" 14619 [(set_attr "type" "multi") 14620 (set_attr "length" "14")]) 14621 14622(define_expand "tls_global_dynamic_32" 14623 [(parallel [(set (match_operand:SI 0 "register_operand" "") 14624 (unspec:SI 14625 [(match_dup 2) 14626 (match_operand:SI 1 "tls_symbolic_operand" "") 14627 (match_dup 3)] 14628 UNSPEC_TLS_GD)) 14629 (clobber (match_scratch:SI 4 "")) 14630 (clobber (match_scratch:SI 5 "")) 14631 (clobber (reg:CC FLAGS_REG))])] 14632 "" 14633{ 14634 if (flag_pic) 14635 operands[2] = pic_offset_table_rtx; 14636 else 14637 { 14638 operands[2] = gen_reg_rtx (Pmode); 14639 emit_insn (gen_set_got (operands[2])); 14640 } 14641 if (TARGET_GNU2_TLS) 14642 { 14643 emit_insn (gen_tls_dynamic_gnu2_32 14644 (operands[0], operands[1], operands[2])); 14645 DONE; 14646 } 14647 operands[3] = ix86_tls_get_addr (); 14648}) 14649 14650(define_insn "*tls_global_dynamic_64" 14651 [(set (match_operand:DI 0 "register_operand" "=a") 14652 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" "")) 14653 (match_operand:DI 3 "" ""))) 14654 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 14655 UNSPEC_TLS_GD)] 14656 "TARGET_64BIT" 14657 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2" 14658 [(set_attr "type" "multi") 14659 (set_attr "length" "16")]) 14660 14661(define_expand "tls_global_dynamic_64" 14662 [(parallel [(set (match_operand:DI 0 "register_operand" "") 14663 (call:DI (mem:QI (match_dup 2)) (const_int 0))) 14664 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 14665 UNSPEC_TLS_GD)])] 14666 "" 14667{ 14668 if (TARGET_GNU2_TLS) 14669 { 14670 emit_insn (gen_tls_dynamic_gnu2_64 14671 (operands[0], operands[1])); 14672 DONE; 14673 } 14674 operands[2] = ix86_tls_get_addr (); 14675}) 14676 14677(define_insn "*tls_local_dynamic_base_32_gnu" 14678 [(set (match_operand:SI 0 "register_operand" "=a") 14679 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14680 (match_operand:SI 2 "call_insn_operand" "")] 14681 UNSPEC_TLS_LD_BASE)) 14682 (clobber (match_scratch:SI 3 "=d")) 14683 (clobber (match_scratch:SI 4 "=c")) 14684 (clobber (reg:CC FLAGS_REG))] 14685 "!TARGET_64BIT && TARGET_GNU_TLS" 14686 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2" 14687 [(set_attr "type" "multi") 14688 (set_attr "length" "11")]) 14689 14690(define_insn "*tls_local_dynamic_base_32_sun" 14691 [(set (match_operand:SI 0 "register_operand" "=a") 14692 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14693 (match_operand:SI 2 "call_insn_operand" "")] 14694 UNSPEC_TLS_LD_BASE)) 14695 (clobber (match_scratch:SI 3 "=d")) 14696 (clobber (match_scratch:SI 4 "=c")) 14697 (clobber (reg:CC FLAGS_REG))] 14698 "!TARGET_64BIT && TARGET_SUN_TLS" 14699 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]} 14700 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3" 14701 [(set_attr "type" "multi") 14702 (set_attr "length" "13")]) 14703 14704(define_expand "tls_local_dynamic_base_32" 14705 [(parallel [(set (match_operand:SI 0 "register_operand" "") 14706 (unspec:SI [(match_dup 1) (match_dup 2)] 14707 UNSPEC_TLS_LD_BASE)) 14708 (clobber (match_scratch:SI 3 "")) 14709 (clobber (match_scratch:SI 4 "")) 14710 (clobber (reg:CC FLAGS_REG))])] 14711 "" 14712{ 14713 if (flag_pic) 14714 operands[1] = pic_offset_table_rtx; 14715 else 14716 { 14717 operands[1] = gen_reg_rtx (Pmode); 14718 emit_insn (gen_set_got (operands[1])); 14719 } 14720 if (TARGET_GNU2_TLS) 14721 { 14722 emit_insn (gen_tls_dynamic_gnu2_32 14723 (operands[0], ix86_tls_module_base (), operands[1])); 14724 DONE; 14725 } 14726 operands[2] = ix86_tls_get_addr (); 14727}) 14728 14729(define_insn "*tls_local_dynamic_base_64" 14730 [(set (match_operand:DI 0 "register_operand" "=a") 14731 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" "")) 14732 (match_operand:DI 2 "" ""))) 14733 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)] 14734 "TARGET_64BIT" 14735 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1" 14736 [(set_attr "type" "multi") 14737 (set_attr "length" "12")]) 14738 14739(define_expand "tls_local_dynamic_base_64" 14740 [(parallel [(set (match_operand:DI 0 "register_operand" "") 14741 (call:DI (mem:QI (match_dup 1)) (const_int 0))) 14742 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])] 14743 "" 14744{ 14745 if (TARGET_GNU2_TLS) 14746 { 14747 emit_insn (gen_tls_dynamic_gnu2_64 14748 (operands[0], ix86_tls_module_base ())); 14749 DONE; 14750 } 14751 operands[1] = ix86_tls_get_addr (); 14752}) 14753 14754;; Local dynamic of a single variable is a lose. Show combine how 14755;; to convert that back to global dynamic. 14756 14757(define_insn_and_split "*tls_local_dynamic_32_once" 14758 [(set (match_operand:SI 0 "register_operand" "=a") 14759 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14760 (match_operand:SI 2 "call_insn_operand" "")] 14761 UNSPEC_TLS_LD_BASE) 14762 (const:SI (unspec:SI 14763 [(match_operand:SI 3 "tls_symbolic_operand" "")] 14764 UNSPEC_DTPOFF)))) 14765 (clobber (match_scratch:SI 4 "=d")) 14766 (clobber (match_scratch:SI 5 "=c")) 14767 (clobber (reg:CC FLAGS_REG))] 14768 "" 14769 "#" 14770 "" 14771 [(parallel [(set (match_dup 0) 14772 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)] 14773 UNSPEC_TLS_GD)) 14774 (clobber (match_dup 4)) 14775 (clobber (match_dup 5)) 14776 (clobber (reg:CC FLAGS_REG))])] 14777 "") 14778 14779;; Load and add the thread base pointer from %gs:0. 14780 14781(define_insn "*load_tp_si" 14782 [(set (match_operand:SI 0 "register_operand" "=r") 14783 (unspec:SI [(const_int 0)] UNSPEC_TP))] 14784 "!TARGET_64BIT" 14785 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}" 14786 [(set_attr "type" "imov") 14787 (set_attr "modrm" "0") 14788 (set_attr "length" "7") 14789 (set_attr "memory" "load") 14790 (set_attr "imm_disp" "false")]) 14791 14792(define_insn "*add_tp_si" 14793 [(set (match_operand:SI 0 "register_operand" "=r") 14794 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) 14795 (match_operand:SI 1 "register_operand" "0"))) 14796 (clobber (reg:CC FLAGS_REG))] 14797 "!TARGET_64BIT" 14798 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}" 14799 [(set_attr "type" "alu") 14800 (set_attr "modrm" "0") 14801 (set_attr "length" "7") 14802 (set_attr "memory" "load") 14803 (set_attr "imm_disp" "false")]) 14804 14805(define_insn "*load_tp_di" 14806 [(set (match_operand:DI 0 "register_operand" "=r") 14807 (unspec:DI [(const_int 0)] UNSPEC_TP))] 14808 "TARGET_64BIT" 14809 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}" 14810 [(set_attr "type" "imov") 14811 (set_attr "modrm" "0") 14812 (set_attr "length" "7") 14813 (set_attr "memory" "load") 14814 (set_attr "imm_disp" "false")]) 14815 14816(define_insn "*add_tp_di" 14817 [(set (match_operand:DI 0 "register_operand" "=r") 14818 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP) 14819 (match_operand:DI 1 "register_operand" "0"))) 14820 (clobber (reg:CC FLAGS_REG))] 14821 "TARGET_64BIT" 14822 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}" 14823 [(set_attr "type" "alu") 14824 (set_attr "modrm" "0") 14825 (set_attr "length" "7") 14826 (set_attr "memory" "load") 14827 (set_attr "imm_disp" "false")]) 14828 14829;; GNU2 TLS patterns can be split. 14830 14831(define_expand "tls_dynamic_gnu2_32" 14832 [(set (match_dup 3) 14833 (plus:SI (match_operand:SI 2 "register_operand" "") 14834 (const:SI 14835 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")] 14836 UNSPEC_TLSDESC)))) 14837 (parallel 14838 [(set (match_operand:SI 0 "register_operand" "") 14839 (unspec:SI [(match_dup 1) (match_dup 3) 14840 (match_dup 2) (reg:SI SP_REG)] 14841 UNSPEC_TLSDESC)) 14842 (clobber (reg:CC FLAGS_REG))])] 14843 "!TARGET_64BIT && TARGET_GNU2_TLS" 14844{ 14845 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); 14846 ix86_tls_descriptor_calls_expanded_in_cfun = true; 14847}) 14848 14849(define_insn "*tls_dynamic_lea_32" 14850 [(set (match_operand:SI 0 "register_operand" "=r") 14851 (plus:SI (match_operand:SI 1 "register_operand" "b") 14852 (const:SI 14853 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")] 14854 UNSPEC_TLSDESC))))] 14855 "!TARGET_64BIT && TARGET_GNU2_TLS" 14856 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}" 14857 [(set_attr "type" "lea") 14858 (set_attr "mode" "SI") 14859 (set_attr "length" "6") 14860 (set_attr "length_address" "4")]) 14861 14862(define_insn "*tls_dynamic_call_32" 14863 [(set (match_operand:SI 0 "register_operand" "=a") 14864 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "") 14865 (match_operand:SI 2 "register_operand" "0") 14866 ;; we have to make sure %ebx still points to the GOT 14867 (match_operand:SI 3 "register_operand" "b") 14868 (reg:SI SP_REG)] 14869 UNSPEC_TLSDESC)) 14870 (clobber (reg:CC FLAGS_REG))] 14871 "!TARGET_64BIT && TARGET_GNU2_TLS" 14872 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}" 14873 [(set_attr "type" "call") 14874 (set_attr "length" "2") 14875 (set_attr "length_address" "0")]) 14876 14877(define_insn_and_split "*tls_dynamic_gnu2_combine_32" 14878 [(set (match_operand:SI 0 "register_operand" "=&a") 14879 (plus:SI 14880 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "") 14881 (match_operand:SI 4 "" "") 14882 (match_operand:SI 2 "register_operand" "b") 14883 (reg:SI SP_REG)] 14884 UNSPEC_TLSDESC) 14885 (const:SI (unspec:SI 14886 [(match_operand:SI 1 "tls_symbolic_operand" "")] 14887 UNSPEC_DTPOFF)))) 14888 (clobber (reg:CC FLAGS_REG))] 14889 "!TARGET_64BIT && TARGET_GNU2_TLS" 14890 "#" 14891 "" 14892 [(set (match_dup 0) (match_dup 5))] 14893{ 14894 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); 14895 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2])); 14896}) 14897 14898(define_expand "tls_dynamic_gnu2_64" 14899 [(set (match_dup 2) 14900 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 14901 UNSPEC_TLSDESC)) 14902 (parallel 14903 [(set (match_operand:DI 0 "register_operand" "") 14904 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)] 14905 UNSPEC_TLSDESC)) 14906 (clobber (reg:CC FLAGS_REG))])] 14907 "TARGET_64BIT && TARGET_GNU2_TLS" 14908{ 14909 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); 14910 ix86_tls_descriptor_calls_expanded_in_cfun = true; 14911}) 14912 14913(define_insn "*tls_dynamic_lea_64" 14914 [(set (match_operand:DI 0 "register_operand" "=r") 14915 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 14916 UNSPEC_TLSDESC))] 14917 "TARGET_64BIT && TARGET_GNU2_TLS" 14918 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}" 14919 [(set_attr "type" "lea") 14920 (set_attr "mode" "DI") 14921 (set_attr "length" "7") 14922 (set_attr "length_address" "4")]) 14923 14924(define_insn "*tls_dynamic_call_64" 14925 [(set (match_operand:DI 0 "register_operand" "=a") 14926 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "") 14927 (match_operand:DI 2 "register_operand" "0") 14928 (reg:DI SP_REG)] 14929 UNSPEC_TLSDESC)) 14930 (clobber (reg:CC FLAGS_REG))] 14931 "TARGET_64BIT && TARGET_GNU2_TLS" 14932 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}" 14933 [(set_attr "type" "call") 14934 (set_attr "length" "2") 14935 (set_attr "length_address" "0")]) 14936 14937(define_insn_and_split "*tls_dynamic_gnu2_combine_64" 14938 [(set (match_operand:DI 0 "register_operand" "=&a") 14939 (plus:DI 14940 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "") 14941 (match_operand:DI 3 "" "") 14942 (reg:DI SP_REG)] 14943 UNSPEC_TLSDESC) 14944 (const:DI (unspec:DI 14945 [(match_operand:DI 1 "tls_symbolic_operand" "")] 14946 UNSPEC_DTPOFF)))) 14947 (clobber (reg:CC FLAGS_REG))] 14948 "TARGET_64BIT && TARGET_GNU2_TLS" 14949 "#" 14950 "" 14951 [(set (match_dup 0) (match_dup 4))] 14952{ 14953 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); 14954 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1])); 14955}) 14956 14957;; 14958 14959;; These patterns match the binary 387 instructions for addM3, subM3, 14960;; mulM3 and divM3. There are three patterns for each of DFmode and 14961;; SFmode. The first is the normal insn, the second the same insn but 14962;; with one operand a conversion, and the third the same insn but with 14963;; the other operand a conversion. The conversion may be SFmode or 14964;; SImode if the target mode DFmode, but only SImode if the target mode 14965;; is SFmode. 14966 14967;; Gcc is slightly more smart about handling normal two address instructions 14968;; so use special patterns for add and mull. 14969 14970(define_insn "*fop_sf_comm_mixed" 14971 [(set (match_operand:SF 0 "register_operand" "=f,x") 14972 (match_operator:SF 3 "binary_fp_operator" 14973 [(match_operand:SF 1 "nonimmediate_operand" "%0,0") 14974 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))] 14975 "TARGET_MIX_SSE_I387 14976 && COMMUTATIVE_ARITH_P (operands[3]) 14977 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 14978 "* return output_387_binary_op (insn, operands);" 14979 [(set (attr "type") 14980 (if_then_else (eq_attr "alternative" "1") 14981 (if_then_else (match_operand:SF 3 "mult_operator" "") 14982 (const_string "ssemul") 14983 (const_string "sseadd")) 14984 (if_then_else (match_operand:SF 3 "mult_operator" "") 14985 (const_string "fmul") 14986 (const_string "fop")))) 14987 (set_attr "mode" "SF")]) 14988 14989(define_insn "*fop_sf_comm_sse" 14990 [(set (match_operand:SF 0 "register_operand" "=x") 14991 (match_operator:SF 3 "binary_fp_operator" 14992 [(match_operand:SF 1 "nonimmediate_operand" "%0") 14993 (match_operand:SF 2 "nonimmediate_operand" "xm")]))] 14994 "TARGET_SSE_MATH 14995 && COMMUTATIVE_ARITH_P (operands[3]) 14996 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 14997 "* return output_387_binary_op (insn, operands);" 14998 [(set (attr "type") 14999 (if_then_else (match_operand:SF 3 "mult_operator" "") 15000 (const_string "ssemul") 15001 (const_string "sseadd"))) 15002 (set_attr "mode" "SF")]) 15003 15004(define_insn "*fop_sf_comm_i387" 15005 [(set (match_operand:SF 0 "register_operand" "=f") 15006 (match_operator:SF 3 "binary_fp_operator" 15007 [(match_operand:SF 1 "nonimmediate_operand" "%0") 15008 (match_operand:SF 2 "nonimmediate_operand" "fm")]))] 15009 "TARGET_80387 15010 && COMMUTATIVE_ARITH_P (operands[3]) 15011 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15012 "* return output_387_binary_op (insn, operands);" 15013 [(set (attr "type") 15014 (if_then_else (match_operand:SF 3 "mult_operator" "") 15015 (const_string "fmul") 15016 (const_string "fop"))) 15017 (set_attr "mode" "SF")]) 15018 15019(define_insn "*fop_sf_1_mixed" 15020 [(set (match_operand:SF 0 "register_operand" "=f,f,x") 15021 (match_operator:SF 3 "binary_fp_operator" 15022 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0") 15023 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))] 15024 "TARGET_MIX_SSE_I387 15025 && !COMMUTATIVE_ARITH_P (operands[3]) 15026 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15027 "* return output_387_binary_op (insn, operands);" 15028 [(set (attr "type") 15029 (cond [(and (eq_attr "alternative" "2") 15030 (match_operand:SF 3 "mult_operator" "")) 15031 (const_string "ssemul") 15032 (and (eq_attr "alternative" "2") 15033 (match_operand:SF 3 "div_operator" "")) 15034 (const_string "ssediv") 15035 (eq_attr "alternative" "2") 15036 (const_string "sseadd") 15037 (match_operand:SF 3 "mult_operator" "") 15038 (const_string "fmul") 15039 (match_operand:SF 3 "div_operator" "") 15040 (const_string "fdiv") 15041 ] 15042 (const_string "fop"))) 15043 (set_attr "mode" "SF")]) 15044 15045(define_insn "*fop_sf_1_sse" 15046 [(set (match_operand:SF 0 "register_operand" "=x") 15047 (match_operator:SF 3 "binary_fp_operator" 15048 [(match_operand:SF 1 "register_operand" "0") 15049 (match_operand:SF 2 "nonimmediate_operand" "xm")]))] 15050 "TARGET_SSE_MATH 15051 && !COMMUTATIVE_ARITH_P (operands[3])" 15052 "* return output_387_binary_op (insn, operands);" 15053 [(set (attr "type") 15054 (cond [(match_operand:SF 3 "mult_operator" "") 15055 (const_string "ssemul") 15056 (match_operand:SF 3 "div_operator" "") 15057 (const_string "ssediv") 15058 ] 15059 (const_string "sseadd"))) 15060 (set_attr "mode" "SF")]) 15061 15062;; This pattern is not fully shadowed by the pattern above. 15063(define_insn "*fop_sf_1_i387" 15064 [(set (match_operand:SF 0 "register_operand" "=f,f") 15065 (match_operator:SF 3 "binary_fp_operator" 15066 [(match_operand:SF 1 "nonimmediate_operand" "0,fm") 15067 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))] 15068 "TARGET_80387 && !TARGET_SSE_MATH 15069 && !COMMUTATIVE_ARITH_P (operands[3]) 15070 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15071 "* return output_387_binary_op (insn, operands);" 15072 [(set (attr "type") 15073 (cond [(match_operand:SF 3 "mult_operator" "") 15074 (const_string "fmul") 15075 (match_operand:SF 3 "div_operator" "") 15076 (const_string "fdiv") 15077 ] 15078 (const_string "fop"))) 15079 (set_attr "mode" "SF")]) 15080 15081;; ??? Add SSE splitters for these! 15082(define_insn "*fop_sf_2<mode>_i387" 15083 [(set (match_operand:SF 0 "register_operand" "=f,f") 15084 (match_operator:SF 3 "binary_fp_operator" 15085 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r")) 15086 (match_operand:SF 2 "register_operand" "0,0")]))] 15087 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH" 15088 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15089 [(set (attr "type") 15090 (cond [(match_operand:SF 3 "mult_operator" "") 15091 (const_string "fmul") 15092 (match_operand:SF 3 "div_operator" "") 15093 (const_string "fdiv") 15094 ] 15095 (const_string "fop"))) 15096 (set_attr "fp_int_src" "true") 15097 (set_attr "mode" "<MODE>")]) 15098 15099(define_insn "*fop_sf_3<mode>_i387" 15100 [(set (match_operand:SF 0 "register_operand" "=f,f") 15101 (match_operator:SF 3 "binary_fp_operator" 15102 [(match_operand:SF 1 "register_operand" "0,0") 15103 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))] 15104 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH" 15105 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15106 [(set (attr "type") 15107 (cond [(match_operand:SF 3 "mult_operator" "") 15108 (const_string "fmul") 15109 (match_operand:SF 3 "div_operator" "") 15110 (const_string "fdiv") 15111 ] 15112 (const_string "fop"))) 15113 (set_attr "fp_int_src" "true") 15114 (set_attr "mode" "<MODE>")]) 15115 15116(define_insn "*fop_df_comm_mixed" 15117 [(set (match_operand:DF 0 "register_operand" "=f,Y") 15118 (match_operator:DF 3 "binary_fp_operator" 15119 [(match_operand:DF 1 "nonimmediate_operand" "%0,0") 15120 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))] 15121 "TARGET_SSE2 && TARGET_MIX_SSE_I387 15122 && COMMUTATIVE_ARITH_P (operands[3]) 15123 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15124 "* return output_387_binary_op (insn, operands);" 15125 [(set (attr "type") 15126 (if_then_else (eq_attr "alternative" "1") 15127 (if_then_else (match_operand:DF 3 "mult_operator" "") 15128 (const_string "ssemul") 15129 (const_string "sseadd")) 15130 (if_then_else (match_operand:DF 3 "mult_operator" "") 15131 (const_string "fmul") 15132 (const_string "fop")))) 15133 (set_attr "mode" "DF")]) 15134 15135(define_insn "*fop_df_comm_sse" 15136 [(set (match_operand:DF 0 "register_operand" "=Y") 15137 (match_operator:DF 3 "binary_fp_operator" 15138 [(match_operand:DF 1 "nonimmediate_operand" "%0") 15139 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))] 15140 "TARGET_SSE2 && TARGET_SSE_MATH 15141 && COMMUTATIVE_ARITH_P (operands[3]) 15142 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15143 "* return output_387_binary_op (insn, operands);" 15144 [(set (attr "type") 15145 (if_then_else (match_operand:DF 3 "mult_operator" "") 15146 (const_string "ssemul") 15147 (const_string "sseadd"))) 15148 (set_attr "mode" "DF")]) 15149 15150(define_insn "*fop_df_comm_i387" 15151 [(set (match_operand:DF 0 "register_operand" "=f") 15152 (match_operator:DF 3 "binary_fp_operator" 15153 [(match_operand:DF 1 "nonimmediate_operand" "%0") 15154 (match_operand:DF 2 "nonimmediate_operand" "fm")]))] 15155 "TARGET_80387 15156 && COMMUTATIVE_ARITH_P (operands[3]) 15157 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15158 "* return output_387_binary_op (insn, operands);" 15159 [(set (attr "type") 15160 (if_then_else (match_operand:DF 3 "mult_operator" "") 15161 (const_string "fmul") 15162 (const_string "fop"))) 15163 (set_attr "mode" "DF")]) 15164 15165(define_insn "*fop_df_1_mixed" 15166 [(set (match_operand:DF 0 "register_operand" "=f,f,Y") 15167 (match_operator:DF 3 "binary_fp_operator" 15168 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0") 15169 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))] 15170 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387 15171 && !COMMUTATIVE_ARITH_P (operands[3]) 15172 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15173 "* return output_387_binary_op (insn, operands);" 15174 [(set (attr "type") 15175 (cond [(and (eq_attr "alternative" "2") 15176 (match_operand:DF 3 "mult_operator" "")) 15177 (const_string "ssemul") 15178 (and (eq_attr "alternative" "2") 15179 (match_operand:DF 3 "div_operator" "")) 15180 (const_string "ssediv") 15181 (eq_attr "alternative" "2") 15182 (const_string "sseadd") 15183 (match_operand:DF 3 "mult_operator" "") 15184 (const_string "fmul") 15185 (match_operand:DF 3 "div_operator" "") 15186 (const_string "fdiv") 15187 ] 15188 (const_string "fop"))) 15189 (set_attr "mode" "DF")]) 15190 15191(define_insn "*fop_df_1_sse" 15192 [(set (match_operand:DF 0 "register_operand" "=Y") 15193 (match_operator:DF 3 "binary_fp_operator" 15194 [(match_operand:DF 1 "register_operand" "0") 15195 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))] 15196 "TARGET_SSE2 && TARGET_SSE_MATH 15197 && !COMMUTATIVE_ARITH_P (operands[3])" 15198 "* return output_387_binary_op (insn, operands);" 15199 [(set_attr "mode" "DF") 15200 (set (attr "type") 15201 (cond [(match_operand:DF 3 "mult_operator" "") 15202 (const_string "ssemul") 15203 (match_operand:DF 3 "div_operator" "") 15204 (const_string "ssediv") 15205 ] 15206 (const_string "sseadd")))]) 15207 15208;; This pattern is not fully shadowed by the pattern above. 15209(define_insn "*fop_df_1_i387" 15210 [(set (match_operand:DF 0 "register_operand" "=f,f") 15211 (match_operator:DF 3 "binary_fp_operator" 15212 [(match_operand:DF 1 "nonimmediate_operand" "0,fm") 15213 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))] 15214 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH) 15215 && !COMMUTATIVE_ARITH_P (operands[3]) 15216 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15217 "* return output_387_binary_op (insn, operands);" 15218 [(set (attr "type") 15219 (cond [(match_operand:DF 3 "mult_operator" "") 15220 (const_string "fmul") 15221 (match_operand:DF 3 "div_operator" "") 15222 (const_string "fdiv") 15223 ] 15224 (const_string "fop"))) 15225 (set_attr "mode" "DF")]) 15226 15227;; ??? Add SSE splitters for these! 15228(define_insn "*fop_df_2<mode>_i387" 15229 [(set (match_operand:DF 0 "register_operand" "=f,f") 15230 (match_operator:DF 3 "binary_fp_operator" 15231 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r")) 15232 (match_operand:DF 2 "register_operand" "0,0")]))] 15233 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 15234 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15235 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15236 [(set (attr "type") 15237 (cond [(match_operand:DF 3 "mult_operator" "") 15238 (const_string "fmul") 15239 (match_operand:DF 3 "div_operator" "") 15240 (const_string "fdiv") 15241 ] 15242 (const_string "fop"))) 15243 (set_attr "fp_int_src" "true") 15244 (set_attr "mode" "<MODE>")]) 15245 15246(define_insn "*fop_df_3<mode>_i387" 15247 [(set (match_operand:DF 0 "register_operand" "=f,f") 15248 (match_operator:DF 3 "binary_fp_operator" 15249 [(match_operand:DF 1 "register_operand" "0,0") 15250 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))] 15251 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 15252 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15253 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15254 [(set (attr "type") 15255 (cond [(match_operand:DF 3 "mult_operator" "") 15256 (const_string "fmul") 15257 (match_operand:DF 3 "div_operator" "") 15258 (const_string "fdiv") 15259 ] 15260 (const_string "fop"))) 15261 (set_attr "fp_int_src" "true") 15262 (set_attr "mode" "<MODE>")]) 15263 15264(define_insn "*fop_df_4_i387" 15265 [(set (match_operand:DF 0 "register_operand" "=f,f") 15266 (match_operator:DF 3 "binary_fp_operator" 15267 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0")) 15268 (match_operand:DF 2 "register_operand" "0,f")]))] 15269 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH) 15270 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15271 "* return output_387_binary_op (insn, operands);" 15272 [(set (attr "type") 15273 (cond [(match_operand:DF 3 "mult_operator" "") 15274 (const_string "fmul") 15275 (match_operand:DF 3 "div_operator" "") 15276 (const_string "fdiv") 15277 ] 15278 (const_string "fop"))) 15279 (set_attr "mode" "SF")]) 15280 15281(define_insn "*fop_df_5_i387" 15282 [(set (match_operand:DF 0 "register_operand" "=f,f") 15283 (match_operator:DF 3 "binary_fp_operator" 15284 [(match_operand:DF 1 "register_operand" "0,f") 15285 (float_extend:DF 15286 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15287 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15288 "* return output_387_binary_op (insn, operands);" 15289 [(set (attr "type") 15290 (cond [(match_operand:DF 3 "mult_operator" "") 15291 (const_string "fmul") 15292 (match_operand:DF 3 "div_operator" "") 15293 (const_string "fdiv") 15294 ] 15295 (const_string "fop"))) 15296 (set_attr "mode" "SF")]) 15297 15298(define_insn "*fop_df_6_i387" 15299 [(set (match_operand:DF 0 "register_operand" "=f,f") 15300 (match_operator:DF 3 "binary_fp_operator" 15301 [(float_extend:DF 15302 (match_operand:SF 1 "register_operand" "0,f")) 15303 (float_extend:DF 15304 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15305 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15306 "* return output_387_binary_op (insn, operands);" 15307 [(set (attr "type") 15308 (cond [(match_operand:DF 3 "mult_operator" "") 15309 (const_string "fmul") 15310 (match_operand:DF 3 "div_operator" "") 15311 (const_string "fdiv") 15312 ] 15313 (const_string "fop"))) 15314 (set_attr "mode" "SF")]) 15315 15316(define_insn "*fop_xf_comm_i387" 15317 [(set (match_operand:XF 0 "register_operand" "=f") 15318 (match_operator:XF 3 "binary_fp_operator" 15319 [(match_operand:XF 1 "register_operand" "%0") 15320 (match_operand:XF 2 "register_operand" "f")]))] 15321 "TARGET_80387 15322 && COMMUTATIVE_ARITH_P (operands[3])" 15323 "* return output_387_binary_op (insn, operands);" 15324 [(set (attr "type") 15325 (if_then_else (match_operand:XF 3 "mult_operator" "") 15326 (const_string "fmul") 15327 (const_string "fop"))) 15328 (set_attr "mode" "XF")]) 15329 15330(define_insn "*fop_xf_1_i387" 15331 [(set (match_operand:XF 0 "register_operand" "=f,f") 15332 (match_operator:XF 3 "binary_fp_operator" 15333 [(match_operand:XF 1 "register_operand" "0,f") 15334 (match_operand:XF 2 "register_operand" "f,0")]))] 15335 "TARGET_80387 15336 && !COMMUTATIVE_ARITH_P (operands[3])" 15337 "* return output_387_binary_op (insn, operands);" 15338 [(set (attr "type") 15339 (cond [(match_operand:XF 3 "mult_operator" "") 15340 (const_string "fmul") 15341 (match_operand:XF 3 "div_operator" "") 15342 (const_string "fdiv") 15343 ] 15344 (const_string "fop"))) 15345 (set_attr "mode" "XF")]) 15346 15347(define_insn "*fop_xf_2<mode>_i387" 15348 [(set (match_operand:XF 0 "register_operand" "=f,f") 15349 (match_operator:XF 3 "binary_fp_operator" 15350 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r")) 15351 (match_operand:XF 2 "register_operand" "0,0")]))] 15352 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP" 15353 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15354 [(set (attr "type") 15355 (cond [(match_operand:XF 3 "mult_operator" "") 15356 (const_string "fmul") 15357 (match_operand:XF 3 "div_operator" "") 15358 (const_string "fdiv") 15359 ] 15360 (const_string "fop"))) 15361 (set_attr "fp_int_src" "true") 15362 (set_attr "mode" "<MODE>")]) 15363 15364(define_insn "*fop_xf_3<mode>_i387" 15365 [(set (match_operand:XF 0 "register_operand" "=f,f") 15366 (match_operator:XF 3 "binary_fp_operator" 15367 [(match_operand:XF 1 "register_operand" "0,0") 15368 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))] 15369 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP" 15370 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15371 [(set (attr "type") 15372 (cond [(match_operand:XF 3 "mult_operator" "") 15373 (const_string "fmul") 15374 (match_operand:XF 3 "div_operator" "") 15375 (const_string "fdiv") 15376 ] 15377 (const_string "fop"))) 15378 (set_attr "fp_int_src" "true") 15379 (set_attr "mode" "<MODE>")]) 15380 15381(define_insn "*fop_xf_4_i387" 15382 [(set (match_operand:XF 0 "register_operand" "=f,f") 15383 (match_operator:XF 3 "binary_fp_operator" 15384 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0")) 15385 (match_operand:XF 2 "register_operand" "0,f")]))] 15386 "TARGET_80387" 15387 "* return output_387_binary_op (insn, operands);" 15388 [(set (attr "type") 15389 (cond [(match_operand:XF 3 "mult_operator" "") 15390 (const_string "fmul") 15391 (match_operand:XF 3 "div_operator" "") 15392 (const_string "fdiv") 15393 ] 15394 (const_string "fop"))) 15395 (set_attr "mode" "SF")]) 15396 15397(define_insn "*fop_xf_5_i387" 15398 [(set (match_operand:XF 0 "register_operand" "=f,f") 15399 (match_operator:XF 3 "binary_fp_operator" 15400 [(match_operand:XF 1 "register_operand" "0,f") 15401 (float_extend:XF 15402 (match_operand 2 "nonimmediate_operand" "fm,0"))]))] 15403 "TARGET_80387" 15404 "* return output_387_binary_op (insn, operands);" 15405 [(set (attr "type") 15406 (cond [(match_operand:XF 3 "mult_operator" "") 15407 (const_string "fmul") 15408 (match_operand:XF 3 "div_operator" "") 15409 (const_string "fdiv") 15410 ] 15411 (const_string "fop"))) 15412 (set_attr "mode" "SF")]) 15413 15414(define_insn "*fop_xf_6_i387" 15415 [(set (match_operand:XF 0 "register_operand" "=f,f") 15416 (match_operator:XF 3 "binary_fp_operator" 15417 [(float_extend:XF 15418 (match_operand 1 "register_operand" "0,f")) 15419 (float_extend:XF 15420 (match_operand 2 "nonimmediate_operand" "fm,0"))]))] 15421 "TARGET_80387" 15422 "* return output_387_binary_op (insn, operands);" 15423 [(set (attr "type") 15424 (cond [(match_operand:XF 3 "mult_operator" "") 15425 (const_string "fmul") 15426 (match_operand:XF 3 "div_operator" "") 15427 (const_string "fdiv") 15428 ] 15429 (const_string "fop"))) 15430 (set_attr "mode" "SF")]) 15431 15432(define_split 15433 [(set (match_operand 0 "register_operand" "") 15434 (match_operator 3 "binary_fp_operator" 15435 [(float (match_operand:X87MODEI12 1 "register_operand" "")) 15436 (match_operand 2 "register_operand" "")]))] 15437 "TARGET_80387 && reload_completed 15438 && FLOAT_MODE_P (GET_MODE (operands[0]))" 15439 [(const_int 0)] 15440{ 15441 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]); 15442 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); 15443 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 15444 gen_rtx_fmt_ee (GET_CODE (operands[3]), 15445 GET_MODE (operands[3]), 15446 operands[4], 15447 operands[2]))); 15448 ix86_free_from_memory (GET_MODE (operands[1])); 15449 DONE; 15450}) 15451 15452(define_split 15453 [(set (match_operand 0 "register_operand" "") 15454 (match_operator 3 "binary_fp_operator" 15455 [(match_operand 1 "register_operand" "") 15456 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))] 15457 "TARGET_80387 && reload_completed 15458 && FLOAT_MODE_P (GET_MODE (operands[0]))" 15459 [(const_int 0)] 15460{ 15461 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); 15462 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); 15463 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 15464 gen_rtx_fmt_ee (GET_CODE (operands[3]), 15465 GET_MODE (operands[3]), 15466 operands[1], 15467 operands[4]))); 15468 ix86_free_from_memory (GET_MODE (operands[2])); 15469 DONE; 15470}) 15471 15472;; FPU special functions. 15473 15474(define_expand "sqrtsf2" 15475 [(set (match_operand:SF 0 "register_operand" "") 15476 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))] 15477 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH" 15478{ 15479 if (!TARGET_SSE_MATH) 15480 operands[1] = force_reg (SFmode, operands[1]); 15481}) 15482 15483(define_insn "*sqrtsf2_mixed" 15484 [(set (match_operand:SF 0 "register_operand" "=f,x") 15485 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))] 15486 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387" 15487 "@ 15488 fsqrt 15489 sqrtss\t{%1, %0|%0, %1}" 15490 [(set_attr "type" "fpspc,sse") 15491 (set_attr "mode" "SF,SF") 15492 (set_attr "athlon_decode" "direct,*")]) 15493 15494(define_insn "*sqrtsf2_sse" 15495 [(set (match_operand:SF 0 "register_operand" "=x") 15496 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))] 15497 "TARGET_SSE_MATH" 15498 "sqrtss\t{%1, %0|%0, %1}" 15499 [(set_attr "type" "sse") 15500 (set_attr "mode" "SF") 15501 (set_attr "athlon_decode" "*")]) 15502 15503(define_insn "*sqrtsf2_i387" 15504 [(set (match_operand:SF 0 "register_operand" "=f") 15505 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))] 15506 "TARGET_USE_FANCY_MATH_387" 15507 "fsqrt" 15508 [(set_attr "type" "fpspc") 15509 (set_attr "mode" "SF") 15510 (set_attr "athlon_decode" "direct")]) 15511 15512(define_expand "sqrtdf2" 15513 [(set (match_operand:DF 0 "register_operand" "") 15514 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))] 15515 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 15516{ 15517 if (!(TARGET_SSE2 && TARGET_SSE_MATH)) 15518 operands[1] = force_reg (DFmode, operands[1]); 15519}) 15520 15521(define_insn "*sqrtdf2_mixed" 15522 [(set (match_operand:DF 0 "register_operand" "=f,Y") 15523 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))] 15524 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387" 15525 "@ 15526 fsqrt 15527 sqrtsd\t{%1, %0|%0, %1}" 15528 [(set_attr "type" "fpspc,sse") 15529 (set_attr "mode" "DF,DF") 15530 (set_attr "athlon_decode" "direct,*")]) 15531 15532(define_insn "*sqrtdf2_sse" 15533 [(set (match_operand:DF 0 "register_operand" "=Y") 15534 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))] 15535 "TARGET_SSE2 && TARGET_SSE_MATH" 15536 "sqrtsd\t{%1, %0|%0, %1}" 15537 [(set_attr "type" "sse") 15538 (set_attr "mode" "DF") 15539 (set_attr "athlon_decode" "*")]) 15540 15541(define_insn "*sqrtdf2_i387" 15542 [(set (match_operand:DF 0 "register_operand" "=f") 15543 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))] 15544 "TARGET_USE_FANCY_MATH_387" 15545 "fsqrt" 15546 [(set_attr "type" "fpspc") 15547 (set_attr "mode" "DF") 15548 (set_attr "athlon_decode" "direct")]) 15549 15550(define_insn "*sqrtextendsfdf2_i387" 15551 [(set (match_operand:DF 0 "register_operand" "=f") 15552 (sqrt:DF (float_extend:DF 15553 (match_operand:SF 1 "register_operand" "0"))))] 15554 "TARGET_USE_FANCY_MATH_387 15555 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)" 15556 "fsqrt" 15557 [(set_attr "type" "fpspc") 15558 (set_attr "mode" "DF") 15559 (set_attr "athlon_decode" "direct")]) 15560 15561(define_insn "sqrtxf2" 15562 [(set (match_operand:XF 0 "register_operand" "=f") 15563 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] 15564 "TARGET_USE_FANCY_MATH_387" 15565 "fsqrt" 15566 [(set_attr "type" "fpspc") 15567 (set_attr "mode" "XF") 15568 (set_attr "athlon_decode" "direct")]) 15569 15570(define_insn "*sqrtextendsfxf2_i387" 15571 [(set (match_operand:XF 0 "register_operand" "=f") 15572 (sqrt:XF (float_extend:XF 15573 (match_operand:SF 1 "register_operand" "0"))))] 15574 "TARGET_USE_FANCY_MATH_387" 15575 "fsqrt" 15576 [(set_attr "type" "fpspc") 15577 (set_attr "mode" "XF") 15578 (set_attr "athlon_decode" "direct")]) 15579 15580(define_insn "*sqrtextenddfxf2_i387" 15581 [(set (match_operand:XF 0 "register_operand" "=f") 15582 (sqrt:XF (float_extend:XF 15583 (match_operand:DF 1 "register_operand" "0"))))] 15584 "TARGET_USE_FANCY_MATH_387" 15585 "fsqrt" 15586 [(set_attr "type" "fpspc") 15587 (set_attr "mode" "XF") 15588 (set_attr "athlon_decode" "direct")]) 15589 15590(define_insn "fpremxf4" 15591 [(set (match_operand:XF 0 "register_operand" "=f") 15592 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15593 (match_operand:XF 3 "register_operand" "1")] 15594 UNSPEC_FPREM_F)) 15595 (set (match_operand:XF 1 "register_operand" "=u") 15596 (unspec:XF [(match_dup 2) (match_dup 3)] 15597 UNSPEC_FPREM_U)) 15598 (set (reg:CCFP FPSR_REG) 15599 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))] 15600 "TARGET_USE_FANCY_MATH_387 15601 && flag_unsafe_math_optimizations" 15602 "fprem" 15603 [(set_attr "type" "fpspc") 15604 (set_attr "mode" "XF")]) 15605 15606(define_expand "fmodsf3" 15607 [(use (match_operand:SF 0 "register_operand" "")) 15608 (use (match_operand:SF 1 "register_operand" "")) 15609 (use (match_operand:SF 2 "register_operand" ""))] 15610 "TARGET_USE_FANCY_MATH_387 15611 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15612 && flag_unsafe_math_optimizations" 15613{ 15614 rtx label = gen_label_rtx (); 15615 15616 rtx op1 = gen_reg_rtx (XFmode); 15617 rtx op2 = gen_reg_rtx (XFmode); 15618 15619 emit_insn(gen_extendsfxf2 (op1, operands[1])); 15620 emit_insn(gen_extendsfxf2 (op2, operands[2])); 15621 15622 emit_label (label); 15623 15624 emit_insn (gen_fpremxf4 (op1, op2, op1, op2)); 15625 ix86_emit_fp_unordered_jump (label); 15626 15627 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1)); 15628 DONE; 15629}) 15630 15631(define_expand "fmoddf3" 15632 [(use (match_operand:DF 0 "register_operand" "")) 15633 (use (match_operand:DF 1 "register_operand" "")) 15634 (use (match_operand:DF 2 "register_operand" ""))] 15635 "TARGET_USE_FANCY_MATH_387 15636 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15637 && flag_unsafe_math_optimizations" 15638{ 15639 rtx label = gen_label_rtx (); 15640 15641 rtx op1 = gen_reg_rtx (XFmode); 15642 rtx op2 = gen_reg_rtx (XFmode); 15643 15644 emit_insn (gen_extenddfxf2 (op1, operands[1])); 15645 emit_insn (gen_extenddfxf2 (op2, operands[2])); 15646 15647 emit_label (label); 15648 15649 emit_insn (gen_fpremxf4 (op1, op2, op1, op2)); 15650 ix86_emit_fp_unordered_jump (label); 15651 15652 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1)); 15653 DONE; 15654}) 15655 15656(define_expand "fmodxf3" 15657 [(use (match_operand:XF 0 "register_operand" "")) 15658 (use (match_operand:XF 1 "register_operand" "")) 15659 (use (match_operand:XF 2 "register_operand" ""))] 15660 "TARGET_USE_FANCY_MATH_387 15661 && flag_unsafe_math_optimizations" 15662{ 15663 rtx label = gen_label_rtx (); 15664 15665 emit_label (label); 15666 15667 emit_insn (gen_fpremxf4 (operands[1], operands[2], 15668 operands[1], operands[2])); 15669 ix86_emit_fp_unordered_jump (label); 15670 15671 emit_move_insn (operands[0], operands[1]); 15672 DONE; 15673}) 15674 15675(define_insn "fprem1xf4" 15676 [(set (match_operand:XF 0 "register_operand" "=f") 15677 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15678 (match_operand:XF 3 "register_operand" "1")] 15679 UNSPEC_FPREM1_F)) 15680 (set (match_operand:XF 1 "register_operand" "=u") 15681 (unspec:XF [(match_dup 2) (match_dup 3)] 15682 UNSPEC_FPREM1_U)) 15683 (set (reg:CCFP FPSR_REG) 15684 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))] 15685 "TARGET_USE_FANCY_MATH_387 15686 && flag_unsafe_math_optimizations" 15687 "fprem1" 15688 [(set_attr "type" "fpspc") 15689 (set_attr "mode" "XF")]) 15690 15691(define_expand "dremsf3" 15692 [(use (match_operand:SF 0 "register_operand" "")) 15693 (use (match_operand:SF 1 "register_operand" "")) 15694 (use (match_operand:SF 2 "register_operand" ""))] 15695 "TARGET_USE_FANCY_MATH_387 15696 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15697 && flag_unsafe_math_optimizations" 15698{ 15699 rtx label = gen_label_rtx (); 15700 15701 rtx op1 = gen_reg_rtx (XFmode); 15702 rtx op2 = gen_reg_rtx (XFmode); 15703 15704 emit_insn(gen_extendsfxf2 (op1, operands[1])); 15705 emit_insn(gen_extendsfxf2 (op2, operands[2])); 15706 15707 emit_label (label); 15708 15709 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2)); 15710 ix86_emit_fp_unordered_jump (label); 15711 15712 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1)); 15713 DONE; 15714}) 15715 15716(define_expand "dremdf3" 15717 [(use (match_operand:DF 0 "register_operand" "")) 15718 (use (match_operand:DF 1 "register_operand" "")) 15719 (use (match_operand:DF 2 "register_operand" ""))] 15720 "TARGET_USE_FANCY_MATH_387 15721 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15722 && flag_unsafe_math_optimizations" 15723{ 15724 rtx label = gen_label_rtx (); 15725 15726 rtx op1 = gen_reg_rtx (XFmode); 15727 rtx op2 = gen_reg_rtx (XFmode); 15728 15729 emit_insn (gen_extenddfxf2 (op1, operands[1])); 15730 emit_insn (gen_extenddfxf2 (op2, operands[2])); 15731 15732 emit_label (label); 15733 15734 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2)); 15735 ix86_emit_fp_unordered_jump (label); 15736 15737 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1)); 15738 DONE; 15739}) 15740 15741(define_expand "dremxf3" 15742 [(use (match_operand:XF 0 "register_operand" "")) 15743 (use (match_operand:XF 1 "register_operand" "")) 15744 (use (match_operand:XF 2 "register_operand" ""))] 15745 "TARGET_USE_FANCY_MATH_387 15746 && flag_unsafe_math_optimizations" 15747{ 15748 rtx label = gen_label_rtx (); 15749 15750 emit_label (label); 15751 15752 emit_insn (gen_fprem1xf4 (operands[1], operands[2], 15753 operands[1], operands[2])); 15754 ix86_emit_fp_unordered_jump (label); 15755 15756 emit_move_insn (operands[0], operands[1]); 15757 DONE; 15758}) 15759 15760(define_insn "*sindf2" 15761 [(set (match_operand:DF 0 "register_operand" "=f") 15762 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))] 15763 "TARGET_USE_FANCY_MATH_387 15764 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15765 && flag_unsafe_math_optimizations" 15766 "fsin" 15767 [(set_attr "type" "fpspc") 15768 (set_attr "mode" "DF")]) 15769 15770(define_insn "*sinsf2" 15771 [(set (match_operand:SF 0 "register_operand" "=f") 15772 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))] 15773 "TARGET_USE_FANCY_MATH_387 15774 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15775 && flag_unsafe_math_optimizations" 15776 "fsin" 15777 [(set_attr "type" "fpspc") 15778 (set_attr "mode" "SF")]) 15779 15780(define_insn "*sinextendsfdf2" 15781 [(set (match_operand:DF 0 "register_operand" "=f") 15782 (unspec:DF [(float_extend:DF 15783 (match_operand:SF 1 "register_operand" "0"))] 15784 UNSPEC_SIN))] 15785 "TARGET_USE_FANCY_MATH_387 15786 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15787 && flag_unsafe_math_optimizations" 15788 "fsin" 15789 [(set_attr "type" "fpspc") 15790 (set_attr "mode" "DF")]) 15791 15792(define_insn "*sinxf2" 15793 [(set (match_operand:XF 0 "register_operand" "=f") 15794 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))] 15795 "TARGET_USE_FANCY_MATH_387 15796 && flag_unsafe_math_optimizations" 15797 "fsin" 15798 [(set_attr "type" "fpspc") 15799 (set_attr "mode" "XF")]) 15800 15801(define_insn "*cosdf2" 15802 [(set (match_operand:DF 0 "register_operand" "=f") 15803 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))] 15804 "TARGET_USE_FANCY_MATH_387 15805 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15806 && flag_unsafe_math_optimizations" 15807 "fcos" 15808 [(set_attr "type" "fpspc") 15809 (set_attr "mode" "DF")]) 15810 15811(define_insn "*cossf2" 15812 [(set (match_operand:SF 0 "register_operand" "=f") 15813 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))] 15814 "TARGET_USE_FANCY_MATH_387 15815 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15816 && flag_unsafe_math_optimizations" 15817 "fcos" 15818 [(set_attr "type" "fpspc") 15819 (set_attr "mode" "SF")]) 15820 15821(define_insn "*cosextendsfdf2" 15822 [(set (match_operand:DF 0 "register_operand" "=f") 15823 (unspec:DF [(float_extend:DF 15824 (match_operand:SF 1 "register_operand" "0"))] 15825 UNSPEC_COS))] 15826 "TARGET_USE_FANCY_MATH_387 15827 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15828 && flag_unsafe_math_optimizations" 15829 "fcos" 15830 [(set_attr "type" "fpspc") 15831 (set_attr "mode" "DF")]) 15832 15833(define_insn "*cosxf2" 15834 [(set (match_operand:XF 0 "register_operand" "=f") 15835 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))] 15836 "TARGET_USE_FANCY_MATH_387 15837 && flag_unsafe_math_optimizations" 15838 "fcos" 15839 [(set_attr "type" "fpspc") 15840 (set_attr "mode" "XF")]) 15841 15842;; With sincos pattern defined, sin and cos builtin function will be 15843;; expanded to sincos pattern with one of its outputs left unused. 15844;; Cse pass will detected, if two sincos patterns can be combined, 15845;; otherwise sincos pattern will be split back to sin or cos pattern, 15846;; depending on the unused output. 15847 15848(define_insn "sincosdf3" 15849 [(set (match_operand:DF 0 "register_operand" "=f") 15850 (unspec:DF [(match_operand:DF 2 "register_operand" "0")] 15851 UNSPEC_SINCOS_COS)) 15852 (set (match_operand:DF 1 "register_operand" "=u") 15853 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15854 "TARGET_USE_FANCY_MATH_387 15855 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15856 && flag_unsafe_math_optimizations" 15857 "fsincos" 15858 [(set_attr "type" "fpspc") 15859 (set_attr "mode" "DF")]) 15860 15861(define_split 15862 [(set (match_operand:DF 0 "register_operand" "") 15863 (unspec:DF [(match_operand:DF 2 "register_operand" "")] 15864 UNSPEC_SINCOS_COS)) 15865 (set (match_operand:DF 1 "register_operand" "") 15866 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15867 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15868 && !reload_completed && !reload_in_progress" 15869 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))] 15870 "") 15871 15872(define_split 15873 [(set (match_operand:DF 0 "register_operand" "") 15874 (unspec:DF [(match_operand:DF 2 "register_operand" "")] 15875 UNSPEC_SINCOS_COS)) 15876 (set (match_operand:DF 1 "register_operand" "") 15877 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15878 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15879 && !reload_completed && !reload_in_progress" 15880 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))] 15881 "") 15882 15883(define_insn "sincossf3" 15884 [(set (match_operand:SF 0 "register_operand" "=f") 15885 (unspec:SF [(match_operand:SF 2 "register_operand" "0")] 15886 UNSPEC_SINCOS_COS)) 15887 (set (match_operand:SF 1 "register_operand" "=u") 15888 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15889 "TARGET_USE_FANCY_MATH_387 15890 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15891 && flag_unsafe_math_optimizations" 15892 "fsincos" 15893 [(set_attr "type" "fpspc") 15894 (set_attr "mode" "SF")]) 15895 15896(define_split 15897 [(set (match_operand:SF 0 "register_operand" "") 15898 (unspec:SF [(match_operand:SF 2 "register_operand" "")] 15899 UNSPEC_SINCOS_COS)) 15900 (set (match_operand:SF 1 "register_operand" "") 15901 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15902 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15903 && !reload_completed && !reload_in_progress" 15904 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))] 15905 "") 15906 15907(define_split 15908 [(set (match_operand:SF 0 "register_operand" "") 15909 (unspec:SF [(match_operand:SF 2 "register_operand" "")] 15910 UNSPEC_SINCOS_COS)) 15911 (set (match_operand:SF 1 "register_operand" "") 15912 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15913 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15914 && !reload_completed && !reload_in_progress" 15915 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))] 15916 "") 15917 15918(define_insn "*sincosextendsfdf3" 15919 [(set (match_operand:DF 0 "register_operand" "=f") 15920 (unspec:DF [(float_extend:DF 15921 (match_operand:SF 2 "register_operand" "0"))] 15922 UNSPEC_SINCOS_COS)) 15923 (set (match_operand:DF 1 "register_operand" "=u") 15924 (unspec:DF [(float_extend:DF 15925 (match_dup 2))] UNSPEC_SINCOS_SIN))] 15926 "TARGET_USE_FANCY_MATH_387 15927 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15928 && flag_unsafe_math_optimizations" 15929 "fsincos" 15930 [(set_attr "type" "fpspc") 15931 (set_attr "mode" "DF")]) 15932 15933(define_split 15934 [(set (match_operand:DF 0 "register_operand" "") 15935 (unspec:DF [(float_extend:DF 15936 (match_operand:SF 2 "register_operand" ""))] 15937 UNSPEC_SINCOS_COS)) 15938 (set (match_operand:DF 1 "register_operand" "") 15939 (unspec:DF [(float_extend:DF 15940 (match_dup 2))] UNSPEC_SINCOS_SIN))] 15941 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15942 && !reload_completed && !reload_in_progress" 15943 [(set (match_dup 1) (unspec:DF [(float_extend:DF 15944 (match_dup 2))] UNSPEC_SIN))] 15945 "") 15946 15947(define_split 15948 [(set (match_operand:DF 0 "register_operand" "") 15949 (unspec:DF [(float_extend:DF 15950 (match_operand:SF 2 "register_operand" ""))] 15951 UNSPEC_SINCOS_COS)) 15952 (set (match_operand:DF 1 "register_operand" "") 15953 (unspec:DF [(float_extend:DF 15954 (match_dup 2))] UNSPEC_SINCOS_SIN))] 15955 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15956 && !reload_completed && !reload_in_progress" 15957 [(set (match_dup 0) (unspec:DF [(float_extend:DF 15958 (match_dup 2))] UNSPEC_COS))] 15959 "") 15960 15961(define_insn "sincosxf3" 15962 [(set (match_operand:XF 0 "register_operand" "=f") 15963 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 15964 UNSPEC_SINCOS_COS)) 15965 (set (match_operand:XF 1 "register_operand" "=u") 15966 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15967 "TARGET_USE_FANCY_MATH_387 15968 && flag_unsafe_math_optimizations" 15969 "fsincos" 15970 [(set_attr "type" "fpspc") 15971 (set_attr "mode" "XF")]) 15972 15973(define_split 15974 [(set (match_operand:XF 0 "register_operand" "") 15975 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 15976 UNSPEC_SINCOS_COS)) 15977 (set (match_operand:XF 1 "register_operand" "") 15978 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15979 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15980 && !reload_completed && !reload_in_progress" 15981 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))] 15982 "") 15983 15984(define_split 15985 [(set (match_operand:XF 0 "register_operand" "") 15986 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 15987 UNSPEC_SINCOS_COS)) 15988 (set (match_operand:XF 1 "register_operand" "") 15989 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15990 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15991 && !reload_completed && !reload_in_progress" 15992 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))] 15993 "") 15994 15995(define_insn "*tandf3_1" 15996 [(set (match_operand:DF 0 "register_operand" "=f") 15997 (unspec:DF [(match_operand:DF 2 "register_operand" "0")] 15998 UNSPEC_TAN_ONE)) 15999 (set (match_operand:DF 1 "register_operand" "=u") 16000 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))] 16001 "TARGET_USE_FANCY_MATH_387 16002 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16003 && flag_unsafe_math_optimizations" 16004 "fptan" 16005 [(set_attr "type" "fpspc") 16006 (set_attr "mode" "DF")]) 16007 16008;; optimize sequence: fptan 16009;; fstp %st(0) 16010;; fld1 16011;; into fptan insn. 16012 16013(define_peephole2 16014 [(parallel[(set (match_operand:DF 0 "register_operand" "") 16015 (unspec:DF [(match_operand:DF 2 "register_operand" "")] 16016 UNSPEC_TAN_ONE)) 16017 (set (match_operand:DF 1 "register_operand" "") 16018 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]) 16019 (set (match_dup 0) 16020 (match_operand:DF 3 "immediate_operand" ""))] 16021 "standard_80387_constant_p (operands[3]) == 2" 16022 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE)) 16023 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])] 16024 "") 16025 16026(define_expand "tandf2" 16027 [(parallel [(set (match_dup 2) 16028 (unspec:DF [(match_operand:DF 1 "register_operand" "")] 16029 UNSPEC_TAN_ONE)) 16030 (set (match_operand:DF 0 "register_operand" "") 16031 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])] 16032 "TARGET_USE_FANCY_MATH_387 16033 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16034 && flag_unsafe_math_optimizations" 16035{ 16036 operands[2] = gen_reg_rtx (DFmode); 16037}) 16038 16039(define_insn "*tansf3_1" 16040 [(set (match_operand:SF 0 "register_operand" "=f") 16041 (unspec:SF [(match_operand:SF 2 "register_operand" "0")] 16042 UNSPEC_TAN_ONE)) 16043 (set (match_operand:SF 1 "register_operand" "=u") 16044 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))] 16045 "TARGET_USE_FANCY_MATH_387 16046 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16047 && flag_unsafe_math_optimizations" 16048 "fptan" 16049 [(set_attr "type" "fpspc") 16050 (set_attr "mode" "SF")]) 16051 16052;; optimize sequence: fptan 16053;; fstp %st(0) 16054;; fld1 16055;; into fptan insn. 16056 16057(define_peephole2 16058 [(parallel[(set (match_operand:SF 0 "register_operand" "") 16059 (unspec:SF [(match_operand:SF 2 "register_operand" "")] 16060 UNSPEC_TAN_ONE)) 16061 (set (match_operand:SF 1 "register_operand" "") 16062 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]) 16063 (set (match_dup 0) 16064 (match_operand:SF 3 "immediate_operand" ""))] 16065 "standard_80387_constant_p (operands[3]) == 2" 16066 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE)) 16067 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])] 16068 "") 16069 16070(define_expand "tansf2" 16071 [(parallel [(set (match_dup 2) 16072 (unspec:SF [(match_operand:SF 1 "register_operand" "")] 16073 UNSPEC_TAN_ONE)) 16074 (set (match_operand:SF 0 "register_operand" "") 16075 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])] 16076 "TARGET_USE_FANCY_MATH_387 16077 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16078 && flag_unsafe_math_optimizations" 16079{ 16080 operands[2] = gen_reg_rtx (SFmode); 16081}) 16082 16083(define_insn "*tanxf3_1" 16084 [(set (match_operand:XF 0 "register_operand" "=f") 16085 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 16086 UNSPEC_TAN_ONE)) 16087 (set (match_operand:XF 1 "register_operand" "=u") 16088 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))] 16089 "TARGET_USE_FANCY_MATH_387 16090 && flag_unsafe_math_optimizations" 16091 "fptan" 16092 [(set_attr "type" "fpspc") 16093 (set_attr "mode" "XF")]) 16094 16095;; optimize sequence: fptan 16096;; fstp %st(0) 16097;; fld1 16098;; into fptan insn. 16099 16100(define_peephole2 16101 [(parallel[(set (match_operand:XF 0 "register_operand" "") 16102 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 16103 UNSPEC_TAN_ONE)) 16104 (set (match_operand:XF 1 "register_operand" "") 16105 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]) 16106 (set (match_dup 0) 16107 (match_operand:XF 3 "immediate_operand" ""))] 16108 "standard_80387_constant_p (operands[3]) == 2" 16109 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE)) 16110 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])] 16111 "") 16112 16113(define_expand "tanxf2" 16114 [(parallel [(set (match_dup 2) 16115 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 16116 UNSPEC_TAN_ONE)) 16117 (set (match_operand:XF 0 "register_operand" "") 16118 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])] 16119 "TARGET_USE_FANCY_MATH_387 16120 && flag_unsafe_math_optimizations" 16121{ 16122 operands[2] = gen_reg_rtx (XFmode); 16123}) 16124 16125(define_insn "atan2df3_1" 16126 [(set (match_operand:DF 0 "register_operand" "=f") 16127 (unspec:DF [(match_operand:DF 2 "register_operand" "0") 16128 (match_operand:DF 1 "register_operand" "u")] 16129 UNSPEC_FPATAN)) 16130 (clobber (match_scratch:DF 3 "=1"))] 16131 "TARGET_USE_FANCY_MATH_387 16132 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16133 && flag_unsafe_math_optimizations" 16134 "fpatan" 16135 [(set_attr "type" "fpspc") 16136 (set_attr "mode" "DF")]) 16137 16138(define_expand "atan2df3" 16139 [(use (match_operand:DF 0 "register_operand" "")) 16140 (use (match_operand:DF 2 "register_operand" "")) 16141 (use (match_operand:DF 1 "register_operand" ""))] 16142 "TARGET_USE_FANCY_MATH_387 16143 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16144 && flag_unsafe_math_optimizations" 16145{ 16146 rtx copy = gen_reg_rtx (DFmode); 16147 emit_move_insn (copy, operands[1]); 16148 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2])); 16149 DONE; 16150}) 16151 16152(define_expand "atandf2" 16153 [(parallel [(set (match_operand:DF 0 "register_operand" "") 16154 (unspec:DF [(match_dup 2) 16155 (match_operand:DF 1 "register_operand" "")] 16156 UNSPEC_FPATAN)) 16157 (clobber (match_scratch:DF 3 ""))])] 16158 "TARGET_USE_FANCY_MATH_387 16159 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16160 && flag_unsafe_math_optimizations" 16161{ 16162 operands[2] = gen_reg_rtx (DFmode); 16163 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */ 16164}) 16165 16166(define_insn "atan2sf3_1" 16167 [(set (match_operand:SF 0 "register_operand" "=f") 16168 (unspec:SF [(match_operand:SF 2 "register_operand" "0") 16169 (match_operand:SF 1 "register_operand" "u")] 16170 UNSPEC_FPATAN)) 16171 (clobber (match_scratch:SF 3 "=1"))] 16172 "TARGET_USE_FANCY_MATH_387 16173 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16174 && flag_unsafe_math_optimizations" 16175 "fpatan" 16176 [(set_attr "type" "fpspc") 16177 (set_attr "mode" "SF")]) 16178 16179(define_expand "atan2sf3" 16180 [(use (match_operand:SF 0 "register_operand" "")) 16181 (use (match_operand:SF 2 "register_operand" "")) 16182 (use (match_operand:SF 1 "register_operand" ""))] 16183 "TARGET_USE_FANCY_MATH_387 16184 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16185 && flag_unsafe_math_optimizations" 16186{ 16187 rtx copy = gen_reg_rtx (SFmode); 16188 emit_move_insn (copy, operands[1]); 16189 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2])); 16190 DONE; 16191}) 16192 16193(define_expand "atansf2" 16194 [(parallel [(set (match_operand:SF 0 "register_operand" "") 16195 (unspec:SF [(match_dup 2) 16196 (match_operand:SF 1 "register_operand" "")] 16197 UNSPEC_FPATAN)) 16198 (clobber (match_scratch:SF 3 ""))])] 16199 "TARGET_USE_FANCY_MATH_387 16200 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16201 && flag_unsafe_math_optimizations" 16202{ 16203 operands[2] = gen_reg_rtx (SFmode); 16204 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */ 16205}) 16206 16207(define_insn "atan2xf3_1" 16208 [(set (match_operand:XF 0 "register_operand" "=f") 16209 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16210 (match_operand:XF 1 "register_operand" "u")] 16211 UNSPEC_FPATAN)) 16212 (clobber (match_scratch:XF 3 "=1"))] 16213 "TARGET_USE_FANCY_MATH_387 16214 && flag_unsafe_math_optimizations" 16215 "fpatan" 16216 [(set_attr "type" "fpspc") 16217 (set_attr "mode" "XF")]) 16218 16219(define_expand "atan2xf3" 16220 [(use (match_operand:XF 0 "register_operand" "")) 16221 (use (match_operand:XF 2 "register_operand" "")) 16222 (use (match_operand:XF 1 "register_operand" ""))] 16223 "TARGET_USE_FANCY_MATH_387 16224 && flag_unsafe_math_optimizations" 16225{ 16226 rtx copy = gen_reg_rtx (XFmode); 16227 emit_move_insn (copy, operands[1]); 16228 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2])); 16229 DONE; 16230}) 16231 16232(define_expand "atanxf2" 16233 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16234 (unspec:XF [(match_dup 2) 16235 (match_operand:XF 1 "register_operand" "")] 16236 UNSPEC_FPATAN)) 16237 (clobber (match_scratch:XF 3 ""))])] 16238 "TARGET_USE_FANCY_MATH_387 16239 && flag_unsafe_math_optimizations" 16240{ 16241 operands[2] = gen_reg_rtx (XFmode); 16242 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 16243}) 16244 16245(define_expand "asindf2" 16246 [(set (match_dup 2) 16247 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16248 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16249 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16250 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16251 (parallel [(set (match_dup 7) 16252 (unspec:XF [(match_dup 6) (match_dup 2)] 16253 UNSPEC_FPATAN)) 16254 (clobber (match_scratch:XF 8 ""))]) 16255 (set (match_operand:DF 0 "register_operand" "") 16256 (float_truncate:DF (match_dup 7)))] 16257 "TARGET_USE_FANCY_MATH_387 16258 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16259 && flag_unsafe_math_optimizations" 16260{ 16261 int i; 16262 16263 for (i=2; i<8; i++) 16264 operands[i] = gen_reg_rtx (XFmode); 16265 16266 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16267}) 16268 16269(define_expand "asinsf2" 16270 [(set (match_dup 2) 16271 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16272 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16273 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16274 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16275 (parallel [(set (match_dup 7) 16276 (unspec:XF [(match_dup 6) (match_dup 2)] 16277 UNSPEC_FPATAN)) 16278 (clobber (match_scratch:XF 8 ""))]) 16279 (set (match_operand:SF 0 "register_operand" "") 16280 (float_truncate:SF (match_dup 7)))] 16281 "TARGET_USE_FANCY_MATH_387 16282 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16283 && flag_unsafe_math_optimizations" 16284{ 16285 int i; 16286 16287 for (i=2; i<8; i++) 16288 operands[i] = gen_reg_rtx (XFmode); 16289 16290 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16291}) 16292 16293(define_expand "asinxf2" 16294 [(set (match_dup 2) 16295 (mult:XF (match_operand:XF 1 "register_operand" "") 16296 (match_dup 1))) 16297 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 16298 (set (match_dup 5) (sqrt:XF (match_dup 4))) 16299 (parallel [(set (match_operand:XF 0 "register_operand" "") 16300 (unspec:XF [(match_dup 5) (match_dup 1)] 16301 UNSPEC_FPATAN)) 16302 (clobber (match_scratch:XF 6 ""))])] 16303 "TARGET_USE_FANCY_MATH_387 16304 && flag_unsafe_math_optimizations" 16305{ 16306 int i; 16307 16308 for (i=2; i<6; i++) 16309 operands[i] = gen_reg_rtx (XFmode); 16310 16311 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16312}) 16313 16314(define_expand "acosdf2" 16315 [(set (match_dup 2) 16316 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16317 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16318 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16319 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16320 (parallel [(set (match_dup 7) 16321 (unspec:XF [(match_dup 2) (match_dup 6)] 16322 UNSPEC_FPATAN)) 16323 (clobber (match_scratch:XF 8 ""))]) 16324 (set (match_operand:DF 0 "register_operand" "") 16325 (float_truncate:DF (match_dup 7)))] 16326 "TARGET_USE_FANCY_MATH_387 16327 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16328 && flag_unsafe_math_optimizations" 16329{ 16330 int i; 16331 16332 for (i=2; i<8; i++) 16333 operands[i] = gen_reg_rtx (XFmode); 16334 16335 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16336}) 16337 16338(define_expand "acossf2" 16339 [(set (match_dup 2) 16340 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16341 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16342 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16343 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16344 (parallel [(set (match_dup 7) 16345 (unspec:XF [(match_dup 2) (match_dup 6)] 16346 UNSPEC_FPATAN)) 16347 (clobber (match_scratch:XF 8 ""))]) 16348 (set (match_operand:SF 0 "register_operand" "") 16349 (float_truncate:SF (match_dup 7)))] 16350 "TARGET_USE_FANCY_MATH_387 16351 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16352 && flag_unsafe_math_optimizations" 16353{ 16354 int i; 16355 16356 for (i=2; i<8; i++) 16357 operands[i] = gen_reg_rtx (XFmode); 16358 16359 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16360}) 16361 16362(define_expand "acosxf2" 16363 [(set (match_dup 2) 16364 (mult:XF (match_operand:XF 1 "register_operand" "") 16365 (match_dup 1))) 16366 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 16367 (set (match_dup 5) (sqrt:XF (match_dup 4))) 16368 (parallel [(set (match_operand:XF 0 "register_operand" "") 16369 (unspec:XF [(match_dup 1) (match_dup 5)] 16370 UNSPEC_FPATAN)) 16371 (clobber (match_scratch:XF 6 ""))])] 16372 "TARGET_USE_FANCY_MATH_387 16373 && flag_unsafe_math_optimizations" 16374{ 16375 int i; 16376 16377 for (i=2; i<6; i++) 16378 operands[i] = gen_reg_rtx (XFmode); 16379 16380 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16381}) 16382 16383(define_insn "fyl2x_xf3" 16384 [(set (match_operand:XF 0 "register_operand" "=f") 16385 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16386 (match_operand:XF 1 "register_operand" "u")] 16387 UNSPEC_FYL2X)) 16388 (clobber (match_scratch:XF 3 "=1"))] 16389 "TARGET_USE_FANCY_MATH_387 16390 && flag_unsafe_math_optimizations" 16391 "fyl2x" 16392 [(set_attr "type" "fpspc") 16393 (set_attr "mode" "XF")]) 16394 16395(define_expand "logsf2" 16396 [(set (match_dup 2) 16397 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16398 (parallel [(set (match_dup 4) 16399 (unspec:XF [(match_dup 2) 16400 (match_dup 3)] UNSPEC_FYL2X)) 16401 (clobber (match_scratch:XF 5 ""))]) 16402 (set (match_operand:SF 0 "register_operand" "") 16403 (float_truncate:SF (match_dup 4)))] 16404 "TARGET_USE_FANCY_MATH_387 16405 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16406 && flag_unsafe_math_optimizations" 16407{ 16408 rtx temp; 16409 16410 operands[2] = gen_reg_rtx (XFmode); 16411 operands[3] = gen_reg_rtx (XFmode); 16412 operands[4] = gen_reg_rtx (XFmode); 16413 16414 temp = standard_80387_constant_rtx (4); /* fldln2 */ 16415 emit_move_insn (operands[3], temp); 16416}) 16417 16418(define_expand "logdf2" 16419 [(set (match_dup 2) 16420 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16421 (parallel [(set (match_dup 4) 16422 (unspec:XF [(match_dup 2) 16423 (match_dup 3)] UNSPEC_FYL2X)) 16424 (clobber (match_scratch:XF 5 ""))]) 16425 (set (match_operand:DF 0 "register_operand" "") 16426 (float_truncate:DF (match_dup 4)))] 16427 "TARGET_USE_FANCY_MATH_387 16428 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16429 && flag_unsafe_math_optimizations" 16430{ 16431 rtx temp; 16432 16433 operands[2] = gen_reg_rtx (XFmode); 16434 operands[3] = gen_reg_rtx (XFmode); 16435 operands[4] = gen_reg_rtx (XFmode); 16436 16437 temp = standard_80387_constant_rtx (4); /* fldln2 */ 16438 emit_move_insn (operands[3], temp); 16439}) 16440 16441(define_expand "logxf2" 16442 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16443 (unspec:XF [(match_operand:XF 1 "register_operand" "") 16444 (match_dup 2)] UNSPEC_FYL2X)) 16445 (clobber (match_scratch:XF 3 ""))])] 16446 "TARGET_USE_FANCY_MATH_387 16447 && flag_unsafe_math_optimizations" 16448{ 16449 rtx temp; 16450 16451 operands[2] = gen_reg_rtx (XFmode); 16452 temp = standard_80387_constant_rtx (4); /* fldln2 */ 16453 emit_move_insn (operands[2], temp); 16454}) 16455 16456(define_expand "log10sf2" 16457 [(set (match_dup 2) 16458 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16459 (parallel [(set (match_dup 4) 16460 (unspec:XF [(match_dup 2) 16461 (match_dup 3)] UNSPEC_FYL2X)) 16462 (clobber (match_scratch:XF 5 ""))]) 16463 (set (match_operand:SF 0 "register_operand" "") 16464 (float_truncate:SF (match_dup 4)))] 16465 "TARGET_USE_FANCY_MATH_387 16466 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16467 && flag_unsafe_math_optimizations" 16468{ 16469 rtx temp; 16470 16471 operands[2] = gen_reg_rtx (XFmode); 16472 operands[3] = gen_reg_rtx (XFmode); 16473 operands[4] = gen_reg_rtx (XFmode); 16474 16475 temp = standard_80387_constant_rtx (3); /* fldlg2 */ 16476 emit_move_insn (operands[3], temp); 16477}) 16478 16479(define_expand "log10df2" 16480 [(set (match_dup 2) 16481 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16482 (parallel [(set (match_dup 4) 16483 (unspec:XF [(match_dup 2) 16484 (match_dup 3)] UNSPEC_FYL2X)) 16485 (clobber (match_scratch:XF 5 ""))]) 16486 (set (match_operand:DF 0 "register_operand" "") 16487 (float_truncate:DF (match_dup 4)))] 16488 "TARGET_USE_FANCY_MATH_387 16489 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16490 && flag_unsafe_math_optimizations" 16491{ 16492 rtx temp; 16493 16494 operands[2] = gen_reg_rtx (XFmode); 16495 operands[3] = gen_reg_rtx (XFmode); 16496 operands[4] = gen_reg_rtx (XFmode); 16497 16498 temp = standard_80387_constant_rtx (3); /* fldlg2 */ 16499 emit_move_insn (operands[3], temp); 16500}) 16501 16502(define_expand "log10xf2" 16503 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16504 (unspec:XF [(match_operand:XF 1 "register_operand" "") 16505 (match_dup 2)] UNSPEC_FYL2X)) 16506 (clobber (match_scratch:XF 3 ""))])] 16507 "TARGET_USE_FANCY_MATH_387 16508 && flag_unsafe_math_optimizations" 16509{ 16510 rtx temp; 16511 16512 operands[2] = gen_reg_rtx (XFmode); 16513 temp = standard_80387_constant_rtx (3); /* fldlg2 */ 16514 emit_move_insn (operands[2], temp); 16515}) 16516 16517(define_expand "log2sf2" 16518 [(set (match_dup 2) 16519 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16520 (parallel [(set (match_dup 4) 16521 (unspec:XF [(match_dup 2) 16522 (match_dup 3)] UNSPEC_FYL2X)) 16523 (clobber (match_scratch:XF 5 ""))]) 16524 (set (match_operand:SF 0 "register_operand" "") 16525 (float_truncate:SF (match_dup 4)))] 16526 "TARGET_USE_FANCY_MATH_387 16527 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16528 && flag_unsafe_math_optimizations" 16529{ 16530 operands[2] = gen_reg_rtx (XFmode); 16531 operands[3] = gen_reg_rtx (XFmode); 16532 operands[4] = gen_reg_rtx (XFmode); 16533 16534 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16535}) 16536 16537(define_expand "log2df2" 16538 [(set (match_dup 2) 16539 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16540 (parallel [(set (match_dup 4) 16541 (unspec:XF [(match_dup 2) 16542 (match_dup 3)] UNSPEC_FYL2X)) 16543 (clobber (match_scratch:XF 5 ""))]) 16544 (set (match_operand:DF 0 "register_operand" "") 16545 (float_truncate:DF (match_dup 4)))] 16546 "TARGET_USE_FANCY_MATH_387 16547 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16548 && flag_unsafe_math_optimizations" 16549{ 16550 operands[2] = gen_reg_rtx (XFmode); 16551 operands[3] = gen_reg_rtx (XFmode); 16552 operands[4] = gen_reg_rtx (XFmode); 16553 16554 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16555}) 16556 16557(define_expand "log2xf2" 16558 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16559 (unspec:XF [(match_operand:XF 1 "register_operand" "") 16560 (match_dup 2)] UNSPEC_FYL2X)) 16561 (clobber (match_scratch:XF 3 ""))])] 16562 "TARGET_USE_FANCY_MATH_387 16563 && flag_unsafe_math_optimizations" 16564{ 16565 operands[2] = gen_reg_rtx (XFmode); 16566 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 16567}) 16568 16569(define_insn "fyl2xp1_xf3" 16570 [(set (match_operand:XF 0 "register_operand" "=f") 16571 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16572 (match_operand:XF 1 "register_operand" "u")] 16573 UNSPEC_FYL2XP1)) 16574 (clobber (match_scratch:XF 3 "=1"))] 16575 "TARGET_USE_FANCY_MATH_387 16576 && flag_unsafe_math_optimizations" 16577 "fyl2xp1" 16578 [(set_attr "type" "fpspc") 16579 (set_attr "mode" "XF")]) 16580 16581(define_expand "log1psf2" 16582 [(use (match_operand:SF 0 "register_operand" "")) 16583 (use (match_operand:SF 1 "register_operand" ""))] 16584 "TARGET_USE_FANCY_MATH_387 16585 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16586 && flag_unsafe_math_optimizations" 16587{ 16588 rtx op0 = gen_reg_rtx (XFmode); 16589 rtx op1 = gen_reg_rtx (XFmode); 16590 16591 emit_insn (gen_extendsfxf2 (op1, operands[1])); 16592 ix86_emit_i387_log1p (op0, op1); 16593 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 16594 DONE; 16595}) 16596 16597(define_expand "log1pdf2" 16598 [(use (match_operand:DF 0 "register_operand" "")) 16599 (use (match_operand:DF 1 "register_operand" ""))] 16600 "TARGET_USE_FANCY_MATH_387 16601 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16602 && flag_unsafe_math_optimizations" 16603{ 16604 rtx op0 = gen_reg_rtx (XFmode); 16605 rtx op1 = gen_reg_rtx (XFmode); 16606 16607 emit_insn (gen_extenddfxf2 (op1, operands[1])); 16608 ix86_emit_i387_log1p (op0, op1); 16609 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 16610 DONE; 16611}) 16612 16613(define_expand "log1pxf2" 16614 [(use (match_operand:XF 0 "register_operand" "")) 16615 (use (match_operand:XF 1 "register_operand" ""))] 16616 "TARGET_USE_FANCY_MATH_387 16617 && flag_unsafe_math_optimizations" 16618{ 16619 ix86_emit_i387_log1p (operands[0], operands[1]); 16620 DONE; 16621}) 16622 16623(define_insn "*fxtractxf3" 16624 [(set (match_operand:XF 0 "register_operand" "=f") 16625 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 16626 UNSPEC_XTRACT_FRACT)) 16627 (set (match_operand:XF 1 "register_operand" "=u") 16628 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))] 16629 "TARGET_USE_FANCY_MATH_387 16630 && flag_unsafe_math_optimizations" 16631 "fxtract" 16632 [(set_attr "type" "fpspc") 16633 (set_attr "mode" "XF")]) 16634 16635(define_expand "logbsf2" 16636 [(set (match_dup 2) 16637 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16638 (parallel [(set (match_dup 3) 16639 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT)) 16640 (set (match_dup 4) 16641 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]) 16642 (set (match_operand:SF 0 "register_operand" "") 16643 (float_truncate:SF (match_dup 4)))] 16644 "TARGET_USE_FANCY_MATH_387 16645 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16646 && flag_unsafe_math_optimizations" 16647{ 16648 operands[2] = gen_reg_rtx (XFmode); 16649 operands[3] = gen_reg_rtx (XFmode); 16650 operands[4] = gen_reg_rtx (XFmode); 16651}) 16652 16653(define_expand "logbdf2" 16654 [(set (match_dup 2) 16655 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16656 (parallel [(set (match_dup 3) 16657 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT)) 16658 (set (match_dup 4) 16659 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]) 16660 (set (match_operand:DF 0 "register_operand" "") 16661 (float_truncate:DF (match_dup 4)))] 16662 "TARGET_USE_FANCY_MATH_387 16663 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16664 && flag_unsafe_math_optimizations" 16665{ 16666 operands[2] = gen_reg_rtx (XFmode); 16667 operands[3] = gen_reg_rtx (XFmode); 16668 operands[4] = gen_reg_rtx (XFmode); 16669}) 16670 16671(define_expand "logbxf2" 16672 [(parallel [(set (match_dup 2) 16673 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 16674 UNSPEC_XTRACT_FRACT)) 16675 (set (match_operand:XF 0 "register_operand" "") 16676 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 16677 "TARGET_USE_FANCY_MATH_387 16678 && flag_unsafe_math_optimizations" 16679{ 16680 operands[2] = gen_reg_rtx (XFmode); 16681}) 16682 16683(define_expand "ilogbsi2" 16684 [(parallel [(set (match_dup 2) 16685 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 16686 UNSPEC_XTRACT_FRACT)) 16687 (set (match_operand:XF 3 "register_operand" "") 16688 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))]) 16689 (parallel [(set (match_operand:SI 0 "register_operand" "") 16690 (fix:SI (match_dup 3))) 16691 (clobber (reg:CC FLAGS_REG))])] 16692 "TARGET_USE_FANCY_MATH_387 16693 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16694 && flag_unsafe_math_optimizations" 16695{ 16696 operands[2] = gen_reg_rtx (XFmode); 16697 operands[3] = gen_reg_rtx (XFmode); 16698}) 16699 16700(define_insn "*f2xm1xf2" 16701 [(set (match_operand:XF 0 "register_operand" "=f") 16702 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16703 UNSPEC_F2XM1))] 16704 "TARGET_USE_FANCY_MATH_387 16705 && flag_unsafe_math_optimizations" 16706 "f2xm1" 16707 [(set_attr "type" "fpspc") 16708 (set_attr "mode" "XF")]) 16709 16710(define_insn "*fscalexf4" 16711 [(set (match_operand:XF 0 "register_operand" "=f") 16712 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16713 (match_operand:XF 3 "register_operand" "1")] 16714 UNSPEC_FSCALE_FRACT)) 16715 (set (match_operand:XF 1 "register_operand" "=u") 16716 (unspec:XF [(match_dup 2) (match_dup 3)] 16717 UNSPEC_FSCALE_EXP))] 16718 "TARGET_USE_FANCY_MATH_387 16719 && flag_unsafe_math_optimizations" 16720 "fscale" 16721 [(set_attr "type" "fpspc") 16722 (set_attr "mode" "XF")]) 16723 16724(define_expand "expsf2" 16725 [(set (match_dup 2) 16726 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16727 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16728 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16729 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16730 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16731 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 16732 (parallel [(set (match_dup 10) 16733 (unspec:XF [(match_dup 9) (match_dup 5)] 16734 UNSPEC_FSCALE_FRACT)) 16735 (set (match_dup 11) 16736 (unspec:XF [(match_dup 9) (match_dup 5)] 16737 UNSPEC_FSCALE_EXP))]) 16738 (set (match_operand:SF 0 "register_operand" "") 16739 (float_truncate:SF (match_dup 10)))] 16740 "TARGET_USE_FANCY_MATH_387 16741 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16742 && flag_unsafe_math_optimizations" 16743{ 16744 rtx temp; 16745 int i; 16746 16747 for (i=2; i<12; i++) 16748 operands[i] = gen_reg_rtx (XFmode); 16749 temp = standard_80387_constant_rtx (5); /* fldl2e */ 16750 emit_move_insn (operands[3], temp); 16751 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 16752}) 16753 16754(define_expand "expdf2" 16755 [(set (match_dup 2) 16756 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16757 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16758 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16759 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16760 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16761 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 16762 (parallel [(set (match_dup 10) 16763 (unspec:XF [(match_dup 9) (match_dup 5)] 16764 UNSPEC_FSCALE_FRACT)) 16765 (set (match_dup 11) 16766 (unspec:XF [(match_dup 9) (match_dup 5)] 16767 UNSPEC_FSCALE_EXP))]) 16768 (set (match_operand:DF 0 "register_operand" "") 16769 (float_truncate:DF (match_dup 10)))] 16770 "TARGET_USE_FANCY_MATH_387 16771 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16772 && flag_unsafe_math_optimizations" 16773{ 16774 rtx temp; 16775 int i; 16776 16777 for (i=2; i<12; i++) 16778 operands[i] = gen_reg_rtx (XFmode); 16779 temp = standard_80387_constant_rtx (5); /* fldl2e */ 16780 emit_move_insn (operands[3], temp); 16781 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 16782}) 16783 16784(define_expand "expxf2" 16785 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 16786 (match_dup 2))) 16787 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 16788 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 16789 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 16790 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 16791 (parallel [(set (match_operand:XF 0 "register_operand" "") 16792 (unspec:XF [(match_dup 8) (match_dup 4)] 16793 UNSPEC_FSCALE_FRACT)) 16794 (set (match_dup 9) 16795 (unspec:XF [(match_dup 8) (match_dup 4)] 16796 UNSPEC_FSCALE_EXP))])] 16797 "TARGET_USE_FANCY_MATH_387 16798 && flag_unsafe_math_optimizations" 16799{ 16800 rtx temp; 16801 int i; 16802 16803 for (i=2; i<10; i++) 16804 operands[i] = gen_reg_rtx (XFmode); 16805 temp = standard_80387_constant_rtx (5); /* fldl2e */ 16806 emit_move_insn (operands[2], temp); 16807 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ 16808}) 16809 16810(define_expand "exp10sf2" 16811 [(set (match_dup 2) 16812 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16813 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16814 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16815 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16816 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16817 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 16818 (parallel [(set (match_dup 10) 16819 (unspec:XF [(match_dup 9) (match_dup 5)] 16820 UNSPEC_FSCALE_FRACT)) 16821 (set (match_dup 11) 16822 (unspec:XF [(match_dup 9) (match_dup 5)] 16823 UNSPEC_FSCALE_EXP))]) 16824 (set (match_operand:SF 0 "register_operand" "") 16825 (float_truncate:SF (match_dup 10)))] 16826 "TARGET_USE_FANCY_MATH_387 16827 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16828 && flag_unsafe_math_optimizations" 16829{ 16830 rtx temp; 16831 int i; 16832 16833 for (i=2; i<12; i++) 16834 operands[i] = gen_reg_rtx (XFmode); 16835 temp = standard_80387_constant_rtx (6); /* fldl2t */ 16836 emit_move_insn (operands[3], temp); 16837 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 16838}) 16839 16840(define_expand "exp10df2" 16841 [(set (match_dup 2) 16842 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16843 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16844 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16845 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16846 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16847 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 16848 (parallel [(set (match_dup 10) 16849 (unspec:XF [(match_dup 9) (match_dup 5)] 16850 UNSPEC_FSCALE_FRACT)) 16851 (set (match_dup 11) 16852 (unspec:XF [(match_dup 9) (match_dup 5)] 16853 UNSPEC_FSCALE_EXP))]) 16854 (set (match_operand:DF 0 "register_operand" "") 16855 (float_truncate:DF (match_dup 10)))] 16856 "TARGET_USE_FANCY_MATH_387 16857 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16858 && flag_unsafe_math_optimizations" 16859{ 16860 rtx temp; 16861 int i; 16862 16863 for (i=2; i<12; i++) 16864 operands[i] = gen_reg_rtx (XFmode); 16865 temp = standard_80387_constant_rtx (6); /* fldl2t */ 16866 emit_move_insn (operands[3], temp); 16867 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 16868}) 16869 16870(define_expand "exp10xf2" 16871 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 16872 (match_dup 2))) 16873 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 16874 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 16875 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 16876 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 16877 (parallel [(set (match_operand:XF 0 "register_operand" "") 16878 (unspec:XF [(match_dup 8) (match_dup 4)] 16879 UNSPEC_FSCALE_FRACT)) 16880 (set (match_dup 9) 16881 (unspec:XF [(match_dup 8) (match_dup 4)] 16882 UNSPEC_FSCALE_EXP))])] 16883 "TARGET_USE_FANCY_MATH_387 16884 && flag_unsafe_math_optimizations" 16885{ 16886 rtx temp; 16887 int i; 16888 16889 for (i=2; i<10; i++) 16890 operands[i] = gen_reg_rtx (XFmode); 16891 temp = standard_80387_constant_rtx (6); /* fldl2t */ 16892 emit_move_insn (operands[2], temp); 16893 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ 16894}) 16895 16896(define_expand "exp2sf2" 16897 [(set (match_dup 2) 16898 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16899 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT)) 16900 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3))) 16901 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1)) 16902 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6))) 16903 (parallel [(set (match_dup 8) 16904 (unspec:XF [(match_dup 7) (match_dup 3)] 16905 UNSPEC_FSCALE_FRACT)) 16906 (set (match_dup 9) 16907 (unspec:XF [(match_dup 7) (match_dup 3)] 16908 UNSPEC_FSCALE_EXP))]) 16909 (set (match_operand:SF 0 "register_operand" "") 16910 (float_truncate:SF (match_dup 8)))] 16911 "TARGET_USE_FANCY_MATH_387 16912 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16913 && flag_unsafe_math_optimizations" 16914{ 16915 int i; 16916 16917 for (i=2; i<10; i++) 16918 operands[i] = gen_reg_rtx (XFmode); 16919 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */ 16920}) 16921 16922(define_expand "exp2df2" 16923 [(set (match_dup 2) 16924 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16925 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT)) 16926 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3))) 16927 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1)) 16928 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6))) 16929 (parallel [(set (match_dup 8) 16930 (unspec:XF [(match_dup 7) (match_dup 3)] 16931 UNSPEC_FSCALE_FRACT)) 16932 (set (match_dup 9) 16933 (unspec:XF [(match_dup 7) (match_dup 3)] 16934 UNSPEC_FSCALE_EXP))]) 16935 (set (match_operand:DF 0 "register_operand" "") 16936 (float_truncate:DF (match_dup 8)))] 16937 "TARGET_USE_FANCY_MATH_387 16938 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16939 && flag_unsafe_math_optimizations" 16940{ 16941 int i; 16942 16943 for (i=2; i<10; i++) 16944 operands[i] = gen_reg_rtx (XFmode); 16945 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */ 16946}) 16947 16948(define_expand "exp2xf2" 16949 [(set (match_dup 2) (match_operand:XF 1 "register_operand" "")) 16950 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT)) 16951 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3))) 16952 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1)) 16953 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6))) 16954 (parallel [(set (match_operand:XF 0 "register_operand" "") 16955 (unspec:XF [(match_dup 7) (match_dup 3)] 16956 UNSPEC_FSCALE_FRACT)) 16957 (set (match_dup 8) 16958 (unspec:XF [(match_dup 7) (match_dup 3)] 16959 UNSPEC_FSCALE_EXP))])] 16960 "TARGET_USE_FANCY_MATH_387 16961 && flag_unsafe_math_optimizations" 16962{ 16963 int i; 16964 16965 for (i=2; i<9; i++) 16966 operands[i] = gen_reg_rtx (XFmode); 16967 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */ 16968}) 16969 16970(define_expand "expm1df2" 16971 [(set (match_dup 2) 16972 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16973 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16974 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16975 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16976 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16977 (parallel [(set (match_dup 8) 16978 (unspec:XF [(match_dup 7) (match_dup 5)] 16979 UNSPEC_FSCALE_FRACT)) 16980 (set (match_dup 9) 16981 (unspec:XF [(match_dup 7) (match_dup 5)] 16982 UNSPEC_FSCALE_EXP))]) 16983 (parallel [(set (match_dup 11) 16984 (unspec:XF [(match_dup 10) (match_dup 9)] 16985 UNSPEC_FSCALE_FRACT)) 16986 (set (match_dup 12) 16987 (unspec:XF [(match_dup 10) (match_dup 9)] 16988 UNSPEC_FSCALE_EXP))]) 16989 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10))) 16990 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8))) 16991 (set (match_operand:DF 0 "register_operand" "") 16992 (float_truncate:DF (match_dup 14)))] 16993 "TARGET_USE_FANCY_MATH_387 16994 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16995 && flag_unsafe_math_optimizations" 16996{ 16997 rtx temp; 16998 int i; 16999 17000 for (i=2; i<15; i++) 17001 operands[i] = gen_reg_rtx (XFmode); 17002 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17003 emit_move_insn (operands[3], temp); 17004 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */ 17005}) 17006 17007(define_expand "expm1sf2" 17008 [(set (match_dup 2) 17009 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 17010 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 17011 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 17012 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 17013 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 17014 (parallel [(set (match_dup 8) 17015 (unspec:XF [(match_dup 7) (match_dup 5)] 17016 UNSPEC_FSCALE_FRACT)) 17017 (set (match_dup 9) 17018 (unspec:XF [(match_dup 7) (match_dup 5)] 17019 UNSPEC_FSCALE_EXP))]) 17020 (parallel [(set (match_dup 11) 17021 (unspec:XF [(match_dup 10) (match_dup 9)] 17022 UNSPEC_FSCALE_FRACT)) 17023 (set (match_dup 12) 17024 (unspec:XF [(match_dup 10) (match_dup 9)] 17025 UNSPEC_FSCALE_EXP))]) 17026 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10))) 17027 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8))) 17028 (set (match_operand:SF 0 "register_operand" "") 17029 (float_truncate:SF (match_dup 14)))] 17030 "TARGET_USE_FANCY_MATH_387 17031 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17032 && flag_unsafe_math_optimizations" 17033{ 17034 rtx temp; 17035 int i; 17036 17037 for (i=2; i<15; i++) 17038 operands[i] = gen_reg_rtx (XFmode); 17039 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17040 emit_move_insn (operands[3], temp); 17041 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */ 17042}) 17043 17044(define_expand "expm1xf2" 17045 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 17046 (match_dup 2))) 17047 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 17048 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 17049 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 17050 (parallel [(set (match_dup 7) 17051 (unspec:XF [(match_dup 6) (match_dup 4)] 17052 UNSPEC_FSCALE_FRACT)) 17053 (set (match_dup 8) 17054 (unspec:XF [(match_dup 6) (match_dup 4)] 17055 UNSPEC_FSCALE_EXP))]) 17056 (parallel [(set (match_dup 10) 17057 (unspec:XF [(match_dup 9) (match_dup 8)] 17058 UNSPEC_FSCALE_FRACT)) 17059 (set (match_dup 11) 17060 (unspec:XF [(match_dup 9) (match_dup 8)] 17061 UNSPEC_FSCALE_EXP))]) 17062 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9))) 17063 (set (match_operand:XF 0 "register_operand" "") 17064 (plus:XF (match_dup 12) (match_dup 7)))] 17065 "TARGET_USE_FANCY_MATH_387 17066 && flag_unsafe_math_optimizations" 17067{ 17068 rtx temp; 17069 int i; 17070 17071 for (i=2; i<13; i++) 17072 operands[i] = gen_reg_rtx (XFmode); 17073 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17074 emit_move_insn (operands[2], temp); 17075 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */ 17076}) 17077 17078(define_expand "ldexpdf3" 17079 [(set (match_dup 3) 17080 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 17081 (set (match_dup 4) 17082 (float:XF (match_operand:SI 2 "register_operand" ""))) 17083 (parallel [(set (match_dup 5) 17084 (unspec:XF [(match_dup 3) (match_dup 4)] 17085 UNSPEC_FSCALE_FRACT)) 17086 (set (match_dup 6) 17087 (unspec:XF [(match_dup 3) (match_dup 4)] 17088 UNSPEC_FSCALE_EXP))]) 17089 (set (match_operand:DF 0 "register_operand" "") 17090 (float_truncate:DF (match_dup 5)))] 17091 "TARGET_USE_FANCY_MATH_387 17092 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17093 && flag_unsafe_math_optimizations" 17094{ 17095 int i; 17096 17097 for (i=3; i<7; i++) 17098 operands[i] = gen_reg_rtx (XFmode); 17099}) 17100 17101(define_expand "ldexpsf3" 17102 [(set (match_dup 3) 17103 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 17104 (set (match_dup 4) 17105 (float:XF (match_operand:SI 2 "register_operand" ""))) 17106 (parallel [(set (match_dup 5) 17107 (unspec:XF [(match_dup 3) (match_dup 4)] 17108 UNSPEC_FSCALE_FRACT)) 17109 (set (match_dup 6) 17110 (unspec:XF [(match_dup 3) (match_dup 4)] 17111 UNSPEC_FSCALE_EXP))]) 17112 (set (match_operand:SF 0 "register_operand" "") 17113 (float_truncate:SF (match_dup 5)))] 17114 "TARGET_USE_FANCY_MATH_387 17115 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17116 && flag_unsafe_math_optimizations" 17117{ 17118 int i; 17119 17120 for (i=3; i<7; i++) 17121 operands[i] = gen_reg_rtx (XFmode); 17122}) 17123 17124(define_expand "ldexpxf3" 17125 [(set (match_dup 3) 17126 (float:XF (match_operand:SI 2 "register_operand" ""))) 17127 (parallel [(set (match_operand:XF 0 " register_operand" "") 17128 (unspec:XF [(match_operand:XF 1 "register_operand" "") 17129 (match_dup 3)] 17130 UNSPEC_FSCALE_FRACT)) 17131 (set (match_dup 4) 17132 (unspec:XF [(match_dup 1) (match_dup 3)] 17133 UNSPEC_FSCALE_EXP))])] 17134 "TARGET_USE_FANCY_MATH_387 17135 && flag_unsafe_math_optimizations" 17136{ 17137 int i; 17138 17139 for (i=3; i<5; i++) 17140 operands[i] = gen_reg_rtx (XFmode); 17141}) 17142 17143 17144(define_insn "frndintxf2" 17145 [(set (match_operand:XF 0 "register_operand" "=f") 17146 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17147 UNSPEC_FRNDINT))] 17148 "TARGET_USE_FANCY_MATH_387 17149 && flag_unsafe_math_optimizations" 17150 "frndint" 17151 [(set_attr "type" "fpspc") 17152 (set_attr "mode" "XF")]) 17153 17154(define_expand "rintdf2" 17155 [(use (match_operand:DF 0 "register_operand" "")) 17156 (use (match_operand:DF 1 "register_operand" ""))] 17157 "TARGET_USE_FANCY_MATH_387 17158 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17159 && flag_unsafe_math_optimizations" 17160{ 17161 rtx op0 = gen_reg_rtx (XFmode); 17162 rtx op1 = gen_reg_rtx (XFmode); 17163 17164 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17165 emit_insn (gen_frndintxf2 (op0, op1)); 17166 17167 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17168 DONE; 17169}) 17170 17171(define_expand "rintsf2" 17172 [(use (match_operand:SF 0 "register_operand" "")) 17173 (use (match_operand:SF 1 "register_operand" ""))] 17174 "TARGET_USE_FANCY_MATH_387 17175 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17176 && flag_unsafe_math_optimizations" 17177{ 17178 rtx op0 = gen_reg_rtx (XFmode); 17179 rtx op1 = gen_reg_rtx (XFmode); 17180 17181 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17182 emit_insn (gen_frndintxf2 (op0, op1)); 17183 17184 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17185 DONE; 17186}) 17187 17188(define_expand "rintxf2" 17189 [(use (match_operand:XF 0 "register_operand" "")) 17190 (use (match_operand:XF 1 "register_operand" ""))] 17191 "TARGET_USE_FANCY_MATH_387 17192 && flag_unsafe_math_optimizations" 17193{ 17194 emit_insn (gen_frndintxf2 (operands[0], operands[1])); 17195 DONE; 17196}) 17197 17198(define_insn_and_split "*fistdi2_1" 17199 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17200 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17201 UNSPEC_FIST))] 17202 "TARGET_USE_FANCY_MATH_387 17203 && flag_unsafe_math_optimizations 17204 && !(reload_completed || reload_in_progress)" 17205 "#" 17206 "&& 1" 17207 [(const_int 0)] 17208{ 17209 if (memory_operand (operands[0], VOIDmode)) 17210 emit_insn (gen_fistdi2 (operands[0], operands[1])); 17211 else 17212 { 17213 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP); 17214 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1], 17215 operands[2])); 17216 } 17217 DONE; 17218} 17219 [(set_attr "type" "fpspc") 17220 (set_attr "mode" "DI")]) 17221 17222(define_insn "fistdi2" 17223 [(set (match_operand:DI 0 "memory_operand" "=m") 17224 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 17225 UNSPEC_FIST)) 17226 (clobber (match_scratch:XF 2 "=&1f"))] 17227 "TARGET_USE_FANCY_MATH_387 17228 && flag_unsafe_math_optimizations" 17229 "* return output_fix_trunc (insn, operands, 0);" 17230 [(set_attr "type" "fpspc") 17231 (set_attr "mode" "DI")]) 17232 17233(define_insn "fistdi2_with_temp" 17234 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17235 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17236 UNSPEC_FIST)) 17237 (clobber (match_operand:DI 2 "memory_operand" "=m,m")) 17238 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 17239 "TARGET_USE_FANCY_MATH_387 17240 && flag_unsafe_math_optimizations" 17241 "#" 17242 [(set_attr "type" "fpspc") 17243 (set_attr "mode" "DI")]) 17244 17245(define_split 17246 [(set (match_operand:DI 0 "register_operand" "") 17247 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17248 UNSPEC_FIST)) 17249 (clobber (match_operand:DI 2 "memory_operand" "")) 17250 (clobber (match_scratch 3 ""))] 17251 "reload_completed" 17252 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 17253 (clobber (match_dup 3))]) 17254 (set (match_dup 0) (match_dup 2))] 17255 "") 17256 17257(define_split 17258 [(set (match_operand:DI 0 "memory_operand" "") 17259 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17260 UNSPEC_FIST)) 17261 (clobber (match_operand:DI 2 "memory_operand" "")) 17262 (clobber (match_scratch 3 ""))] 17263 "reload_completed" 17264 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 17265 (clobber (match_dup 3))])] 17266 "") 17267 17268(define_insn_and_split "*fist<mode>2_1" 17269 [(set (match_operand:X87MODEI12 0 "register_operand" "=r") 17270 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17271 UNSPEC_FIST))] 17272 "TARGET_USE_FANCY_MATH_387 17273 && flag_unsafe_math_optimizations 17274 && !(reload_completed || reload_in_progress)" 17275 "#" 17276 "&& 1" 17277 [(const_int 0)] 17278{ 17279 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17280 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1], 17281 operands[2])); 17282 DONE; 17283} 17284 [(set_attr "type" "fpspc") 17285 (set_attr "mode" "<MODE>")]) 17286 17287(define_insn "fist<mode>2" 17288 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 17289 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17290 UNSPEC_FIST))] 17291 "TARGET_USE_FANCY_MATH_387 17292 && flag_unsafe_math_optimizations" 17293 "* return output_fix_trunc (insn, operands, 0);" 17294 [(set_attr "type" "fpspc") 17295 (set_attr "mode" "<MODE>")]) 17296 17297(define_insn "fist<mode>2_with_temp" 17298 [(set (match_operand:X87MODEI12 0 "register_operand" "=r") 17299 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17300 UNSPEC_FIST)) 17301 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))] 17302 "TARGET_USE_FANCY_MATH_387 17303 && flag_unsafe_math_optimizations" 17304 "#" 17305 [(set_attr "type" "fpspc") 17306 (set_attr "mode" "<MODE>")]) 17307 17308(define_split 17309 [(set (match_operand:X87MODEI12 0 "register_operand" "") 17310 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17311 UNSPEC_FIST)) 17312 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))] 17313 "reload_completed" 17314 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] 17315 UNSPEC_FIST)) 17316 (set (match_dup 0) (match_dup 2))] 17317 "") 17318 17319(define_split 17320 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 17321 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17322 UNSPEC_FIST)) 17323 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))] 17324 "reload_completed" 17325 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] 17326 UNSPEC_FIST))] 17327 "") 17328 17329(define_expand "lrint<mode>2" 17330 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") 17331 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] 17332 UNSPEC_FIST))] 17333 "TARGET_USE_FANCY_MATH_387 17334 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17335 && flag_unsafe_math_optimizations" 17336 "") 17337 17338;; Rounding mode control word calculation could clobber FLAGS_REG. 17339(define_insn_and_split "frndintxf2_floor" 17340 [(set (match_operand:XF 0 "register_operand" "=f") 17341 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17342 UNSPEC_FRNDINT_FLOOR)) 17343 (clobber (reg:CC FLAGS_REG))] 17344 "TARGET_USE_FANCY_MATH_387 17345 && flag_unsafe_math_optimizations 17346 && !(reload_completed || reload_in_progress)" 17347 "#" 17348 "&& 1" 17349 [(const_int 0)] 17350{ 17351 ix86_optimize_mode_switching[I387_FLOOR] = 1; 17352 17353 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17354 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); 17355 17356 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1], 17357 operands[2], operands[3])); 17358 DONE; 17359} 17360 [(set_attr "type" "frndint") 17361 (set_attr "i387_cw" "floor") 17362 (set_attr "mode" "XF")]) 17363 17364(define_insn "frndintxf2_floor_i387" 17365 [(set (match_operand:XF 0 "register_operand" "=f") 17366 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17367 UNSPEC_FRNDINT_FLOOR)) 17368 (use (match_operand:HI 2 "memory_operand" "m")) 17369 (use (match_operand:HI 3 "memory_operand" "m"))] 17370 "TARGET_USE_FANCY_MATH_387 17371 && flag_unsafe_math_optimizations" 17372 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 17373 [(set_attr "type" "frndint") 17374 (set_attr "i387_cw" "floor") 17375 (set_attr "mode" "XF")]) 17376 17377(define_expand "floorxf2" 17378 [(use (match_operand:XF 0 "register_operand" "")) 17379 (use (match_operand:XF 1 "register_operand" ""))] 17380 "TARGET_USE_FANCY_MATH_387 17381 && flag_unsafe_math_optimizations" 17382{ 17383 emit_insn (gen_frndintxf2_floor (operands[0], operands[1])); 17384 DONE; 17385}) 17386 17387(define_expand "floordf2" 17388 [(use (match_operand:DF 0 "register_operand" "")) 17389 (use (match_operand:DF 1 "register_operand" ""))] 17390 "TARGET_USE_FANCY_MATH_387 17391 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17392 && flag_unsafe_math_optimizations" 17393{ 17394 rtx op0 = gen_reg_rtx (XFmode); 17395 rtx op1 = gen_reg_rtx (XFmode); 17396 17397 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17398 emit_insn (gen_frndintxf2_floor (op0, op1)); 17399 17400 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17401 DONE; 17402}) 17403 17404(define_expand "floorsf2" 17405 [(use (match_operand:SF 0 "register_operand" "")) 17406 (use (match_operand:SF 1 "register_operand" ""))] 17407 "TARGET_USE_FANCY_MATH_387 17408 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17409 && flag_unsafe_math_optimizations" 17410{ 17411 rtx op0 = gen_reg_rtx (XFmode); 17412 rtx op1 = gen_reg_rtx (XFmode); 17413 17414 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17415 emit_insn (gen_frndintxf2_floor (op0, op1)); 17416 17417 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17418 DONE; 17419}) 17420 17421(define_insn_and_split "*fist<mode>2_floor_1" 17422 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 17423 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")] 17424 UNSPEC_FIST_FLOOR)) 17425 (clobber (reg:CC FLAGS_REG))] 17426 "TARGET_USE_FANCY_MATH_387 17427 && flag_unsafe_math_optimizations 17428 && !(reload_completed || reload_in_progress)" 17429 "#" 17430 "&& 1" 17431 [(const_int 0)] 17432{ 17433 ix86_optimize_mode_switching[I387_FLOOR] = 1; 17434 17435 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17436 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); 17437 if (memory_operand (operands[0], VOIDmode)) 17438 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1], 17439 operands[2], operands[3])); 17440 else 17441 { 17442 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17443 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1], 17444 operands[2], operands[3], 17445 operands[4])); 17446 } 17447 DONE; 17448} 17449 [(set_attr "type" "fistp") 17450 (set_attr "i387_cw" "floor") 17451 (set_attr "mode" "<MODE>")]) 17452 17453(define_insn "fistdi2_floor" 17454 [(set (match_operand:DI 0 "memory_operand" "=m") 17455 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 17456 UNSPEC_FIST_FLOOR)) 17457 (use (match_operand:HI 2 "memory_operand" "m")) 17458 (use (match_operand:HI 3 "memory_operand" "m")) 17459 (clobber (match_scratch:XF 4 "=&1f"))] 17460 "TARGET_USE_FANCY_MATH_387 17461 && flag_unsafe_math_optimizations" 17462 "* return output_fix_trunc (insn, operands, 0);" 17463 [(set_attr "type" "fistp") 17464 (set_attr "i387_cw" "floor") 17465 (set_attr "mode" "DI")]) 17466 17467(define_insn "fistdi2_floor_with_temp" 17468 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17469 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17470 UNSPEC_FIST_FLOOR)) 17471 (use (match_operand:HI 2 "memory_operand" "m,m")) 17472 (use (match_operand:HI 3 "memory_operand" "m,m")) 17473 (clobber (match_operand:DI 4 "memory_operand" "=m,m")) 17474 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 17475 "TARGET_USE_FANCY_MATH_387 17476 && flag_unsafe_math_optimizations" 17477 "#" 17478 [(set_attr "type" "fistp") 17479 (set_attr "i387_cw" "floor") 17480 (set_attr "mode" "DI")]) 17481 17482(define_split 17483 [(set (match_operand:DI 0 "register_operand" "") 17484 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17485 UNSPEC_FIST_FLOOR)) 17486 (use (match_operand:HI 2 "memory_operand" "")) 17487 (use (match_operand:HI 3 "memory_operand" "")) 17488 (clobber (match_operand:DI 4 "memory_operand" "")) 17489 (clobber (match_scratch 5 ""))] 17490 "reload_completed" 17491 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) 17492 (use (match_dup 2)) 17493 (use (match_dup 3)) 17494 (clobber (match_dup 5))]) 17495 (set (match_dup 0) (match_dup 4))] 17496 "") 17497 17498(define_split 17499 [(set (match_operand:DI 0 "memory_operand" "") 17500 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17501 UNSPEC_FIST_FLOOR)) 17502 (use (match_operand:HI 2 "memory_operand" "")) 17503 (use (match_operand:HI 3 "memory_operand" "")) 17504 (clobber (match_operand:DI 4 "memory_operand" "")) 17505 (clobber (match_scratch 5 ""))] 17506 "reload_completed" 17507 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) 17508 (use (match_dup 2)) 17509 (use (match_dup 3)) 17510 (clobber (match_dup 5))])] 17511 "") 17512 17513(define_insn "fist<mode>2_floor" 17514 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 17515 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17516 UNSPEC_FIST_FLOOR)) 17517 (use (match_operand:HI 2 "memory_operand" "m")) 17518 (use (match_operand:HI 3 "memory_operand" "m"))] 17519 "TARGET_USE_FANCY_MATH_387 17520 && flag_unsafe_math_optimizations" 17521 "* return output_fix_trunc (insn, operands, 0);" 17522 [(set_attr "type" "fistp") 17523 (set_attr "i387_cw" "floor") 17524 (set_attr "mode" "<MODE>")]) 17525 17526(define_insn "fist<mode>2_floor_with_temp" 17527 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") 17528 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")] 17529 UNSPEC_FIST_FLOOR)) 17530 (use (match_operand:HI 2 "memory_operand" "m,m")) 17531 (use (match_operand:HI 3 "memory_operand" "m,m")) 17532 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))] 17533 "TARGET_USE_FANCY_MATH_387 17534 && flag_unsafe_math_optimizations" 17535 "#" 17536 [(set_attr "type" "fistp") 17537 (set_attr "i387_cw" "floor") 17538 (set_attr "mode" "<MODE>")]) 17539 17540(define_split 17541 [(set (match_operand:X87MODEI12 0 "register_operand" "") 17542 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17543 UNSPEC_FIST_FLOOR)) 17544 (use (match_operand:HI 2 "memory_operand" "")) 17545 (use (match_operand:HI 3 "memory_operand" "")) 17546 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 17547 "reload_completed" 17548 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)] 17549 UNSPEC_FIST_FLOOR)) 17550 (use (match_dup 2)) 17551 (use (match_dup 3))]) 17552 (set (match_dup 0) (match_dup 4))] 17553 "") 17554 17555(define_split 17556 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 17557 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17558 UNSPEC_FIST_FLOOR)) 17559 (use (match_operand:HI 2 "memory_operand" "")) 17560 (use (match_operand:HI 3 "memory_operand" "")) 17561 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 17562 "reload_completed" 17563 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] 17564 UNSPEC_FIST_FLOOR)) 17565 (use (match_dup 2)) 17566 (use (match_dup 3))])] 17567 "") 17568 17569(define_expand "lfloor<mode>2" 17570 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") 17571 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] 17572 UNSPEC_FIST_FLOOR)) 17573 (clobber (reg:CC FLAGS_REG))])] 17574 "TARGET_USE_FANCY_MATH_387 17575 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17576 && flag_unsafe_math_optimizations" 17577 "") 17578 17579;; Rounding mode control word calculation could clobber FLAGS_REG. 17580(define_insn_and_split "frndintxf2_ceil" 17581 [(set (match_operand:XF 0 "register_operand" "=f") 17582 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17583 UNSPEC_FRNDINT_CEIL)) 17584 (clobber (reg:CC FLAGS_REG))] 17585 "TARGET_USE_FANCY_MATH_387 17586 && flag_unsafe_math_optimizations 17587 && !(reload_completed || reload_in_progress)" 17588 "#" 17589 "&& 1" 17590 [(const_int 0)] 17591{ 17592 ix86_optimize_mode_switching[I387_CEIL] = 1; 17593 17594 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17595 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); 17596 17597 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1], 17598 operands[2], operands[3])); 17599 DONE; 17600} 17601 [(set_attr "type" "frndint") 17602 (set_attr "i387_cw" "ceil") 17603 (set_attr "mode" "XF")]) 17604 17605(define_insn "frndintxf2_ceil_i387" 17606 [(set (match_operand:XF 0 "register_operand" "=f") 17607 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17608 UNSPEC_FRNDINT_CEIL)) 17609 (use (match_operand:HI 2 "memory_operand" "m")) 17610 (use (match_operand:HI 3 "memory_operand" "m"))] 17611 "TARGET_USE_FANCY_MATH_387 17612 && flag_unsafe_math_optimizations" 17613 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 17614 [(set_attr "type" "frndint") 17615 (set_attr "i387_cw" "ceil") 17616 (set_attr "mode" "XF")]) 17617 17618(define_expand "ceilxf2" 17619 [(use (match_operand:XF 0 "register_operand" "")) 17620 (use (match_operand:XF 1 "register_operand" ""))] 17621 "TARGET_USE_FANCY_MATH_387 17622 && flag_unsafe_math_optimizations" 17623{ 17624 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1])); 17625 DONE; 17626}) 17627 17628(define_expand "ceildf2" 17629 [(use (match_operand:DF 0 "register_operand" "")) 17630 (use (match_operand:DF 1 "register_operand" ""))] 17631 "TARGET_USE_FANCY_MATH_387 17632 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17633 && flag_unsafe_math_optimizations" 17634{ 17635 rtx op0 = gen_reg_rtx (XFmode); 17636 rtx op1 = gen_reg_rtx (XFmode); 17637 17638 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17639 emit_insn (gen_frndintxf2_ceil (op0, op1)); 17640 17641 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17642 DONE; 17643}) 17644 17645(define_expand "ceilsf2" 17646 [(use (match_operand:SF 0 "register_operand" "")) 17647 (use (match_operand:SF 1 "register_operand" ""))] 17648 "TARGET_USE_FANCY_MATH_387 17649 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17650 && flag_unsafe_math_optimizations" 17651{ 17652 rtx op0 = gen_reg_rtx (XFmode); 17653 rtx op1 = gen_reg_rtx (XFmode); 17654 17655 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17656 emit_insn (gen_frndintxf2_ceil (op0, op1)); 17657 17658 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17659 DONE; 17660}) 17661 17662(define_insn_and_split "*fist<mode>2_ceil_1" 17663 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 17664 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")] 17665 UNSPEC_FIST_CEIL)) 17666 (clobber (reg:CC FLAGS_REG))] 17667 "TARGET_USE_FANCY_MATH_387 17668 && flag_unsafe_math_optimizations 17669 && !(reload_completed || reload_in_progress)" 17670 "#" 17671 "&& 1" 17672 [(const_int 0)] 17673{ 17674 ix86_optimize_mode_switching[I387_CEIL] = 1; 17675 17676 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17677 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); 17678 if (memory_operand (operands[0], VOIDmode)) 17679 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1], 17680 operands[2], operands[3])); 17681 else 17682 { 17683 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17684 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1], 17685 operands[2], operands[3], 17686 operands[4])); 17687 } 17688 DONE; 17689} 17690 [(set_attr "type" "fistp") 17691 (set_attr "i387_cw" "ceil") 17692 (set_attr "mode" "<MODE>")]) 17693 17694(define_insn "fistdi2_ceil" 17695 [(set (match_operand:DI 0 "memory_operand" "=m") 17696 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 17697 UNSPEC_FIST_CEIL)) 17698 (use (match_operand:HI 2 "memory_operand" "m")) 17699 (use (match_operand:HI 3 "memory_operand" "m")) 17700 (clobber (match_scratch:XF 4 "=&1f"))] 17701 "TARGET_USE_FANCY_MATH_387 17702 && flag_unsafe_math_optimizations" 17703 "* return output_fix_trunc (insn, operands, 0);" 17704 [(set_attr "type" "fistp") 17705 (set_attr "i387_cw" "ceil") 17706 (set_attr "mode" "DI")]) 17707 17708(define_insn "fistdi2_ceil_with_temp" 17709 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17710 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17711 UNSPEC_FIST_CEIL)) 17712 (use (match_operand:HI 2 "memory_operand" "m,m")) 17713 (use (match_operand:HI 3 "memory_operand" "m,m")) 17714 (clobber (match_operand:DI 4 "memory_operand" "=m,m")) 17715 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 17716 "TARGET_USE_FANCY_MATH_387 17717 && flag_unsafe_math_optimizations" 17718 "#" 17719 [(set_attr "type" "fistp") 17720 (set_attr "i387_cw" "ceil") 17721 (set_attr "mode" "DI")]) 17722 17723(define_split 17724 [(set (match_operand:DI 0 "register_operand" "") 17725 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17726 UNSPEC_FIST_CEIL)) 17727 (use (match_operand:HI 2 "memory_operand" "")) 17728 (use (match_operand:HI 3 "memory_operand" "")) 17729 (clobber (match_operand:DI 4 "memory_operand" "")) 17730 (clobber (match_scratch 5 ""))] 17731 "reload_completed" 17732 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) 17733 (use (match_dup 2)) 17734 (use (match_dup 3)) 17735 (clobber (match_dup 5))]) 17736 (set (match_dup 0) (match_dup 4))] 17737 "") 17738 17739(define_split 17740 [(set (match_operand:DI 0 "memory_operand" "") 17741 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17742 UNSPEC_FIST_CEIL)) 17743 (use (match_operand:HI 2 "memory_operand" "")) 17744 (use (match_operand:HI 3 "memory_operand" "")) 17745 (clobber (match_operand:DI 4 "memory_operand" "")) 17746 (clobber (match_scratch 5 ""))] 17747 "reload_completed" 17748 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) 17749 (use (match_dup 2)) 17750 (use (match_dup 3)) 17751 (clobber (match_dup 5))])] 17752 "") 17753 17754(define_insn "fist<mode>2_ceil" 17755 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 17756 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17757 UNSPEC_FIST_CEIL)) 17758 (use (match_operand:HI 2 "memory_operand" "m")) 17759 (use (match_operand:HI 3 "memory_operand" "m"))] 17760 "TARGET_USE_FANCY_MATH_387 17761 && flag_unsafe_math_optimizations" 17762 "* return output_fix_trunc (insn, operands, 0);" 17763 [(set_attr "type" "fistp") 17764 (set_attr "i387_cw" "ceil") 17765 (set_attr "mode" "<MODE>")]) 17766 17767(define_insn "fist<mode>2_ceil_with_temp" 17768 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") 17769 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")] 17770 UNSPEC_FIST_CEIL)) 17771 (use (match_operand:HI 2 "memory_operand" "m,m")) 17772 (use (match_operand:HI 3 "memory_operand" "m,m")) 17773 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))] 17774 "TARGET_USE_FANCY_MATH_387 17775 && flag_unsafe_math_optimizations" 17776 "#" 17777 [(set_attr "type" "fistp") 17778 (set_attr "i387_cw" "ceil") 17779 (set_attr "mode" "<MODE>")]) 17780 17781(define_split 17782 [(set (match_operand:X87MODEI12 0 "register_operand" "") 17783 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17784 UNSPEC_FIST_CEIL)) 17785 (use (match_operand:HI 2 "memory_operand" "")) 17786 (use (match_operand:HI 3 "memory_operand" "")) 17787 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 17788 "reload_completed" 17789 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)] 17790 UNSPEC_FIST_CEIL)) 17791 (use (match_dup 2)) 17792 (use (match_dup 3))]) 17793 (set (match_dup 0) (match_dup 4))] 17794 "") 17795 17796(define_split 17797 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 17798 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17799 UNSPEC_FIST_CEIL)) 17800 (use (match_operand:HI 2 "memory_operand" "")) 17801 (use (match_operand:HI 3 "memory_operand" "")) 17802 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 17803 "reload_completed" 17804 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] 17805 UNSPEC_FIST_CEIL)) 17806 (use (match_dup 2)) 17807 (use (match_dup 3))])] 17808 "") 17809 17810(define_expand "lceil<mode>2" 17811 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") 17812 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] 17813 UNSPEC_FIST_CEIL)) 17814 (clobber (reg:CC FLAGS_REG))])] 17815 "TARGET_USE_FANCY_MATH_387 17816 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17817 && flag_unsafe_math_optimizations" 17818 "") 17819 17820;; Rounding mode control word calculation could clobber FLAGS_REG. 17821(define_insn_and_split "frndintxf2_trunc" 17822 [(set (match_operand:XF 0 "register_operand" "=f") 17823 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17824 UNSPEC_FRNDINT_TRUNC)) 17825 (clobber (reg:CC FLAGS_REG))] 17826 "TARGET_USE_FANCY_MATH_387 17827 && flag_unsafe_math_optimizations 17828 && !(reload_completed || reload_in_progress)" 17829 "#" 17830 "&& 1" 17831 [(const_int 0)] 17832{ 17833 ix86_optimize_mode_switching[I387_TRUNC] = 1; 17834 17835 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17836 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 17837 17838 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1], 17839 operands[2], operands[3])); 17840 DONE; 17841} 17842 [(set_attr "type" "frndint") 17843 (set_attr "i387_cw" "trunc") 17844 (set_attr "mode" "XF")]) 17845 17846(define_insn "frndintxf2_trunc_i387" 17847 [(set (match_operand:XF 0 "register_operand" "=f") 17848 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17849 UNSPEC_FRNDINT_TRUNC)) 17850 (use (match_operand:HI 2 "memory_operand" "m")) 17851 (use (match_operand:HI 3 "memory_operand" "m"))] 17852 "TARGET_USE_FANCY_MATH_387 17853 && flag_unsafe_math_optimizations" 17854 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 17855 [(set_attr "type" "frndint") 17856 (set_attr "i387_cw" "trunc") 17857 (set_attr "mode" "XF")]) 17858 17859(define_expand "btruncxf2" 17860 [(use (match_operand:XF 0 "register_operand" "")) 17861 (use (match_operand:XF 1 "register_operand" ""))] 17862 "TARGET_USE_FANCY_MATH_387 17863 && flag_unsafe_math_optimizations" 17864{ 17865 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1])); 17866 DONE; 17867}) 17868 17869(define_expand "btruncdf2" 17870 [(use (match_operand:DF 0 "register_operand" "")) 17871 (use (match_operand:DF 1 "register_operand" ""))] 17872 "TARGET_USE_FANCY_MATH_387 17873 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17874 && flag_unsafe_math_optimizations" 17875{ 17876 rtx op0 = gen_reg_rtx (XFmode); 17877 rtx op1 = gen_reg_rtx (XFmode); 17878 17879 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17880 emit_insn (gen_frndintxf2_trunc (op0, op1)); 17881 17882 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17883 DONE; 17884}) 17885 17886(define_expand "btruncsf2" 17887 [(use (match_operand:SF 0 "register_operand" "")) 17888 (use (match_operand:SF 1 "register_operand" ""))] 17889 "TARGET_USE_FANCY_MATH_387 17890 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17891 && flag_unsafe_math_optimizations" 17892{ 17893 rtx op0 = gen_reg_rtx (XFmode); 17894 rtx op1 = gen_reg_rtx (XFmode); 17895 17896 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17897 emit_insn (gen_frndintxf2_trunc (op0, op1)); 17898 17899 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17900 DONE; 17901}) 17902 17903;; Rounding mode control word calculation could clobber FLAGS_REG. 17904(define_insn_and_split "frndintxf2_mask_pm" 17905 [(set (match_operand:XF 0 "register_operand" "=f") 17906 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17907 UNSPEC_FRNDINT_MASK_PM)) 17908 (clobber (reg:CC FLAGS_REG))] 17909 "TARGET_USE_FANCY_MATH_387 17910 && flag_unsafe_math_optimizations 17911 && !(reload_completed || reload_in_progress)" 17912 "#" 17913 "&& 1" 17914 [(const_int 0)] 17915{ 17916 ix86_optimize_mode_switching[I387_MASK_PM] = 1; 17917 17918 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17919 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM); 17920 17921 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1], 17922 operands[2], operands[3])); 17923 DONE; 17924} 17925 [(set_attr "type" "frndint") 17926 (set_attr "i387_cw" "mask_pm") 17927 (set_attr "mode" "XF")]) 17928 17929(define_insn "frndintxf2_mask_pm_i387" 17930 [(set (match_operand:XF 0 "register_operand" "=f") 17931 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17932 UNSPEC_FRNDINT_MASK_PM)) 17933 (use (match_operand:HI 2 "memory_operand" "m")) 17934 (use (match_operand:HI 3 "memory_operand" "m"))] 17935 "TARGET_USE_FANCY_MATH_387 17936 && flag_unsafe_math_optimizations" 17937 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2" 17938 [(set_attr "type" "frndint") 17939 (set_attr "i387_cw" "mask_pm") 17940 (set_attr "mode" "XF")]) 17941 17942(define_expand "nearbyintxf2" 17943 [(use (match_operand:XF 0 "register_operand" "")) 17944 (use (match_operand:XF 1 "register_operand" ""))] 17945 "TARGET_USE_FANCY_MATH_387 17946 && flag_unsafe_math_optimizations" 17947{ 17948 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1])); 17949 17950 DONE; 17951}) 17952 17953(define_expand "nearbyintdf2" 17954 [(use (match_operand:DF 0 "register_operand" "")) 17955 (use (match_operand:DF 1 "register_operand" ""))] 17956 "TARGET_USE_FANCY_MATH_387 17957 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17958 && flag_unsafe_math_optimizations" 17959{ 17960 rtx op0 = gen_reg_rtx (XFmode); 17961 rtx op1 = gen_reg_rtx (XFmode); 17962 17963 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17964 emit_insn (gen_frndintxf2_mask_pm (op0, op1)); 17965 17966 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17967 DONE; 17968}) 17969 17970(define_expand "nearbyintsf2" 17971 [(use (match_operand:SF 0 "register_operand" "")) 17972 (use (match_operand:SF 1 "register_operand" ""))] 17973 "TARGET_USE_FANCY_MATH_387 17974 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17975 && flag_unsafe_math_optimizations" 17976{ 17977 rtx op0 = gen_reg_rtx (XFmode); 17978 rtx op1 = gen_reg_rtx (XFmode); 17979 17980 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17981 emit_insn (gen_frndintxf2_mask_pm (op0, op1)); 17982 17983 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17984 DONE; 17985}) 17986 17987 17988;; Block operation instructions 17989 17990(define_insn "cld" 17991 [(set (reg:SI DIRFLAG_REG) (const_int 0))] 17992 "" 17993 "cld" 17994 [(set_attr "type" "cld")]) 17995 17996(define_expand "movmemsi" 17997 [(use (match_operand:BLK 0 "memory_operand" "")) 17998 (use (match_operand:BLK 1 "memory_operand" "")) 17999 (use (match_operand:SI 2 "nonmemory_operand" "")) 18000 (use (match_operand:SI 3 "const_int_operand" ""))] 18001 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS" 18002{ 18003 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3])) 18004 DONE; 18005 else 18006 FAIL; 18007}) 18008 18009(define_expand "movmemdi" 18010 [(use (match_operand:BLK 0 "memory_operand" "")) 18011 (use (match_operand:BLK 1 "memory_operand" "")) 18012 (use (match_operand:DI 2 "nonmemory_operand" "")) 18013 (use (match_operand:DI 3 "const_int_operand" ""))] 18014 "TARGET_64BIT" 18015{ 18016 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3])) 18017 DONE; 18018 else 18019 FAIL; 18020}) 18021 18022;; Most CPUs don't like single string operations 18023;; Handle this case here to simplify previous expander. 18024 18025(define_expand "strmov" 18026 [(set (match_dup 4) (match_operand 3 "memory_operand" "")) 18027 (set (match_operand 1 "memory_operand" "") (match_dup 4)) 18028 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5)) 18029 (clobber (reg:CC FLAGS_REG))]) 18030 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6)) 18031 (clobber (reg:CC FLAGS_REG))])] 18032 "" 18033{ 18034 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1]))); 18035 18036 /* If .md ever supports :P for Pmode, these can be directly 18037 in the pattern above. */ 18038 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust); 18039 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust); 18040 18041 if (TARGET_SINGLE_STRINGOP || optimize_size) 18042 { 18043 emit_insn (gen_strmov_singleop (operands[0], operands[1], 18044 operands[2], operands[3], 18045 operands[5], operands[6])); 18046 DONE; 18047 } 18048 18049 operands[4] = gen_reg_rtx (GET_MODE (operands[1])); 18050}) 18051 18052(define_expand "strmov_singleop" 18053 [(parallel [(set (match_operand 1 "memory_operand" "") 18054 (match_operand 3 "memory_operand" "")) 18055 (set (match_operand 0 "register_operand" "") 18056 (match_operand 4 "" "")) 18057 (set (match_operand 2 "register_operand" "") 18058 (match_operand 5 "" "")) 18059 (use (reg:SI DIRFLAG_REG))])] 18060 "TARGET_SINGLE_STRINGOP || optimize_size" 18061 "") 18062 18063(define_insn "*strmovdi_rex_1" 18064 [(set (mem:DI (match_operand:DI 2 "register_operand" "0")) 18065 (mem:DI (match_operand:DI 3 "register_operand" "1"))) 18066 (set (match_operand:DI 0 "register_operand" "=D") 18067 (plus:DI (match_dup 2) 18068 (const_int 8))) 18069 (set (match_operand:DI 1 "register_operand" "=S") 18070 (plus:DI (match_dup 3) 18071 (const_int 8))) 18072 (use (reg:SI DIRFLAG_REG))] 18073 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18074 "movsq" 18075 [(set_attr "type" "str") 18076 (set_attr "mode" "DI") 18077 (set_attr "memory" "both")]) 18078 18079(define_insn "*strmovsi_1" 18080 [(set (mem:SI (match_operand:SI 2 "register_operand" "0")) 18081 (mem:SI (match_operand:SI 3 "register_operand" "1"))) 18082 (set (match_operand:SI 0 "register_operand" "=D") 18083 (plus:SI (match_dup 2) 18084 (const_int 4))) 18085 (set (match_operand:SI 1 "register_operand" "=S") 18086 (plus:SI (match_dup 3) 18087 (const_int 4))) 18088 (use (reg:SI DIRFLAG_REG))] 18089 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18090 "{movsl|movsd}" 18091 [(set_attr "type" "str") 18092 (set_attr "mode" "SI") 18093 (set_attr "memory" "both")]) 18094 18095(define_insn "*strmovsi_rex_1" 18096 [(set (mem:SI (match_operand:DI 2 "register_operand" "0")) 18097 (mem:SI (match_operand:DI 3 "register_operand" "1"))) 18098 (set (match_operand:DI 0 "register_operand" "=D") 18099 (plus:DI (match_dup 2) 18100 (const_int 4))) 18101 (set (match_operand:DI 1 "register_operand" "=S") 18102 (plus:DI (match_dup 3) 18103 (const_int 4))) 18104 (use (reg:SI DIRFLAG_REG))] 18105 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18106 "{movsl|movsd}" 18107 [(set_attr "type" "str") 18108 (set_attr "mode" "SI") 18109 (set_attr "memory" "both")]) 18110 18111(define_insn "*strmovhi_1" 18112 [(set (mem:HI (match_operand:SI 2 "register_operand" "0")) 18113 (mem:HI (match_operand:SI 3 "register_operand" "1"))) 18114 (set (match_operand:SI 0 "register_operand" "=D") 18115 (plus:SI (match_dup 2) 18116 (const_int 2))) 18117 (set (match_operand:SI 1 "register_operand" "=S") 18118 (plus:SI (match_dup 3) 18119 (const_int 2))) 18120 (use (reg:SI DIRFLAG_REG))] 18121 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18122 "movsw" 18123 [(set_attr "type" "str") 18124 (set_attr "memory" "both") 18125 (set_attr "mode" "HI")]) 18126 18127(define_insn "*strmovhi_rex_1" 18128 [(set (mem:HI (match_operand:DI 2 "register_operand" "0")) 18129 (mem:HI (match_operand:DI 3 "register_operand" "1"))) 18130 (set (match_operand:DI 0 "register_operand" "=D") 18131 (plus:DI (match_dup 2) 18132 (const_int 2))) 18133 (set (match_operand:DI 1 "register_operand" "=S") 18134 (plus:DI (match_dup 3) 18135 (const_int 2))) 18136 (use (reg:SI DIRFLAG_REG))] 18137 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18138 "movsw" 18139 [(set_attr "type" "str") 18140 (set_attr "memory" "both") 18141 (set_attr "mode" "HI")]) 18142 18143(define_insn "*strmovqi_1" 18144 [(set (mem:QI (match_operand:SI 2 "register_operand" "0")) 18145 (mem:QI (match_operand:SI 3 "register_operand" "1"))) 18146 (set (match_operand:SI 0 "register_operand" "=D") 18147 (plus:SI (match_dup 2) 18148 (const_int 1))) 18149 (set (match_operand:SI 1 "register_operand" "=S") 18150 (plus:SI (match_dup 3) 18151 (const_int 1))) 18152 (use (reg:SI DIRFLAG_REG))] 18153 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18154 "movsb" 18155 [(set_attr "type" "str") 18156 (set_attr "memory" "both") 18157 (set_attr "mode" "QI")]) 18158 18159(define_insn "*strmovqi_rex_1" 18160 [(set (mem:QI (match_operand:DI 2 "register_operand" "0")) 18161 (mem:QI (match_operand:DI 3 "register_operand" "1"))) 18162 (set (match_operand:DI 0 "register_operand" "=D") 18163 (plus:DI (match_dup 2) 18164 (const_int 1))) 18165 (set (match_operand:DI 1 "register_operand" "=S") 18166 (plus:DI (match_dup 3) 18167 (const_int 1))) 18168 (use (reg:SI DIRFLAG_REG))] 18169 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18170 "movsb" 18171 [(set_attr "type" "str") 18172 (set_attr "memory" "both") 18173 (set_attr "mode" "QI")]) 18174 18175(define_expand "rep_mov" 18176 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0)) 18177 (set (match_operand 0 "register_operand" "") 18178 (match_operand 5 "" "")) 18179 (set (match_operand 2 "register_operand" "") 18180 (match_operand 6 "" "")) 18181 (set (match_operand 1 "memory_operand" "") 18182 (match_operand 3 "memory_operand" "")) 18183 (use (match_dup 4)) 18184 (use (reg:SI DIRFLAG_REG))])] 18185 "" 18186 "") 18187 18188(define_insn "*rep_movdi_rex64" 18189 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) 18190 (set (match_operand:DI 0 "register_operand" "=D") 18191 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2") 18192 (const_int 3)) 18193 (match_operand:DI 3 "register_operand" "0"))) 18194 (set (match_operand:DI 1 "register_operand" "=S") 18195 (plus:DI (ashift:DI (match_dup 5) (const_int 3)) 18196 (match_operand:DI 4 "register_operand" "1"))) 18197 (set (mem:BLK (match_dup 3)) 18198 (mem:BLK (match_dup 4))) 18199 (use (match_dup 5)) 18200 (use (reg:SI DIRFLAG_REG))] 18201 "TARGET_64BIT" 18202 "{rep\;movsq|rep movsq}" 18203 [(set_attr "type" "str") 18204 (set_attr "prefix_rep" "1") 18205 (set_attr "memory" "both") 18206 (set_attr "mode" "DI")]) 18207 18208(define_insn "*rep_movsi" 18209 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0)) 18210 (set (match_operand:SI 0 "register_operand" "=D") 18211 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2") 18212 (const_int 2)) 18213 (match_operand:SI 3 "register_operand" "0"))) 18214 (set (match_operand:SI 1 "register_operand" "=S") 18215 (plus:SI (ashift:SI (match_dup 5) (const_int 2)) 18216 (match_operand:SI 4 "register_operand" "1"))) 18217 (set (mem:BLK (match_dup 3)) 18218 (mem:BLK (match_dup 4))) 18219 (use (match_dup 5)) 18220 (use (reg:SI DIRFLAG_REG))] 18221 "!TARGET_64BIT" 18222 "{rep\;movsl|rep movsd}" 18223 [(set_attr "type" "str") 18224 (set_attr "prefix_rep" "1") 18225 (set_attr "memory" "both") 18226 (set_attr "mode" "SI")]) 18227 18228(define_insn "*rep_movsi_rex64" 18229 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) 18230 (set (match_operand:DI 0 "register_operand" "=D") 18231 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2") 18232 (const_int 2)) 18233 (match_operand:DI 3 "register_operand" "0"))) 18234 (set (match_operand:DI 1 "register_operand" "=S") 18235 (plus:DI (ashift:DI (match_dup 5) (const_int 2)) 18236 (match_operand:DI 4 "register_operand" "1"))) 18237 (set (mem:BLK (match_dup 3)) 18238 (mem:BLK (match_dup 4))) 18239 (use (match_dup 5)) 18240 (use (reg:SI DIRFLAG_REG))] 18241 "TARGET_64BIT" 18242 "{rep\;movsl|rep movsd}" 18243 [(set_attr "type" "str") 18244 (set_attr "prefix_rep" "1") 18245 (set_attr "memory" "both") 18246 (set_attr "mode" "SI")]) 18247 18248(define_insn "*rep_movqi" 18249 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0)) 18250 (set (match_operand:SI 0 "register_operand" "=D") 18251 (plus:SI (match_operand:SI 3 "register_operand" "0") 18252 (match_operand:SI 5 "register_operand" "2"))) 18253 (set (match_operand:SI 1 "register_operand" "=S") 18254 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5))) 18255 (set (mem:BLK (match_dup 3)) 18256 (mem:BLK (match_dup 4))) 18257 (use (match_dup 5)) 18258 (use (reg:SI DIRFLAG_REG))] 18259 "!TARGET_64BIT" 18260 "{rep\;movsb|rep movsb}" 18261 [(set_attr "type" "str") 18262 (set_attr "prefix_rep" "1") 18263 (set_attr "memory" "both") 18264 (set_attr "mode" "SI")]) 18265 18266(define_insn "*rep_movqi_rex64" 18267 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) 18268 (set (match_operand:DI 0 "register_operand" "=D") 18269 (plus:DI (match_operand:DI 3 "register_operand" "0") 18270 (match_operand:DI 5 "register_operand" "2"))) 18271 (set (match_operand:DI 1 "register_operand" "=S") 18272 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5))) 18273 (set (mem:BLK (match_dup 3)) 18274 (mem:BLK (match_dup 4))) 18275 (use (match_dup 5)) 18276 (use (reg:SI DIRFLAG_REG))] 18277 "TARGET_64BIT" 18278 "{rep\;movsb|rep movsb}" 18279 [(set_attr "type" "str") 18280 (set_attr "prefix_rep" "1") 18281 (set_attr "memory" "both") 18282 (set_attr "mode" "SI")]) 18283 18284(define_expand "setmemsi" 18285 [(use (match_operand:BLK 0 "memory_operand" "")) 18286 (use (match_operand:SI 1 "nonmemory_operand" "")) 18287 (use (match_operand 2 "const_int_operand" "")) 18288 (use (match_operand 3 "const_int_operand" ""))] 18289 "" 18290{ 18291 /* If value to set is not zero, use the library routine. */ 18292 if (operands[2] != const0_rtx) 18293 FAIL; 18294 18295 if (ix86_expand_clrmem (operands[0], operands[1], operands[3])) 18296 DONE; 18297 else 18298 FAIL; 18299}) 18300 18301(define_expand "setmemdi" 18302 [(use (match_operand:BLK 0 "memory_operand" "")) 18303 (use (match_operand:DI 1 "nonmemory_operand" "")) 18304 (use (match_operand 2 "const_int_operand" "")) 18305 (use (match_operand 3 "const_int_operand" ""))] 18306 "TARGET_64BIT" 18307{ 18308 /* If value to set is not zero, use the library routine. */ 18309 if (operands[2] != const0_rtx) 18310 FAIL; 18311 18312 if (ix86_expand_clrmem (operands[0], operands[1], operands[3])) 18313 DONE; 18314 else 18315 FAIL; 18316}) 18317 18318;; Most CPUs don't like single string operations 18319;; Handle this case here to simplify previous expander. 18320 18321(define_expand "strset" 18322 [(set (match_operand 1 "memory_operand" "") 18323 (match_operand 2 "register_operand" "")) 18324 (parallel [(set (match_operand 0 "register_operand" "") 18325 (match_dup 3)) 18326 (clobber (reg:CC FLAGS_REG))])] 18327 "" 18328{ 18329 if (GET_MODE (operands[1]) != GET_MODE (operands[2])) 18330 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0); 18331 18332 /* If .md ever supports :P for Pmode, this can be directly 18333 in the pattern above. */ 18334 operands[3] = gen_rtx_PLUS (Pmode, operands[0], 18335 GEN_INT (GET_MODE_SIZE (GET_MODE 18336 (operands[2])))); 18337 if (TARGET_SINGLE_STRINGOP || optimize_size) 18338 { 18339 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2], 18340 operands[3])); 18341 DONE; 18342 } 18343}) 18344 18345(define_expand "strset_singleop" 18346 [(parallel [(set (match_operand 1 "memory_operand" "") 18347 (match_operand 2 "register_operand" "")) 18348 (set (match_operand 0 "register_operand" "") 18349 (match_operand 3 "" "")) 18350 (use (reg:SI DIRFLAG_REG))])] 18351 "TARGET_SINGLE_STRINGOP || optimize_size" 18352 "") 18353 18354(define_insn "*strsetdi_rex_1" 18355 [(set (mem:DI (match_operand:DI 1 "register_operand" "0")) 18356 (match_operand:DI 2 "register_operand" "a")) 18357 (set (match_operand:DI 0 "register_operand" "=D") 18358 (plus:DI (match_dup 1) 18359 (const_int 8))) 18360 (use (reg:SI DIRFLAG_REG))] 18361 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18362 "stosq" 18363 [(set_attr "type" "str") 18364 (set_attr "memory" "store") 18365 (set_attr "mode" "DI")]) 18366 18367(define_insn "*strsetsi_1" 18368 [(set (mem:SI (match_operand:SI 1 "register_operand" "0")) 18369 (match_operand:SI 2 "register_operand" "a")) 18370 (set (match_operand:SI 0 "register_operand" "=D") 18371 (plus:SI (match_dup 1) 18372 (const_int 4))) 18373 (use (reg:SI DIRFLAG_REG))] 18374 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18375 "{stosl|stosd}" 18376 [(set_attr "type" "str") 18377 (set_attr "memory" "store") 18378 (set_attr "mode" "SI")]) 18379 18380(define_insn "*strsetsi_rex_1" 18381 [(set (mem:SI (match_operand:DI 1 "register_operand" "0")) 18382 (match_operand:SI 2 "register_operand" "a")) 18383 (set (match_operand:DI 0 "register_operand" "=D") 18384 (plus:DI (match_dup 1) 18385 (const_int 4))) 18386 (use (reg:SI DIRFLAG_REG))] 18387 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18388 "{stosl|stosd}" 18389 [(set_attr "type" "str") 18390 (set_attr "memory" "store") 18391 (set_attr "mode" "SI")]) 18392 18393(define_insn "*strsethi_1" 18394 [(set (mem:HI (match_operand:SI 1 "register_operand" "0")) 18395 (match_operand:HI 2 "register_operand" "a")) 18396 (set (match_operand:SI 0 "register_operand" "=D") 18397 (plus:SI (match_dup 1) 18398 (const_int 2))) 18399 (use (reg:SI DIRFLAG_REG))] 18400 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18401 "stosw" 18402 [(set_attr "type" "str") 18403 (set_attr "memory" "store") 18404 (set_attr "mode" "HI")]) 18405 18406(define_insn "*strsethi_rex_1" 18407 [(set (mem:HI (match_operand:DI 1 "register_operand" "0")) 18408 (match_operand:HI 2 "register_operand" "a")) 18409 (set (match_operand:DI 0 "register_operand" "=D") 18410 (plus:DI (match_dup 1) 18411 (const_int 2))) 18412 (use (reg:SI DIRFLAG_REG))] 18413 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18414 "stosw" 18415 [(set_attr "type" "str") 18416 (set_attr "memory" "store") 18417 (set_attr "mode" "HI")]) 18418 18419(define_insn "*strsetqi_1" 18420 [(set (mem:QI (match_operand:SI 1 "register_operand" "0")) 18421 (match_operand:QI 2 "register_operand" "a")) 18422 (set (match_operand:SI 0 "register_operand" "=D") 18423 (plus:SI (match_dup 1) 18424 (const_int 1))) 18425 (use (reg:SI DIRFLAG_REG))] 18426 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18427 "stosb" 18428 [(set_attr "type" "str") 18429 (set_attr "memory" "store") 18430 (set_attr "mode" "QI")]) 18431 18432(define_insn "*strsetqi_rex_1" 18433 [(set (mem:QI (match_operand:DI 1 "register_operand" "0")) 18434 (match_operand:QI 2 "register_operand" "a")) 18435 (set (match_operand:DI 0 "register_operand" "=D") 18436 (plus:DI (match_dup 1) 18437 (const_int 1))) 18438 (use (reg:SI DIRFLAG_REG))] 18439 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18440 "stosb" 18441 [(set_attr "type" "str") 18442 (set_attr "memory" "store") 18443 (set_attr "mode" "QI")]) 18444 18445(define_expand "rep_stos" 18446 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0)) 18447 (set (match_operand 0 "register_operand" "") 18448 (match_operand 4 "" "")) 18449 (set (match_operand 2 "memory_operand" "") (const_int 0)) 18450 (use (match_operand 3 "register_operand" "")) 18451 (use (match_dup 1)) 18452 (use (reg:SI DIRFLAG_REG))])] 18453 "" 18454 "") 18455 18456(define_insn "*rep_stosdi_rex64" 18457 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) 18458 (set (match_operand:DI 0 "register_operand" "=D") 18459 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1") 18460 (const_int 3)) 18461 (match_operand:DI 3 "register_operand" "0"))) 18462 (set (mem:BLK (match_dup 3)) 18463 (const_int 0)) 18464 (use (match_operand:DI 2 "register_operand" "a")) 18465 (use (match_dup 4)) 18466 (use (reg:SI DIRFLAG_REG))] 18467 "TARGET_64BIT" 18468 "{rep\;stosq|rep stosq}" 18469 [(set_attr "type" "str") 18470 (set_attr "prefix_rep" "1") 18471 (set_attr "memory" "store") 18472 (set_attr "mode" "DI")]) 18473 18474(define_insn "*rep_stossi" 18475 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0)) 18476 (set (match_operand:SI 0 "register_operand" "=D") 18477 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1") 18478 (const_int 2)) 18479 (match_operand:SI 3 "register_operand" "0"))) 18480 (set (mem:BLK (match_dup 3)) 18481 (const_int 0)) 18482 (use (match_operand:SI 2 "register_operand" "a")) 18483 (use (match_dup 4)) 18484 (use (reg:SI DIRFLAG_REG))] 18485 "!TARGET_64BIT" 18486 "{rep\;stosl|rep stosd}" 18487 [(set_attr "type" "str") 18488 (set_attr "prefix_rep" "1") 18489 (set_attr "memory" "store") 18490 (set_attr "mode" "SI")]) 18491 18492(define_insn "*rep_stossi_rex64" 18493 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) 18494 (set (match_operand:DI 0 "register_operand" "=D") 18495 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1") 18496 (const_int 2)) 18497 (match_operand:DI 3 "register_operand" "0"))) 18498 (set (mem:BLK (match_dup 3)) 18499 (const_int 0)) 18500 (use (match_operand:SI 2 "register_operand" "a")) 18501 (use (match_dup 4)) 18502 (use (reg:SI DIRFLAG_REG))] 18503 "TARGET_64BIT" 18504 "{rep\;stosl|rep stosd}" 18505 [(set_attr "type" "str") 18506 (set_attr "prefix_rep" "1") 18507 (set_attr "memory" "store") 18508 (set_attr "mode" "SI")]) 18509 18510(define_insn "*rep_stosqi" 18511 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0)) 18512 (set (match_operand:SI 0 "register_operand" "=D") 18513 (plus:SI (match_operand:SI 3 "register_operand" "0") 18514 (match_operand:SI 4 "register_operand" "1"))) 18515 (set (mem:BLK (match_dup 3)) 18516 (const_int 0)) 18517 (use (match_operand:QI 2 "register_operand" "a")) 18518 (use (match_dup 4)) 18519 (use (reg:SI DIRFLAG_REG))] 18520 "!TARGET_64BIT" 18521 "{rep\;stosb|rep stosb}" 18522 [(set_attr "type" "str") 18523 (set_attr "prefix_rep" "1") 18524 (set_attr "memory" "store") 18525 (set_attr "mode" "QI")]) 18526 18527(define_insn "*rep_stosqi_rex64" 18528 [(set (match_operand:DI 1 "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 4 "register_operand" "1"))) 18532 (set (mem:BLK (match_dup 3)) 18533 (const_int 0)) 18534 (use (match_operand:QI 2 "register_operand" "a")) 18535 (use (match_dup 4)) 18536 (use (reg:SI DIRFLAG_REG))] 18537 "TARGET_64BIT" 18538 "{rep\;stosb|rep stosb}" 18539 [(set_attr "type" "str") 18540 (set_attr "prefix_rep" "1") 18541 (set_attr "memory" "store") 18542 (set_attr "mode" "QI")]) 18543 18544(define_expand "cmpstrnsi" 18545 [(set (match_operand:SI 0 "register_operand" "") 18546 (compare:SI (match_operand:BLK 1 "general_operand" "") 18547 (match_operand:BLK 2 "general_operand" ""))) 18548 (use (match_operand 3 "general_operand" "")) 18549 (use (match_operand 4 "immediate_operand" ""))] 18550 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS" 18551{ 18552 rtx addr1, addr2, out, outlow, count, countreg, align; 18553 18554 /* Can't use this if the user has appropriated esi or edi. */ 18555 if (global_regs[4] || global_regs[5]) 18556 FAIL; 18557 18558 out = operands[0]; 18559 if (GET_CODE (out) != REG) 18560 out = gen_reg_rtx (SImode); 18561 18562 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); 18563 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0)); 18564 if (addr1 != XEXP (operands[1], 0)) 18565 operands[1] = replace_equiv_address_nv (operands[1], addr1); 18566 if (addr2 != XEXP (operands[2], 0)) 18567 operands[2] = replace_equiv_address_nv (operands[2], addr2); 18568 18569 count = operands[3]; 18570 countreg = ix86_zero_extend_to_Pmode (count); 18571 18572 /* %%% Iff we are testing strict equality, we can use known alignment 18573 to good advantage. This may be possible with combine, particularly 18574 once cc0 is dead. */ 18575 align = operands[4]; 18576 18577 emit_insn (gen_cld ()); 18578 if (GET_CODE (count) == CONST_INT) 18579 { 18580 if (INTVAL (count) == 0) 18581 { 18582 emit_move_insn (operands[0], const0_rtx); 18583 DONE; 18584 } 18585 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align, 18586 operands[1], operands[2])); 18587 } 18588 else 18589 { 18590 if (TARGET_64BIT) 18591 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg)); 18592 else 18593 emit_insn (gen_cmpsi_1 (countreg, countreg)); 18594 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align, 18595 operands[1], operands[2])); 18596 } 18597 18598 outlow = gen_lowpart (QImode, out); 18599 emit_insn (gen_cmpintqi (outlow)); 18600 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow)); 18601 18602 if (operands[0] != out) 18603 emit_move_insn (operands[0], out); 18604 18605 DONE; 18606}) 18607 18608;; Produce a tri-state integer (-1, 0, 1) from condition codes. 18609 18610(define_expand "cmpintqi" 18611 [(set (match_dup 1) 18612 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 18613 (set (match_dup 2) 18614 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 18615 (parallel [(set (match_operand:QI 0 "register_operand" "") 18616 (minus:QI (match_dup 1) 18617 (match_dup 2))) 18618 (clobber (reg:CC FLAGS_REG))])] 18619 "" 18620 "operands[1] = gen_reg_rtx (QImode); 18621 operands[2] = gen_reg_rtx (QImode);") 18622 18623;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is 18624;; zero. Emit extra code to make sure that a zero-length compare is EQ. 18625 18626(define_expand "cmpstrnqi_nz_1" 18627 [(parallel [(set (reg:CC FLAGS_REG) 18628 (compare:CC (match_operand 4 "memory_operand" "") 18629 (match_operand 5 "memory_operand" ""))) 18630 (use (match_operand 2 "register_operand" "")) 18631 (use (match_operand:SI 3 "immediate_operand" "")) 18632 (use (reg:SI DIRFLAG_REG)) 18633 (clobber (match_operand 0 "register_operand" "")) 18634 (clobber (match_operand 1 "register_operand" "")) 18635 (clobber (match_dup 2))])] 18636 "" 18637 "") 18638 18639(define_insn "*cmpstrnqi_nz_1" 18640 [(set (reg:CC FLAGS_REG) 18641 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0")) 18642 (mem:BLK (match_operand:SI 5 "register_operand" "1")))) 18643 (use (match_operand:SI 6 "register_operand" "2")) 18644 (use (match_operand:SI 3 "immediate_operand" "i")) 18645 (use (reg:SI DIRFLAG_REG)) 18646 (clobber (match_operand:SI 0 "register_operand" "=S")) 18647 (clobber (match_operand:SI 1 "register_operand" "=D")) 18648 (clobber (match_operand:SI 2 "register_operand" "=c"))] 18649 "!TARGET_64BIT" 18650 "repz{\;| }cmpsb" 18651 [(set_attr "type" "str") 18652 (set_attr "mode" "QI") 18653 (set_attr "prefix_rep" "1")]) 18654 18655(define_insn "*cmpstrnqi_nz_rex_1" 18656 [(set (reg:CC FLAGS_REG) 18657 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0")) 18658 (mem:BLK (match_operand:DI 5 "register_operand" "1")))) 18659 (use (match_operand:DI 6 "register_operand" "2")) 18660 (use (match_operand:SI 3 "immediate_operand" "i")) 18661 (use (reg:SI DIRFLAG_REG)) 18662 (clobber (match_operand:DI 0 "register_operand" "=S")) 18663 (clobber (match_operand:DI 1 "register_operand" "=D")) 18664 (clobber (match_operand:DI 2 "register_operand" "=c"))] 18665 "TARGET_64BIT" 18666 "repz{\;| }cmpsb" 18667 [(set_attr "type" "str") 18668 (set_attr "mode" "QI") 18669 (set_attr "prefix_rep" "1")]) 18670 18671;; The same, but the count is not known to not be zero. 18672 18673(define_expand "cmpstrnqi_1" 18674 [(parallel [(set (reg:CC FLAGS_REG) 18675 (if_then_else:CC (ne (match_operand 2 "register_operand" "") 18676 (const_int 0)) 18677 (compare:CC (match_operand 4 "memory_operand" "") 18678 (match_operand 5 "memory_operand" "")) 18679 (const_int 0))) 18680 (use (match_operand:SI 3 "immediate_operand" "")) 18681 (use (reg:CC FLAGS_REG)) 18682 (use (reg:SI DIRFLAG_REG)) 18683 (clobber (match_operand 0 "register_operand" "")) 18684 (clobber (match_operand 1 "register_operand" "")) 18685 (clobber (match_dup 2))])] 18686 "" 18687 "") 18688 18689(define_insn "*cmpstrnqi_1" 18690 [(set (reg:CC FLAGS_REG) 18691 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2") 18692 (const_int 0)) 18693 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0")) 18694 (mem:BLK (match_operand:SI 5 "register_operand" "1"))) 18695 (const_int 0))) 18696 (use (match_operand:SI 3 "immediate_operand" "i")) 18697 (use (reg:CC FLAGS_REG)) 18698 (use (reg:SI DIRFLAG_REG)) 18699 (clobber (match_operand:SI 0 "register_operand" "=S")) 18700 (clobber (match_operand:SI 1 "register_operand" "=D")) 18701 (clobber (match_operand:SI 2 "register_operand" "=c"))] 18702 "!TARGET_64BIT" 18703 "repz{\;| }cmpsb" 18704 [(set_attr "type" "str") 18705 (set_attr "mode" "QI") 18706 (set_attr "prefix_rep" "1")]) 18707 18708(define_insn "*cmpstrnqi_rex_1" 18709 [(set (reg:CC FLAGS_REG) 18710 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2") 18711 (const_int 0)) 18712 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0")) 18713 (mem:BLK (match_operand:DI 5 "register_operand" "1"))) 18714 (const_int 0))) 18715 (use (match_operand:SI 3 "immediate_operand" "i")) 18716 (use (reg:CC FLAGS_REG)) 18717 (use (reg:SI DIRFLAG_REG)) 18718 (clobber (match_operand:DI 0 "register_operand" "=S")) 18719 (clobber (match_operand:DI 1 "register_operand" "=D")) 18720 (clobber (match_operand:DI 2 "register_operand" "=c"))] 18721 "TARGET_64BIT" 18722 "repz{\;| }cmpsb" 18723 [(set_attr "type" "str") 18724 (set_attr "mode" "QI") 18725 (set_attr "prefix_rep" "1")]) 18726 18727(define_expand "strlensi" 18728 [(set (match_operand:SI 0 "register_operand" "") 18729 (unspec:SI [(match_operand:BLK 1 "general_operand" "") 18730 (match_operand:QI 2 "immediate_operand" "") 18731 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))] 18732 "" 18733{ 18734 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) 18735 DONE; 18736 else 18737 FAIL; 18738}) 18739 18740(define_expand "strlendi" 18741 [(set (match_operand:DI 0 "register_operand" "") 18742 (unspec:DI [(match_operand:BLK 1 "general_operand" "") 18743 (match_operand:QI 2 "immediate_operand" "") 18744 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))] 18745 "" 18746{ 18747 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) 18748 DONE; 18749 else 18750 FAIL; 18751}) 18752 18753(define_expand "strlenqi_1" 18754 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" "")) 18755 (use (reg:SI DIRFLAG_REG)) 18756 (clobber (match_operand 1 "register_operand" "")) 18757 (clobber (reg:CC FLAGS_REG))])] 18758 "" 18759 "") 18760 18761(define_insn "*strlenqi_1" 18762 [(set (match_operand:SI 0 "register_operand" "=&c") 18763 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1")) 18764 (match_operand:QI 2 "register_operand" "a") 18765 (match_operand:SI 3 "immediate_operand" "i") 18766 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS)) 18767 (use (reg:SI DIRFLAG_REG)) 18768 (clobber (match_operand:SI 1 "register_operand" "=D")) 18769 (clobber (reg:CC FLAGS_REG))] 18770 "!TARGET_64BIT" 18771 "repnz{\;| }scasb" 18772 [(set_attr "type" "str") 18773 (set_attr "mode" "QI") 18774 (set_attr "prefix_rep" "1")]) 18775 18776(define_insn "*strlenqi_rex_1" 18777 [(set (match_operand:DI 0 "register_operand" "=&c") 18778 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1")) 18779 (match_operand:QI 2 "register_operand" "a") 18780 (match_operand:DI 3 "immediate_operand" "i") 18781 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS)) 18782 (use (reg:SI DIRFLAG_REG)) 18783 (clobber (match_operand:DI 1 "register_operand" "=D")) 18784 (clobber (reg:CC FLAGS_REG))] 18785 "TARGET_64BIT" 18786 "repnz{\;| }scasb" 18787 [(set_attr "type" "str") 18788 (set_attr "mode" "QI") 18789 (set_attr "prefix_rep" "1")]) 18790 18791;; Peephole optimizations to clean up after cmpstrn*. This should be 18792;; handled in combine, but it is not currently up to the task. 18793;; When used for their truth value, the cmpstrn* expanders generate 18794;; code like this: 18795;; 18796;; repz cmpsb 18797;; seta %al 18798;; setb %dl 18799;; cmpb %al, %dl 18800;; jcc label 18801;; 18802;; The intermediate three instructions are unnecessary. 18803 18804;; This one handles cmpstrn*_nz_1... 18805(define_peephole2 18806 [(parallel[ 18807 (set (reg:CC FLAGS_REG) 18808 (compare:CC (mem:BLK (match_operand 4 "register_operand" "")) 18809 (mem:BLK (match_operand 5 "register_operand" "")))) 18810 (use (match_operand 6 "register_operand" "")) 18811 (use (match_operand:SI 3 "immediate_operand" "")) 18812 (use (reg:SI DIRFLAG_REG)) 18813 (clobber (match_operand 0 "register_operand" "")) 18814 (clobber (match_operand 1 "register_operand" "")) 18815 (clobber (match_operand 2 "register_operand" ""))]) 18816 (set (match_operand:QI 7 "register_operand" "") 18817 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 18818 (set (match_operand:QI 8 "register_operand" "") 18819 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 18820 (set (reg FLAGS_REG) 18821 (compare (match_dup 7) (match_dup 8))) 18822 ] 18823 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 18824 [(parallel[ 18825 (set (reg:CC FLAGS_REG) 18826 (compare:CC (mem:BLK (match_dup 4)) 18827 (mem:BLK (match_dup 5)))) 18828 (use (match_dup 6)) 18829 (use (match_dup 3)) 18830 (use (reg:SI DIRFLAG_REG)) 18831 (clobber (match_dup 0)) 18832 (clobber (match_dup 1)) 18833 (clobber (match_dup 2))])] 18834 "") 18835 18836;; ...and this one handles cmpstrn*_1. 18837(define_peephole2 18838 [(parallel[ 18839 (set (reg:CC FLAGS_REG) 18840 (if_then_else:CC (ne (match_operand 6 "register_operand" "") 18841 (const_int 0)) 18842 (compare:CC (mem:BLK (match_operand 4 "register_operand" "")) 18843 (mem:BLK (match_operand 5 "register_operand" ""))) 18844 (const_int 0))) 18845 (use (match_operand:SI 3 "immediate_operand" "")) 18846 (use (reg:CC FLAGS_REG)) 18847 (use (reg:SI DIRFLAG_REG)) 18848 (clobber (match_operand 0 "register_operand" "")) 18849 (clobber (match_operand 1 "register_operand" "")) 18850 (clobber (match_operand 2 "register_operand" ""))]) 18851 (set (match_operand:QI 7 "register_operand" "") 18852 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 18853 (set (match_operand:QI 8 "register_operand" "") 18854 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 18855 (set (reg FLAGS_REG) 18856 (compare (match_dup 7) (match_dup 8))) 18857 ] 18858 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 18859 [(parallel[ 18860 (set (reg:CC FLAGS_REG) 18861 (if_then_else:CC (ne (match_dup 6) 18862 (const_int 0)) 18863 (compare:CC (mem:BLK (match_dup 4)) 18864 (mem:BLK (match_dup 5))) 18865 (const_int 0))) 18866 (use (match_dup 3)) 18867 (use (reg:CC FLAGS_REG)) 18868 (use (reg:SI DIRFLAG_REG)) 18869 (clobber (match_dup 0)) 18870 (clobber (match_dup 1)) 18871 (clobber (match_dup 2))])] 18872 "") 18873 18874 18875 18876;; Conditional move instructions. 18877 18878(define_expand "movdicc" 18879 [(set (match_operand:DI 0 "register_operand" "") 18880 (if_then_else:DI (match_operand 1 "comparison_operator" "") 18881 (match_operand:DI 2 "general_operand" "") 18882 (match_operand:DI 3 "general_operand" "")))] 18883 "TARGET_64BIT" 18884 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 18885 18886(define_insn "x86_movdicc_0_m1_rex64" 18887 [(set (match_operand:DI 0 "register_operand" "=r") 18888 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "") 18889 (const_int -1) 18890 (const_int 0))) 18891 (clobber (reg:CC FLAGS_REG))] 18892 "TARGET_64BIT" 18893 "sbb{q}\t%0, %0" 18894 ; Since we don't have the proper number of operands for an alu insn, 18895 ; fill in all the blanks. 18896 [(set_attr "type" "alu") 18897 (set_attr "pent_pair" "pu") 18898 (set_attr "memory" "none") 18899 (set_attr "imm_disp" "false") 18900 (set_attr "mode" "DI") 18901 (set_attr "length_immediate" "0")]) 18902 18903(define_insn "*movdicc_c_rex64" 18904 [(set (match_operand:DI 0 "register_operand" "=r,r") 18905 (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 18906 [(reg FLAGS_REG) (const_int 0)]) 18907 (match_operand:DI 2 "nonimmediate_operand" "rm,0") 18908 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))] 18909 "TARGET_64BIT && TARGET_CMOVE 18910 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 18911 "@ 18912 cmov%O2%C1\t{%2, %0|%0, %2} 18913 cmov%O2%c1\t{%3, %0|%0, %3}" 18914 [(set_attr "type" "icmov") 18915 (set_attr "mode" "DI")]) 18916 18917(define_expand "movsicc" 18918 [(set (match_operand:SI 0 "register_operand" "") 18919 (if_then_else:SI (match_operand 1 "comparison_operator" "") 18920 (match_operand:SI 2 "general_operand" "") 18921 (match_operand:SI 3 "general_operand" "")))] 18922 "" 18923 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 18924 18925;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing 18926;; the register first winds up with `sbbl $0,reg', which is also weird. 18927;; So just document what we're doing explicitly. 18928 18929(define_insn "x86_movsicc_0_m1" 18930 [(set (match_operand:SI 0 "register_operand" "=r") 18931 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "") 18932 (const_int -1) 18933 (const_int 0))) 18934 (clobber (reg:CC FLAGS_REG))] 18935 "" 18936 "sbb{l}\t%0, %0" 18937 ; Since we don't have the proper number of operands for an alu insn, 18938 ; fill in all the blanks. 18939 [(set_attr "type" "alu") 18940 (set_attr "pent_pair" "pu") 18941 (set_attr "memory" "none") 18942 (set_attr "imm_disp" "false") 18943 (set_attr "mode" "SI") 18944 (set_attr "length_immediate" "0")]) 18945 18946(define_insn "*movsicc_noc" 18947 [(set (match_operand:SI 0 "register_operand" "=r,r") 18948 (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 18949 [(reg FLAGS_REG) (const_int 0)]) 18950 (match_operand:SI 2 "nonimmediate_operand" "rm,0") 18951 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))] 18952 "TARGET_CMOVE 18953 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 18954 "@ 18955 cmov%O2%C1\t{%2, %0|%0, %2} 18956 cmov%O2%c1\t{%3, %0|%0, %3}" 18957 [(set_attr "type" "icmov") 18958 (set_attr "mode" "SI")]) 18959 18960(define_expand "movhicc" 18961 [(set (match_operand:HI 0 "register_operand" "") 18962 (if_then_else:HI (match_operand 1 "comparison_operator" "") 18963 (match_operand:HI 2 "general_operand" "") 18964 (match_operand:HI 3 "general_operand" "")))] 18965 "TARGET_HIMODE_MATH" 18966 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 18967 18968(define_insn "*movhicc_noc" 18969 [(set (match_operand:HI 0 "register_operand" "=r,r") 18970 (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 18971 [(reg FLAGS_REG) (const_int 0)]) 18972 (match_operand:HI 2 "nonimmediate_operand" "rm,0") 18973 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))] 18974 "TARGET_CMOVE 18975 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 18976 "@ 18977 cmov%O2%C1\t{%2, %0|%0, %2} 18978 cmov%O2%c1\t{%3, %0|%0, %3}" 18979 [(set_attr "type" "icmov") 18980 (set_attr "mode" "HI")]) 18981 18982(define_expand "movqicc" 18983 [(set (match_operand:QI 0 "register_operand" "") 18984 (if_then_else:QI (match_operand 1 "comparison_operator" "") 18985 (match_operand:QI 2 "general_operand" "") 18986 (match_operand:QI 3 "general_operand" "")))] 18987 "TARGET_QIMODE_MATH" 18988 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 18989 18990(define_insn_and_split "*movqicc_noc" 18991 [(set (match_operand:QI 0 "register_operand" "=r,r") 18992 (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 18993 [(match_operand 4 "flags_reg_operand" "") 18994 (const_int 0)]) 18995 (match_operand:QI 2 "register_operand" "r,0") 18996 (match_operand:QI 3 "register_operand" "0,r")))] 18997 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL" 18998 "#" 18999 "&& reload_completed" 19000 [(set (match_dup 0) 19001 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) 19002 (match_dup 2) 19003 (match_dup 3)))] 19004 "operands[0] = gen_lowpart (SImode, operands[0]); 19005 operands[2] = gen_lowpart (SImode, operands[2]); 19006 operands[3] = gen_lowpart (SImode, operands[3]);" 19007 [(set_attr "type" "icmov") 19008 (set_attr "mode" "SI")]) 19009 19010(define_expand "movsfcc" 19011 [(set (match_operand:SF 0 "register_operand" "") 19012 (if_then_else:SF (match_operand 1 "comparison_operator" "") 19013 (match_operand:SF 2 "register_operand" "") 19014 (match_operand:SF 3 "register_operand" "")))] 19015 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH" 19016 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") 19017 19018(define_insn "*movsfcc_1_387" 19019 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r") 19020 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 19021 [(reg FLAGS_REG) (const_int 0)]) 19022 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0") 19023 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))] 19024 "TARGET_80387 && TARGET_CMOVE 19025 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19026 "@ 19027 fcmov%F1\t{%2, %0|%0, %2} 19028 fcmov%f1\t{%3, %0|%0, %3} 19029 cmov%O2%C1\t{%2, %0|%0, %2} 19030 cmov%O2%c1\t{%3, %0|%0, %3}" 19031 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 19032 (set_attr "mode" "SF,SF,SI,SI")]) 19033 19034(define_expand "movdfcc" 19035 [(set (match_operand:DF 0 "register_operand" "") 19036 (if_then_else:DF (match_operand 1 "comparison_operator" "") 19037 (match_operand:DF 2 "register_operand" "") 19038 (match_operand:DF 3 "register_operand" "")))] 19039 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)" 19040 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") 19041 19042(define_insn "*movdfcc_1" 19043 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r") 19044 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 19045 [(reg FLAGS_REG) (const_int 0)]) 19046 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") 19047 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] 19048 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 19049 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19050 "@ 19051 fcmov%F1\t{%2, %0|%0, %2} 19052 fcmov%f1\t{%3, %0|%0, %3} 19053 # 19054 #" 19055 [(set_attr "type" "fcmov,fcmov,multi,multi") 19056 (set_attr "mode" "DF")]) 19057 19058(define_insn "*movdfcc_1_rex64" 19059 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r") 19060 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 19061 [(reg FLAGS_REG) (const_int 0)]) 19062 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") 19063 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] 19064 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 19065 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19066 "@ 19067 fcmov%F1\t{%2, %0|%0, %2} 19068 fcmov%f1\t{%3, %0|%0, %3} 19069 cmov%O2%C1\t{%2, %0|%0, %2} 19070 cmov%O2%c1\t{%3, %0|%0, %3}" 19071 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 19072 (set_attr "mode" "DF")]) 19073 19074(define_split 19075 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "") 19076 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 19077 [(match_operand 4 "flags_reg_operand" "") 19078 (const_int 0)]) 19079 (match_operand:DF 2 "nonimmediate_operand" "") 19080 (match_operand:DF 3 "nonimmediate_operand" "")))] 19081 "!TARGET_64BIT && reload_completed" 19082 [(set (match_dup 2) 19083 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) 19084 (match_dup 5) 19085 (match_dup 7))) 19086 (set (match_dup 3) 19087 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) 19088 (match_dup 6) 19089 (match_dup 8)))] 19090 "split_di (operands+2, 1, operands+5, operands+6); 19091 split_di (operands+3, 1, operands+7, operands+8); 19092 split_di (operands, 1, operands+2, operands+3);") 19093 19094(define_expand "movxfcc" 19095 [(set (match_operand:XF 0 "register_operand" "") 19096 (if_then_else:XF (match_operand 1 "comparison_operator" "") 19097 (match_operand:XF 2 "register_operand" "") 19098 (match_operand:XF 3 "register_operand" "")))] 19099 "TARGET_80387 && TARGET_CMOVE" 19100 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") 19101 19102(define_insn "*movxfcc_1" 19103 [(set (match_operand:XF 0 "register_operand" "=f,f") 19104 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 19105 [(reg FLAGS_REG) (const_int 0)]) 19106 (match_operand:XF 2 "register_operand" "f,0") 19107 (match_operand:XF 3 "register_operand" "0,f")))] 19108 "TARGET_80387 && TARGET_CMOVE" 19109 "@ 19110 fcmov%F1\t{%2, %0|%0, %2} 19111 fcmov%f1\t{%3, %0|%0, %3}" 19112 [(set_attr "type" "fcmov") 19113 (set_attr "mode" "XF")]) 19114 19115;; These versions of the min/max patterns are intentionally ignorant of 19116;; their behavior wrt -0.0 and NaN (via the commutative operand mark). 19117;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator 19118;; are undefined in this condition, we're certain this is correct. 19119 19120(define_insn "sminsf3" 19121 [(set (match_operand:SF 0 "register_operand" "=x") 19122 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0") 19123 (match_operand:SF 2 "nonimmediate_operand" "xm")))] 19124 "TARGET_SSE_MATH" 19125 "minss\t{%2, %0|%0, %2}" 19126 [(set_attr "type" "sseadd") 19127 (set_attr "mode" "SF")]) 19128 19129(define_insn "smaxsf3" 19130 [(set (match_operand:SF 0 "register_operand" "=x") 19131 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0") 19132 (match_operand:SF 2 "nonimmediate_operand" "xm")))] 19133 "TARGET_SSE_MATH" 19134 "maxss\t{%2, %0|%0, %2}" 19135 [(set_attr "type" "sseadd") 19136 (set_attr "mode" "SF")]) 19137 19138(define_insn "smindf3" 19139 [(set (match_operand:DF 0 "register_operand" "=x") 19140 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0") 19141 (match_operand:DF 2 "nonimmediate_operand" "xm")))] 19142 "TARGET_SSE2 && TARGET_SSE_MATH" 19143 "minsd\t{%2, %0|%0, %2}" 19144 [(set_attr "type" "sseadd") 19145 (set_attr "mode" "DF")]) 19146 19147(define_insn "smaxdf3" 19148 [(set (match_operand:DF 0 "register_operand" "=x") 19149 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0") 19150 (match_operand:DF 2 "nonimmediate_operand" "xm")))] 19151 "TARGET_SSE2 && TARGET_SSE_MATH" 19152 "maxsd\t{%2, %0|%0, %2}" 19153 [(set_attr "type" "sseadd") 19154 (set_attr "mode" "DF")]) 19155 19156;; These versions of the min/max patterns implement exactly the operations 19157;; min = (op1 < op2 ? op1 : op2) 19158;; max = (!(op1 < op2) ? op1 : op2) 19159;; Their operands are not commutative, and thus they may be used in the 19160;; presence of -0.0 and NaN. 19161 19162(define_insn "*ieee_sminsf3" 19163 [(set (match_operand:SF 0 "register_operand" "=x") 19164 (unspec:SF [(match_operand:SF 1 "register_operand" "0") 19165 (match_operand:SF 2 "nonimmediate_operand" "xm")] 19166 UNSPEC_IEEE_MIN))] 19167 "TARGET_SSE_MATH" 19168 "minss\t{%2, %0|%0, %2}" 19169 [(set_attr "type" "sseadd") 19170 (set_attr "mode" "SF")]) 19171 19172(define_insn "*ieee_smaxsf3" 19173 [(set (match_operand:SF 0 "register_operand" "=x") 19174 (unspec:SF [(match_operand:SF 1 "register_operand" "0") 19175 (match_operand:SF 2 "nonimmediate_operand" "xm")] 19176 UNSPEC_IEEE_MAX))] 19177 "TARGET_SSE_MATH" 19178 "maxss\t{%2, %0|%0, %2}" 19179 [(set_attr "type" "sseadd") 19180 (set_attr "mode" "SF")]) 19181 19182(define_insn "*ieee_smindf3" 19183 [(set (match_operand:DF 0 "register_operand" "=x") 19184 (unspec:DF [(match_operand:DF 1 "register_operand" "0") 19185 (match_operand:DF 2 "nonimmediate_operand" "xm")] 19186 UNSPEC_IEEE_MIN))] 19187 "TARGET_SSE2 && TARGET_SSE_MATH" 19188 "minsd\t{%2, %0|%0, %2}" 19189 [(set_attr "type" "sseadd") 19190 (set_attr "mode" "DF")]) 19191 19192(define_insn "*ieee_smaxdf3" 19193 [(set (match_operand:DF 0 "register_operand" "=x") 19194 (unspec:DF [(match_operand:DF 1 "register_operand" "0") 19195 (match_operand:DF 2 "nonimmediate_operand" "xm")] 19196 UNSPEC_IEEE_MAX))] 19197 "TARGET_SSE2 && TARGET_SSE_MATH" 19198 "maxsd\t{%2, %0|%0, %2}" 19199 [(set_attr "type" "sseadd") 19200 (set_attr "mode" "DF")]) 19201 19202;; Make two stack loads independent: 19203;; fld aa fld aa 19204;; fld %st(0) -> fld bb 19205;; fmul bb fmul %st(1), %st 19206;; 19207;; Actually we only match the last two instructions for simplicity. 19208(define_peephole2 19209 [(set (match_operand 0 "fp_register_operand" "") 19210 (match_operand 1 "fp_register_operand" "")) 19211 (set (match_dup 0) 19212 (match_operator 2 "binary_fp_operator" 19213 [(match_dup 0) 19214 (match_operand 3 "memory_operand" "")]))] 19215 "REGNO (operands[0]) != REGNO (operands[1])" 19216 [(set (match_dup 0) (match_dup 3)) 19217 (set (match_dup 0) (match_dup 4))] 19218 19219 ;; The % modifier is not operational anymore in peephole2's, so we have to 19220 ;; swap the operands manually in the case of addition and multiplication. 19221 "if (COMMUTATIVE_ARITH_P (operands[2])) 19222 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), 19223 operands[0], operands[1]); 19224 else 19225 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), 19226 operands[1], operands[0]);") 19227 19228;; Conditional addition patterns 19229(define_expand "addqicc" 19230 [(match_operand:QI 0 "register_operand" "") 19231 (match_operand 1 "comparison_operator" "") 19232 (match_operand:QI 2 "register_operand" "") 19233 (match_operand:QI 3 "const_int_operand" "")] 19234 "" 19235 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 19236 19237(define_expand "addhicc" 19238 [(match_operand:HI 0 "register_operand" "") 19239 (match_operand 1 "comparison_operator" "") 19240 (match_operand:HI 2 "register_operand" "") 19241 (match_operand:HI 3 "const_int_operand" "")] 19242 "" 19243 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 19244 19245(define_expand "addsicc" 19246 [(match_operand:SI 0 "register_operand" "") 19247 (match_operand 1 "comparison_operator" "") 19248 (match_operand:SI 2 "register_operand" "") 19249 (match_operand:SI 3 "const_int_operand" "")] 19250 "" 19251 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 19252 19253(define_expand "adddicc" 19254 [(match_operand:DI 0 "register_operand" "") 19255 (match_operand 1 "comparison_operator" "") 19256 (match_operand:DI 2 "register_operand" "") 19257 (match_operand:DI 3 "const_int_operand" "")] 19258 "TARGET_64BIT" 19259 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 19260 19261 19262;; Misc patterns (?) 19263 19264;; This pattern exists to put a dependency on all ebp-based memory accesses. 19265;; Otherwise there will be nothing to keep 19266;; 19267;; [(set (reg ebp) (reg esp))] 19268;; [(set (reg esp) (plus (reg esp) (const_int -160000))) 19269;; (clobber (eflags)] 19270;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))] 19271;; 19272;; in proper program order. 19273(define_insn "pro_epilogue_adjust_stack_1" 19274 [(set (match_operand:SI 0 "register_operand" "=r,r") 19275 (plus:SI (match_operand:SI 1 "register_operand" "0,r") 19276 (match_operand:SI 2 "immediate_operand" "i,i"))) 19277 (clobber (reg:CC FLAGS_REG)) 19278 (clobber (mem:BLK (scratch)))] 19279 "!TARGET_64BIT" 19280{ 19281 switch (get_attr_type (insn)) 19282 { 19283 case TYPE_IMOV: 19284 return "mov{l}\t{%1, %0|%0, %1}"; 19285 19286 case TYPE_ALU: 19287 if (GET_CODE (operands[2]) == CONST_INT 19288 && (INTVAL (operands[2]) == 128 19289 || (INTVAL (operands[2]) < 0 19290 && INTVAL (operands[2]) != -128))) 19291 { 19292 operands[2] = GEN_INT (-INTVAL (operands[2])); 19293 return "sub{l}\t{%2, %0|%0, %2}"; 19294 } 19295 return "add{l}\t{%2, %0|%0, %2}"; 19296 19297 case TYPE_LEA: 19298 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 19299 return "lea{l}\t{%a2, %0|%0, %a2}"; 19300 19301 default: 19302 gcc_unreachable (); 19303 } 19304} 19305 [(set (attr "type") 19306 (cond [(eq_attr "alternative" "0") 19307 (const_string "alu") 19308 (match_operand:SI 2 "const0_operand" "") 19309 (const_string "imov") 19310 ] 19311 (const_string "lea"))) 19312 (set_attr "mode" "SI")]) 19313 19314(define_insn "pro_epilogue_adjust_stack_rex64" 19315 [(set (match_operand:DI 0 "register_operand" "=r,r") 19316 (plus:DI (match_operand:DI 1 "register_operand" "0,r") 19317 (match_operand:DI 2 "x86_64_immediate_operand" "e,e"))) 19318 (clobber (reg:CC FLAGS_REG)) 19319 (clobber (mem:BLK (scratch)))] 19320 "TARGET_64BIT" 19321{ 19322 switch (get_attr_type (insn)) 19323 { 19324 case TYPE_IMOV: 19325 return "mov{q}\t{%1, %0|%0, %1}"; 19326 19327 case TYPE_ALU: 19328 if (GET_CODE (operands[2]) == CONST_INT 19329 /* Avoid overflows. */ 19330 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 19331 && (INTVAL (operands[2]) == 128 19332 || (INTVAL (operands[2]) < 0 19333 && INTVAL (operands[2]) != -128))) 19334 { 19335 operands[2] = GEN_INT (-INTVAL (operands[2])); 19336 return "sub{q}\t{%2, %0|%0, %2}"; 19337 } 19338 return "add{q}\t{%2, %0|%0, %2}"; 19339 19340 case TYPE_LEA: 19341 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 19342 return "lea{q}\t{%a2, %0|%0, %a2}"; 19343 19344 default: 19345 gcc_unreachable (); 19346 } 19347} 19348 [(set (attr "type") 19349 (cond [(eq_attr "alternative" "0") 19350 (const_string "alu") 19351 (match_operand:DI 2 "const0_operand" "") 19352 (const_string "imov") 19353 ] 19354 (const_string "lea"))) 19355 (set_attr "mode" "DI")]) 19356 19357(define_insn "pro_epilogue_adjust_stack_rex64_2" 19358 [(set (match_operand:DI 0 "register_operand" "=r,r") 19359 (plus:DI (match_operand:DI 1 "register_operand" "0,r") 19360 (match_operand:DI 3 "immediate_operand" "i,i"))) 19361 (use (match_operand:DI 2 "register_operand" "r,r")) 19362 (clobber (reg:CC FLAGS_REG)) 19363 (clobber (mem:BLK (scratch)))] 19364 "TARGET_64BIT" 19365{ 19366 switch (get_attr_type (insn)) 19367 { 19368 case TYPE_ALU: 19369 return "add{q}\t{%2, %0|%0, %2}"; 19370 19371 case TYPE_LEA: 19372 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]); 19373 return "lea{q}\t{%a2, %0|%0, %a2}"; 19374 19375 default: 19376 gcc_unreachable (); 19377 } 19378} 19379 [(set_attr "type" "alu,lea") 19380 (set_attr "mode" "DI")]) 19381 19382(define_expand "allocate_stack_worker" 19383 [(match_operand:SI 0 "register_operand" "")] 19384 "TARGET_STACK_PROBE" 19385{ 19386 if (reload_completed) 19387 { 19388 if (TARGET_64BIT) 19389 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0])); 19390 else 19391 emit_insn (gen_allocate_stack_worker_postreload (operands[0])); 19392 } 19393 else 19394 { 19395 if (TARGET_64BIT) 19396 emit_insn (gen_allocate_stack_worker_rex64 (operands[0])); 19397 else 19398 emit_insn (gen_allocate_stack_worker_1 (operands[0])); 19399 } 19400 DONE; 19401}) 19402 19403(define_insn "allocate_stack_worker_1" 19404 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")] 19405 UNSPECV_STACK_PROBE) 19406 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0))) 19407 (clobber (match_scratch:SI 1 "=0")) 19408 (clobber (reg:CC FLAGS_REG))] 19409 "!TARGET_64BIT && TARGET_STACK_PROBE" 19410 "call\t__alloca" 19411 [(set_attr "type" "multi") 19412 (set_attr "length" "5")]) 19413 19414(define_expand "allocate_stack_worker_postreload" 19415 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")] 19416 UNSPECV_STACK_PROBE) 19417 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0))) 19418 (clobber (match_dup 0)) 19419 (clobber (reg:CC FLAGS_REG))])] 19420 "" 19421 "") 19422 19423(define_insn "allocate_stack_worker_rex64" 19424 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")] 19425 UNSPECV_STACK_PROBE) 19426 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0))) 19427 (clobber (match_scratch:DI 1 "=0")) 19428 (clobber (reg:CC FLAGS_REG))] 19429 "TARGET_64BIT && TARGET_STACK_PROBE" 19430 "call\t__alloca" 19431 [(set_attr "type" "multi") 19432 (set_attr "length" "5")]) 19433 19434(define_expand "allocate_stack_worker_rex64_postreload" 19435 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")] 19436 UNSPECV_STACK_PROBE) 19437 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0))) 19438 (clobber (match_dup 0)) 19439 (clobber (reg:CC FLAGS_REG))])] 19440 "" 19441 "") 19442 19443(define_expand "allocate_stack" 19444 [(parallel [(set (match_operand:SI 0 "register_operand" "=r") 19445 (minus:SI (reg:SI SP_REG) 19446 (match_operand:SI 1 "general_operand" ""))) 19447 (clobber (reg:CC FLAGS_REG))]) 19448 (parallel [(set (reg:SI SP_REG) 19449 (minus:SI (reg:SI SP_REG) (match_dup 1))) 19450 (clobber (reg:CC FLAGS_REG))])] 19451 "TARGET_STACK_PROBE" 19452{ 19453#ifdef CHECK_STACK_LIMIT 19454 if (GET_CODE (operands[1]) == CONST_INT 19455 && INTVAL (operands[1]) < CHECK_STACK_LIMIT) 19456 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, 19457 operands[1])); 19458 else 19459#endif 19460 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode, 19461 operands[1]))); 19462 19463 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 19464 DONE; 19465}) 19466 19467(define_expand "builtin_setjmp_receiver" 19468 [(label_ref (match_operand 0 "" ""))] 19469 "!TARGET_64BIT && flag_pic" 19470{ 19471 if (TARGET_MACHO) 19472 { 19473 rtx xops[3]; 19474 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM); 19475 rtx label_rtx = gen_label_rtx (); 19476 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx)); 19477 xops[0] = xops[1] = picreg; 19478 xops[2] = gen_rtx_CONST (SImode, 19479 gen_rtx_MINUS (SImode, 19480 gen_rtx_LABEL_REF (SImode, label_rtx), 19481 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME))); 19482 ix86_expand_binary_operator (MINUS, SImode, xops); 19483 } 19484 else 19485 emit_insn (gen_set_got (pic_offset_table_rtx)); 19486 DONE; 19487}) 19488 19489;; Avoid redundant prefixes by splitting HImode arithmetic to SImode. 19490 19491(define_split 19492 [(set (match_operand 0 "register_operand" "") 19493 (match_operator 3 "promotable_binary_operator" 19494 [(match_operand 1 "register_operand" "") 19495 (match_operand 2 "aligned_operand" "")])) 19496 (clobber (reg:CC FLAGS_REG))] 19497 "! TARGET_PARTIAL_REG_STALL && reload_completed 19498 && ((GET_MODE (operands[0]) == HImode 19499 && ((!optimize_size && !TARGET_FAST_PREFIX) 19500 /* ??? next two lines just !satisfies_constraint_K (...) */ 19501 || GET_CODE (operands[2]) != CONST_INT 19502 || satisfies_constraint_K (operands[2]))) 19503 || (GET_MODE (operands[0]) == QImode 19504 && (TARGET_PROMOTE_QImode || optimize_size)))" 19505 [(parallel [(set (match_dup 0) 19506 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 19507 (clobber (reg:CC FLAGS_REG))])] 19508 "operands[0] = gen_lowpart (SImode, operands[0]); 19509 operands[1] = gen_lowpart (SImode, operands[1]); 19510 if (GET_CODE (operands[3]) != ASHIFT) 19511 operands[2] = gen_lowpart (SImode, operands[2]); 19512 PUT_MODE (operands[3], SImode);") 19513 19514; Promote the QImode tests, as i386 has encoding of the AND 19515; instruction with 32-bit sign-extended immediate and thus the 19516; instruction size is unchanged, except in the %eax case for 19517; which it is increased by one byte, hence the ! optimize_size. 19518(define_split 19519 [(set (match_operand 0 "flags_reg_operand" "") 19520 (match_operator 2 "compare_operator" 19521 [(and (match_operand 3 "aligned_operand" "") 19522 (match_operand 4 "const_int_operand" "")) 19523 (const_int 0)])) 19524 (set (match_operand 1 "register_operand" "") 19525 (and (match_dup 3) (match_dup 4)))] 19526 "! TARGET_PARTIAL_REG_STALL && reload_completed 19527 /* Ensure that the operand will remain sign-extended immediate. */ 19528 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode) 19529 && ! optimize_size 19530 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX) 19531 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))" 19532 [(parallel [(set (match_dup 0) 19533 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4)) 19534 (const_int 0)])) 19535 (set (match_dup 1) 19536 (and:SI (match_dup 3) (match_dup 4)))])] 19537{ 19538 operands[4] 19539 = gen_int_mode (INTVAL (operands[4]) 19540 & GET_MODE_MASK (GET_MODE (operands[1])), SImode); 19541 operands[1] = gen_lowpart (SImode, operands[1]); 19542 operands[3] = gen_lowpart (SImode, operands[3]); 19543}) 19544 19545; Don't promote the QImode tests, as i386 doesn't have encoding of 19546; the TEST instruction with 32-bit sign-extended immediate and thus 19547; the instruction size would at least double, which is not what we 19548; want even with ! optimize_size. 19549(define_split 19550 [(set (match_operand 0 "flags_reg_operand" "") 19551 (match_operator 1 "compare_operator" 19552 [(and (match_operand:HI 2 "aligned_operand" "") 19553 (match_operand:HI 3 "const_int_operand" "")) 19554 (const_int 0)]))] 19555 "! TARGET_PARTIAL_REG_STALL && reload_completed 19556 /* Ensure that the operand will remain sign-extended immediate. */ 19557 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode) 19558 && ! TARGET_FAST_PREFIX 19559 && ! optimize_size" 19560 [(set (match_dup 0) 19561 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 19562 (const_int 0)]))] 19563{ 19564 operands[3] 19565 = gen_int_mode (INTVAL (operands[3]) 19566 & GET_MODE_MASK (GET_MODE (operands[2])), SImode); 19567 operands[2] = gen_lowpart (SImode, operands[2]); 19568}) 19569 19570(define_split 19571 [(set (match_operand 0 "register_operand" "") 19572 (neg (match_operand 1 "register_operand" ""))) 19573 (clobber (reg:CC FLAGS_REG))] 19574 "! TARGET_PARTIAL_REG_STALL && reload_completed 19575 && (GET_MODE (operands[0]) == HImode 19576 || (GET_MODE (operands[0]) == QImode 19577 && (TARGET_PROMOTE_QImode || optimize_size)))" 19578 [(parallel [(set (match_dup 0) 19579 (neg:SI (match_dup 1))) 19580 (clobber (reg:CC FLAGS_REG))])] 19581 "operands[0] = gen_lowpart (SImode, operands[0]); 19582 operands[1] = gen_lowpart (SImode, operands[1]);") 19583 19584(define_split 19585 [(set (match_operand 0 "register_operand" "") 19586 (not (match_operand 1 "register_operand" "")))] 19587 "! TARGET_PARTIAL_REG_STALL && reload_completed 19588 && (GET_MODE (operands[0]) == HImode 19589 || (GET_MODE (operands[0]) == QImode 19590 && (TARGET_PROMOTE_QImode || optimize_size)))" 19591 [(set (match_dup 0) 19592 (not:SI (match_dup 1)))] 19593 "operands[0] = gen_lowpart (SImode, operands[0]); 19594 operands[1] = gen_lowpart (SImode, operands[1]);") 19595 19596(define_split 19597 [(set (match_operand 0 "register_operand" "") 19598 (if_then_else (match_operator 1 "comparison_operator" 19599 [(reg FLAGS_REG) (const_int 0)]) 19600 (match_operand 2 "register_operand" "") 19601 (match_operand 3 "register_operand" "")))] 19602 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE 19603 && (GET_MODE (operands[0]) == HImode 19604 || (GET_MODE (operands[0]) == QImode 19605 && (TARGET_PROMOTE_QImode || optimize_size)))" 19606 [(set (match_dup 0) 19607 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))] 19608 "operands[0] = gen_lowpart (SImode, operands[0]); 19609 operands[2] = gen_lowpart (SImode, operands[2]); 19610 operands[3] = gen_lowpart (SImode, operands[3]);") 19611 19612 19613;; RTL Peephole optimizations, run before sched2. These primarily look to 19614;; transform a complex memory operation into two memory to register operations. 19615 19616;; Don't push memory operands 19617(define_peephole2 19618 [(set (match_operand:SI 0 "push_operand" "") 19619 (match_operand:SI 1 "memory_operand" "")) 19620 (match_scratch:SI 2 "r")] 19621 "!optimize_size && !TARGET_PUSH_MEMORY 19622 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19623 [(set (match_dup 2) (match_dup 1)) 19624 (set (match_dup 0) (match_dup 2))] 19625 "") 19626 19627(define_peephole2 19628 [(set (match_operand:DI 0 "push_operand" "") 19629 (match_operand:DI 1 "memory_operand" "")) 19630 (match_scratch:DI 2 "r")] 19631 "!optimize_size && !TARGET_PUSH_MEMORY 19632 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19633 [(set (match_dup 2) (match_dup 1)) 19634 (set (match_dup 0) (match_dup 2))] 19635 "") 19636 19637;; We need to handle SFmode only, because DFmode and XFmode is split to 19638;; SImode pushes. 19639(define_peephole2 19640 [(set (match_operand:SF 0 "push_operand" "") 19641 (match_operand:SF 1 "memory_operand" "")) 19642 (match_scratch:SF 2 "r")] 19643 "!optimize_size && !TARGET_PUSH_MEMORY 19644 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19645 [(set (match_dup 2) (match_dup 1)) 19646 (set (match_dup 0) (match_dup 2))] 19647 "") 19648 19649(define_peephole2 19650 [(set (match_operand:HI 0 "push_operand" "") 19651 (match_operand:HI 1 "memory_operand" "")) 19652 (match_scratch:HI 2 "r")] 19653 "!optimize_size && !TARGET_PUSH_MEMORY 19654 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19655 [(set (match_dup 2) (match_dup 1)) 19656 (set (match_dup 0) (match_dup 2))] 19657 "") 19658 19659(define_peephole2 19660 [(set (match_operand:QI 0 "push_operand" "") 19661 (match_operand:QI 1 "memory_operand" "")) 19662 (match_scratch:QI 2 "q")] 19663 "!optimize_size && !TARGET_PUSH_MEMORY 19664 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19665 [(set (match_dup 2) (match_dup 1)) 19666 (set (match_dup 0) (match_dup 2))] 19667 "") 19668 19669;; Don't move an immediate directly to memory when the instruction 19670;; gets too big. 19671(define_peephole2 19672 [(match_scratch:SI 1 "r") 19673 (set (match_operand:SI 0 "memory_operand" "") 19674 (const_int 0))] 19675 "! optimize_size 19676 && ! TARGET_USE_MOV0 19677 && TARGET_SPLIT_LONG_MOVES 19678 && get_attr_length (insn) >= ix86_cost->large_insn 19679 && peep2_regno_dead_p (0, FLAGS_REG)" 19680 [(parallel [(set (match_dup 1) (const_int 0)) 19681 (clobber (reg:CC FLAGS_REG))]) 19682 (set (match_dup 0) (match_dup 1))] 19683 "") 19684 19685(define_peephole2 19686 [(match_scratch:HI 1 "r") 19687 (set (match_operand:HI 0 "memory_operand" "") 19688 (const_int 0))] 19689 "! optimize_size 19690 && ! TARGET_USE_MOV0 19691 && TARGET_SPLIT_LONG_MOVES 19692 && get_attr_length (insn) >= ix86_cost->large_insn 19693 && peep2_regno_dead_p (0, FLAGS_REG)" 19694 [(parallel [(set (match_dup 2) (const_int 0)) 19695 (clobber (reg:CC FLAGS_REG))]) 19696 (set (match_dup 0) (match_dup 1))] 19697 "operands[2] = gen_lowpart (SImode, operands[1]);") 19698 19699(define_peephole2 19700 [(match_scratch:QI 1 "q") 19701 (set (match_operand:QI 0 "memory_operand" "") 19702 (const_int 0))] 19703 "! optimize_size 19704 && ! TARGET_USE_MOV0 19705 && TARGET_SPLIT_LONG_MOVES 19706 && get_attr_length (insn) >= ix86_cost->large_insn 19707 && peep2_regno_dead_p (0, FLAGS_REG)" 19708 [(parallel [(set (match_dup 2) (const_int 0)) 19709 (clobber (reg:CC FLAGS_REG))]) 19710 (set (match_dup 0) (match_dup 1))] 19711 "operands[2] = gen_lowpart (SImode, operands[1]);") 19712 19713(define_peephole2 19714 [(match_scratch:SI 2 "r") 19715 (set (match_operand:SI 0 "memory_operand" "") 19716 (match_operand:SI 1 "immediate_operand" ""))] 19717 "! optimize_size 19718 && get_attr_length (insn) >= ix86_cost->large_insn 19719 && TARGET_SPLIT_LONG_MOVES" 19720 [(set (match_dup 2) (match_dup 1)) 19721 (set (match_dup 0) (match_dup 2))] 19722 "") 19723 19724(define_peephole2 19725 [(match_scratch:HI 2 "r") 19726 (set (match_operand:HI 0 "memory_operand" "") 19727 (match_operand:HI 1 "immediate_operand" ""))] 19728 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn 19729 && TARGET_SPLIT_LONG_MOVES" 19730 [(set (match_dup 2) (match_dup 1)) 19731 (set (match_dup 0) (match_dup 2))] 19732 "") 19733 19734(define_peephole2 19735 [(match_scratch:QI 2 "q") 19736 (set (match_operand:QI 0 "memory_operand" "") 19737 (match_operand:QI 1 "immediate_operand" ""))] 19738 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn 19739 && TARGET_SPLIT_LONG_MOVES" 19740 [(set (match_dup 2) (match_dup 1)) 19741 (set (match_dup 0) (match_dup 2))] 19742 "") 19743 19744;; Don't compare memory with zero, load and use a test instead. 19745(define_peephole2 19746 [(set (match_operand 0 "flags_reg_operand" "") 19747 (match_operator 1 "compare_operator" 19748 [(match_operand:SI 2 "memory_operand" "") 19749 (const_int 0)])) 19750 (match_scratch:SI 3 "r")] 19751 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size" 19752 [(set (match_dup 3) (match_dup 2)) 19753 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))] 19754 "") 19755 19756;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 19757;; Don't split NOTs with a displacement operand, because resulting XOR 19758;; will not be pairable anyway. 19759;; 19760;; On AMD K6, NOT is vector decoded with memory operand that cannot be 19761;; represented using a modRM byte. The XOR replacement is long decoded, 19762;; so this split helps here as well. 19763;; 19764;; Note: Can't do this as a regular split because we can't get proper 19765;; lifetime information then. 19766 19767(define_peephole2 19768 [(set (match_operand:SI 0 "nonimmediate_operand" "") 19769 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))] 19770 "!optimize_size 19771 && peep2_regno_dead_p (0, FLAGS_REG) 19772 && ((TARGET_PENTIUM 19773 && (GET_CODE (operands[0]) != MEM 19774 || !memory_displacement_operand (operands[0], SImode))) 19775 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))" 19776 [(parallel [(set (match_dup 0) 19777 (xor:SI (match_dup 1) (const_int -1))) 19778 (clobber (reg:CC FLAGS_REG))])] 19779 "") 19780 19781(define_peephole2 19782 [(set (match_operand:HI 0 "nonimmediate_operand" "") 19783 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))] 19784 "!optimize_size 19785 && peep2_regno_dead_p (0, FLAGS_REG) 19786 && ((TARGET_PENTIUM 19787 && (GET_CODE (operands[0]) != MEM 19788 || !memory_displacement_operand (operands[0], HImode))) 19789 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))" 19790 [(parallel [(set (match_dup 0) 19791 (xor:HI (match_dup 1) (const_int -1))) 19792 (clobber (reg:CC FLAGS_REG))])] 19793 "") 19794 19795(define_peephole2 19796 [(set (match_operand:QI 0 "nonimmediate_operand" "") 19797 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))] 19798 "!optimize_size 19799 && peep2_regno_dead_p (0, FLAGS_REG) 19800 && ((TARGET_PENTIUM 19801 && (GET_CODE (operands[0]) != MEM 19802 || !memory_displacement_operand (operands[0], QImode))) 19803 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))" 19804 [(parallel [(set (match_dup 0) 19805 (xor:QI (match_dup 1) (const_int -1))) 19806 (clobber (reg:CC FLAGS_REG))])] 19807 "") 19808 19809;; Non pairable "test imm, reg" instructions can be translated to 19810;; "and imm, reg" if reg dies. The "and" form is also shorter (one 19811;; byte opcode instead of two, have a short form for byte operands), 19812;; so do it for other CPUs as well. Given that the value was dead, 19813;; this should not create any new dependencies. Pass on the sub-word 19814;; versions if we're concerned about partial register stalls. 19815 19816(define_peephole2 19817 [(set (match_operand 0 "flags_reg_operand" "") 19818 (match_operator 1 "compare_operator" 19819 [(and:SI (match_operand:SI 2 "register_operand" "") 19820 (match_operand:SI 3 "immediate_operand" "")) 19821 (const_int 0)]))] 19822 "ix86_match_ccmode (insn, CCNOmode) 19823 && (true_regnum (operands[2]) != 0 19824 || satisfies_constraint_K (operands[3])) 19825 && peep2_reg_dead_p (1, operands[2])" 19826 [(parallel 19827 [(set (match_dup 0) 19828 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 19829 (const_int 0)])) 19830 (set (match_dup 2) 19831 (and:SI (match_dup 2) (match_dup 3)))])] 19832 "") 19833 19834;; We don't need to handle HImode case, because it will be promoted to SImode 19835;; on ! TARGET_PARTIAL_REG_STALL 19836 19837(define_peephole2 19838 [(set (match_operand 0 "flags_reg_operand" "") 19839 (match_operator 1 "compare_operator" 19840 [(and:QI (match_operand:QI 2 "register_operand" "") 19841 (match_operand:QI 3 "immediate_operand" "")) 19842 (const_int 0)]))] 19843 "! TARGET_PARTIAL_REG_STALL 19844 && ix86_match_ccmode (insn, CCNOmode) 19845 && true_regnum (operands[2]) != 0 19846 && peep2_reg_dead_p (1, operands[2])" 19847 [(parallel 19848 [(set (match_dup 0) 19849 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 19850 (const_int 0)])) 19851 (set (match_dup 2) 19852 (and:QI (match_dup 2) (match_dup 3)))])] 19853 "") 19854 19855(define_peephole2 19856 [(set (match_operand 0 "flags_reg_operand" "") 19857 (match_operator 1 "compare_operator" 19858 [(and:SI 19859 (zero_extract:SI 19860 (match_operand 2 "ext_register_operand" "") 19861 (const_int 8) 19862 (const_int 8)) 19863 (match_operand 3 "const_int_operand" "")) 19864 (const_int 0)]))] 19865 "! TARGET_PARTIAL_REG_STALL 19866 && ix86_match_ccmode (insn, CCNOmode) 19867 && true_regnum (operands[2]) != 0 19868 && peep2_reg_dead_p (1, operands[2])" 19869 [(parallel [(set (match_dup 0) 19870 (match_op_dup 1 19871 [(and:SI 19872 (zero_extract:SI 19873 (match_dup 2) 19874 (const_int 8) 19875 (const_int 8)) 19876 (match_dup 3)) 19877 (const_int 0)])) 19878 (set (zero_extract:SI (match_dup 2) 19879 (const_int 8) 19880 (const_int 8)) 19881 (and:SI 19882 (zero_extract:SI 19883 (match_dup 2) 19884 (const_int 8) 19885 (const_int 8)) 19886 (match_dup 3)))])] 19887 "") 19888 19889;; Don't do logical operations with memory inputs. 19890(define_peephole2 19891 [(match_scratch:SI 2 "r") 19892 (parallel [(set (match_operand:SI 0 "register_operand" "") 19893 (match_operator:SI 3 "arith_or_logical_operator" 19894 [(match_dup 0) 19895 (match_operand:SI 1 "memory_operand" "")])) 19896 (clobber (reg:CC FLAGS_REG))])] 19897 "! optimize_size && ! TARGET_READ_MODIFY" 19898 [(set (match_dup 2) (match_dup 1)) 19899 (parallel [(set (match_dup 0) 19900 (match_op_dup 3 [(match_dup 0) (match_dup 2)])) 19901 (clobber (reg:CC FLAGS_REG))])] 19902 "") 19903 19904(define_peephole2 19905 [(match_scratch:SI 2 "r") 19906 (parallel [(set (match_operand:SI 0 "register_operand" "") 19907 (match_operator:SI 3 "arith_or_logical_operator" 19908 [(match_operand:SI 1 "memory_operand" "") 19909 (match_dup 0)])) 19910 (clobber (reg:CC FLAGS_REG))])] 19911 "! optimize_size && ! TARGET_READ_MODIFY" 19912 [(set (match_dup 2) (match_dup 1)) 19913 (parallel [(set (match_dup 0) 19914 (match_op_dup 3 [(match_dup 2) (match_dup 0)])) 19915 (clobber (reg:CC FLAGS_REG))])] 19916 "") 19917 19918; Don't do logical operations with memory outputs 19919; 19920; These two don't make sense for PPro/PII -- we're expanding a 4-uop 19921; instruction into two 1-uop insns plus a 2-uop insn. That last has 19922; the same decoder scheduling characteristics as the original. 19923 19924(define_peephole2 19925 [(match_scratch:SI 2 "r") 19926 (parallel [(set (match_operand:SI 0 "memory_operand" "") 19927 (match_operator:SI 3 "arith_or_logical_operator" 19928 [(match_dup 0) 19929 (match_operand:SI 1 "nonmemory_operand" "")])) 19930 (clobber (reg:CC FLAGS_REG))])] 19931 "! optimize_size && ! TARGET_READ_MODIFY_WRITE" 19932 [(set (match_dup 2) (match_dup 0)) 19933 (parallel [(set (match_dup 2) 19934 (match_op_dup 3 [(match_dup 2) (match_dup 1)])) 19935 (clobber (reg:CC FLAGS_REG))]) 19936 (set (match_dup 0) (match_dup 2))] 19937 "") 19938 19939(define_peephole2 19940 [(match_scratch:SI 2 "r") 19941 (parallel [(set (match_operand:SI 0 "memory_operand" "") 19942 (match_operator:SI 3 "arith_or_logical_operator" 19943 [(match_operand:SI 1 "nonmemory_operand" "") 19944 (match_dup 0)])) 19945 (clobber (reg:CC FLAGS_REG))])] 19946 "! optimize_size && ! TARGET_READ_MODIFY_WRITE" 19947 [(set (match_dup 2) (match_dup 0)) 19948 (parallel [(set (match_dup 2) 19949 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 19950 (clobber (reg:CC FLAGS_REG))]) 19951 (set (match_dup 0) (match_dup 2))] 19952 "") 19953 19954;; Attempt to always use XOR for zeroing registers. 19955(define_peephole2 19956 [(set (match_operand 0 "register_operand" "") 19957 (match_operand 1 "const0_operand" ""))] 19958 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD 19959 && (! TARGET_USE_MOV0 || optimize_size) 19960 && GENERAL_REG_P (operands[0]) 19961 && peep2_regno_dead_p (0, FLAGS_REG)" 19962 [(parallel [(set (match_dup 0) (const_int 0)) 19963 (clobber (reg:CC FLAGS_REG))])] 19964{ 19965 operands[0] = gen_lowpart (word_mode, operands[0]); 19966}) 19967 19968(define_peephole2 19969 [(set (strict_low_part (match_operand 0 "register_operand" "")) 19970 (const_int 0))] 19971 "(GET_MODE (operands[0]) == QImode 19972 || GET_MODE (operands[0]) == HImode) 19973 && (! TARGET_USE_MOV0 || optimize_size) 19974 && peep2_regno_dead_p (0, FLAGS_REG)" 19975 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0)) 19976 (clobber (reg:CC FLAGS_REG))])]) 19977 19978;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg. 19979(define_peephole2 19980 [(set (match_operand 0 "register_operand" "") 19981 (const_int -1))] 19982 "(GET_MODE (operands[0]) == HImode 19983 || GET_MODE (operands[0]) == SImode 19984 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT)) 19985 && (optimize_size || TARGET_PENTIUM) 19986 && peep2_regno_dead_p (0, FLAGS_REG)" 19987 [(parallel [(set (match_dup 0) (const_int -1)) 19988 (clobber (reg:CC FLAGS_REG))])] 19989 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode, 19990 operands[0]);") 19991 19992;; Attempt to convert simple leas to adds. These can be created by 19993;; move expanders. 19994(define_peephole2 19995 [(set (match_operand:SI 0 "register_operand" "") 19996 (plus:SI (match_dup 0) 19997 (match_operand:SI 1 "nonmemory_operand" "")))] 19998 "peep2_regno_dead_p (0, FLAGS_REG)" 19999 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) 20000 (clobber (reg:CC FLAGS_REG))])] 20001 "") 20002 20003(define_peephole2 20004 [(set (match_operand:SI 0 "register_operand" "") 20005 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "") 20006 (match_operand:DI 2 "nonmemory_operand" "")) 0))] 20007 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])" 20008 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2))) 20009 (clobber (reg:CC FLAGS_REG))])] 20010 "operands[2] = gen_lowpart (SImode, operands[2]);") 20011 20012(define_peephole2 20013 [(set (match_operand:DI 0 "register_operand" "") 20014 (plus:DI (match_dup 0) 20015 (match_operand:DI 1 "x86_64_general_operand" "")))] 20016 "peep2_regno_dead_p (0, FLAGS_REG)" 20017 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1))) 20018 (clobber (reg:CC FLAGS_REG))])] 20019 "") 20020 20021(define_peephole2 20022 [(set (match_operand:SI 0 "register_operand" "") 20023 (mult:SI (match_dup 0) 20024 (match_operand:SI 1 "const_int_operand" "")))] 20025 "exact_log2 (INTVAL (operands[1])) >= 0 20026 && peep2_regno_dead_p (0, FLAGS_REG)" 20027 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) 20028 (clobber (reg:CC FLAGS_REG))])] 20029 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));") 20030 20031(define_peephole2 20032 [(set (match_operand:DI 0 "register_operand" "") 20033 (mult:DI (match_dup 0) 20034 (match_operand:DI 1 "const_int_operand" "")))] 20035 "exact_log2 (INTVAL (operands[1])) >= 0 20036 && peep2_regno_dead_p (0, FLAGS_REG)" 20037 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2))) 20038 (clobber (reg:CC FLAGS_REG))])] 20039 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));") 20040 20041(define_peephole2 20042 [(set (match_operand:SI 0 "register_operand" "") 20043 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "") 20044 (match_operand:DI 2 "const_int_operand" "")) 0))] 20045 "exact_log2 (INTVAL (operands[2])) >= 0 20046 && REGNO (operands[0]) == REGNO (operands[1]) 20047 && peep2_regno_dead_p (0, FLAGS_REG)" 20048 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) 20049 (clobber (reg:CC FLAGS_REG))])] 20050 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));") 20051 20052;; The ESP adjustments can be done by the push and pop instructions. Resulting 20053;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On 20054;; many CPUs it is also faster, since special hardware to avoid esp 20055;; dependencies is present. 20056 20057;; While some of these conversions may be done using splitters, we use peepholes 20058;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL. 20059 20060;; Convert prologue esp subtractions to push. 20061;; We need register to push. In order to keep verify_flow_info happy we have 20062;; two choices 20063;; - use scratch and clobber it in order to avoid dependencies 20064;; - use already live register 20065;; We can't use the second way right now, since there is no reliable way how to 20066;; verify that given register is live. First choice will also most likely in 20067;; fewer dependencies. On the place of esp adjustments it is very likely that 20068;; call clobbered registers are dead. We may want to use base pointer as an 20069;; alternative when no register is available later. 20070 20071(define_peephole2 20072 [(match_scratch:SI 0 "r") 20073 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) 20074 (clobber (reg:CC FLAGS_REG)) 20075 (clobber (mem:BLK (scratch)))])] 20076 "optimize_size || !TARGET_SUB_ESP_4" 20077 [(clobber (match_dup 0)) 20078 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 20079 (clobber (mem:BLK (scratch)))])]) 20080 20081(define_peephole2 20082 [(match_scratch:SI 0 "r") 20083 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 20084 (clobber (reg:CC FLAGS_REG)) 20085 (clobber (mem:BLK (scratch)))])] 20086 "optimize_size || !TARGET_SUB_ESP_8" 20087 [(clobber (match_dup 0)) 20088 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 20089 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 20090 (clobber (mem:BLK (scratch)))])]) 20091 20092;; Convert esp subtractions to push. 20093(define_peephole2 20094 [(match_scratch:SI 0 "r") 20095 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) 20096 (clobber (reg:CC FLAGS_REG))])] 20097 "optimize_size || !TARGET_SUB_ESP_4" 20098 [(clobber (match_dup 0)) 20099 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))]) 20100 20101(define_peephole2 20102 [(match_scratch:SI 0 "r") 20103 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 20104 (clobber (reg:CC FLAGS_REG))])] 20105 "optimize_size || !TARGET_SUB_ESP_8" 20106 [(clobber (match_dup 0)) 20107 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 20108 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))]) 20109 20110;; Convert epilogue deallocator to pop. 20111(define_peephole2 20112 [(match_scratch:SI 0 "r") 20113 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20114 (clobber (reg:CC FLAGS_REG)) 20115 (clobber (mem:BLK (scratch)))])] 20116 "optimize_size || !TARGET_ADD_ESP_4" 20117 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20118 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20119 (clobber (mem:BLK (scratch)))])] 20120 "") 20121 20122;; Two pops case is tricky, since pop causes dependency on destination register. 20123;; We use two registers if available. 20124(define_peephole2 20125 [(match_scratch:SI 0 "r") 20126 (match_scratch:SI 1 "r") 20127 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 20128 (clobber (reg:CC FLAGS_REG)) 20129 (clobber (mem:BLK (scratch)))])] 20130 "optimize_size || !TARGET_ADD_ESP_8" 20131 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20132 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20133 (clobber (mem:BLK (scratch)))]) 20134 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG))) 20135 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20136 "") 20137 20138(define_peephole2 20139 [(match_scratch:SI 0 "r") 20140 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 20141 (clobber (reg:CC FLAGS_REG)) 20142 (clobber (mem:BLK (scratch)))])] 20143 "optimize_size" 20144 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20145 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20146 (clobber (mem:BLK (scratch)))]) 20147 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20148 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20149 "") 20150 20151;; Convert esp additions to pop. 20152(define_peephole2 20153 [(match_scratch:SI 0 "r") 20154 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20155 (clobber (reg:CC FLAGS_REG))])] 20156 "" 20157 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20158 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20159 "") 20160 20161;; Two pops case is tricky, since pop causes dependency on destination register. 20162;; We use two registers if available. 20163(define_peephole2 20164 [(match_scratch:SI 0 "r") 20165 (match_scratch:SI 1 "r") 20166 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 20167 (clobber (reg:CC FLAGS_REG))])] 20168 "" 20169 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20170 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))]) 20171 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG))) 20172 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20173 "") 20174 20175(define_peephole2 20176 [(match_scratch:SI 0 "r") 20177 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 20178 (clobber (reg:CC FLAGS_REG))])] 20179 "optimize_size" 20180 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20181 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))]) 20182 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20183 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20184 "") 20185 20186;; Convert compares with 1 to shorter inc/dec operations when CF is not 20187;; required and register dies. Similarly for 128 to plus -128. 20188(define_peephole2 20189 [(set (match_operand 0 "flags_reg_operand" "") 20190 (match_operator 1 "compare_operator" 20191 [(match_operand 2 "register_operand" "") 20192 (match_operand 3 "const_int_operand" "")]))] 20193 "(INTVAL (operands[3]) == -1 20194 || INTVAL (operands[3]) == 1 20195 || INTVAL (operands[3]) == 128) 20196 && ix86_match_ccmode (insn, CCGCmode) 20197 && peep2_reg_dead_p (1, operands[2])" 20198 [(parallel [(set (match_dup 0) 20199 (match_op_dup 1 [(match_dup 2) (match_dup 3)])) 20200 (clobber (match_dup 2))])] 20201 "") 20202 20203(define_peephole2 20204 [(match_scratch:DI 0 "r") 20205 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 20206 (clobber (reg:CC FLAGS_REG)) 20207 (clobber (mem:BLK (scratch)))])] 20208 "optimize_size || !TARGET_SUB_ESP_4" 20209 [(clobber (match_dup 0)) 20210 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 20211 (clobber (mem:BLK (scratch)))])]) 20212 20213(define_peephole2 20214 [(match_scratch:DI 0 "r") 20215 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16))) 20216 (clobber (reg:CC FLAGS_REG)) 20217 (clobber (mem:BLK (scratch)))])] 20218 "optimize_size || !TARGET_SUB_ESP_8" 20219 [(clobber (match_dup 0)) 20220 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 20221 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 20222 (clobber (mem:BLK (scratch)))])]) 20223 20224;; Convert esp subtractions to push. 20225(define_peephole2 20226 [(match_scratch:DI 0 "r") 20227 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 20228 (clobber (reg:CC FLAGS_REG))])] 20229 "optimize_size || !TARGET_SUB_ESP_4" 20230 [(clobber (match_dup 0)) 20231 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))]) 20232 20233(define_peephole2 20234 [(match_scratch:DI 0 "r") 20235 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16))) 20236 (clobber (reg:CC FLAGS_REG))])] 20237 "optimize_size || !TARGET_SUB_ESP_8" 20238 [(clobber (match_dup 0)) 20239 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 20240 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))]) 20241 20242;; Convert epilogue deallocator to pop. 20243(define_peephole2 20244 [(match_scratch:DI 0 "r") 20245 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20246 (clobber (reg:CC FLAGS_REG)) 20247 (clobber (mem:BLK (scratch)))])] 20248 "optimize_size || !TARGET_ADD_ESP_4" 20249 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20250 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20251 (clobber (mem:BLK (scratch)))])] 20252 "") 20253 20254;; Two pops case is tricky, since pop causes dependency on destination register. 20255;; We use two registers if available. 20256(define_peephole2 20257 [(match_scratch:DI 0 "r") 20258 (match_scratch:DI 1 "r") 20259 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20260 (clobber (reg:CC FLAGS_REG)) 20261 (clobber (mem:BLK (scratch)))])] 20262 "optimize_size || !TARGET_ADD_ESP_8" 20263 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20264 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20265 (clobber (mem:BLK (scratch)))]) 20266 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG))) 20267 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20268 "") 20269 20270(define_peephole2 20271 [(match_scratch:DI 0 "r") 20272 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20273 (clobber (reg:CC FLAGS_REG)) 20274 (clobber (mem:BLK (scratch)))])] 20275 "optimize_size" 20276 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20277 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20278 (clobber (mem:BLK (scratch)))]) 20279 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20280 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20281 "") 20282 20283;; Convert esp additions to pop. 20284(define_peephole2 20285 [(match_scratch:DI 0 "r") 20286 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20287 (clobber (reg:CC FLAGS_REG))])] 20288 "" 20289 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20290 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20291 "") 20292 20293;; Two pops case is tricky, since pop causes dependency on destination register. 20294;; We use two registers if available. 20295(define_peephole2 20296 [(match_scratch:DI 0 "r") 20297 (match_scratch:DI 1 "r") 20298 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20299 (clobber (reg:CC FLAGS_REG))])] 20300 "" 20301 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20302 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))]) 20303 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG))) 20304 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20305 "") 20306 20307(define_peephole2 20308 [(match_scratch:DI 0 "r") 20309 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20310 (clobber (reg:CC FLAGS_REG))])] 20311 "optimize_size" 20312 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20313 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))]) 20314 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20315 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20316 "") 20317 20318;; Convert imul by three, five and nine into lea 20319(define_peephole2 20320 [(parallel 20321 [(set (match_operand:SI 0 "register_operand" "") 20322 (mult:SI (match_operand:SI 1 "register_operand" "") 20323 (match_operand:SI 2 "const_int_operand" ""))) 20324 (clobber (reg:CC FLAGS_REG))])] 20325 "INTVAL (operands[2]) == 3 20326 || INTVAL (operands[2]) == 5 20327 || INTVAL (operands[2]) == 9" 20328 [(set (match_dup 0) 20329 (plus:SI (mult:SI (match_dup 1) (match_dup 2)) 20330 (match_dup 1)))] 20331 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20332 20333(define_peephole2 20334 [(parallel 20335 [(set (match_operand:SI 0 "register_operand" "") 20336 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "") 20337 (match_operand:SI 2 "const_int_operand" ""))) 20338 (clobber (reg:CC FLAGS_REG))])] 20339 "!optimize_size 20340 && (INTVAL (operands[2]) == 3 20341 || INTVAL (operands[2]) == 5 20342 || INTVAL (operands[2]) == 9)" 20343 [(set (match_dup 0) (match_dup 1)) 20344 (set (match_dup 0) 20345 (plus:SI (mult:SI (match_dup 0) (match_dup 2)) 20346 (match_dup 0)))] 20347 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20348 20349(define_peephole2 20350 [(parallel 20351 [(set (match_operand:DI 0 "register_operand" "") 20352 (mult:DI (match_operand:DI 1 "register_operand" "") 20353 (match_operand:DI 2 "const_int_operand" ""))) 20354 (clobber (reg:CC FLAGS_REG))])] 20355 "TARGET_64BIT 20356 && (INTVAL (operands[2]) == 3 20357 || INTVAL (operands[2]) == 5 20358 || INTVAL (operands[2]) == 9)" 20359 [(set (match_dup 0) 20360 (plus:DI (mult:DI (match_dup 1) (match_dup 2)) 20361 (match_dup 1)))] 20362 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20363 20364(define_peephole2 20365 [(parallel 20366 [(set (match_operand:DI 0 "register_operand" "") 20367 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "") 20368 (match_operand:DI 2 "const_int_operand" ""))) 20369 (clobber (reg:CC FLAGS_REG))])] 20370 "TARGET_64BIT 20371 && !optimize_size 20372 && (INTVAL (operands[2]) == 3 20373 || INTVAL (operands[2]) == 5 20374 || INTVAL (operands[2]) == 9)" 20375 [(set (match_dup 0) (match_dup 1)) 20376 (set (match_dup 0) 20377 (plus:DI (mult:DI (match_dup 0) (match_dup 2)) 20378 (match_dup 0)))] 20379 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20380 20381;; Imul $32bit_imm, mem, reg is vector decoded, while 20382;; imul $32bit_imm, reg, reg is direct decoded. 20383(define_peephole2 20384 [(match_scratch:DI 3 "r") 20385 (parallel [(set (match_operand:DI 0 "register_operand" "") 20386 (mult:DI (match_operand:DI 1 "memory_operand" "") 20387 (match_operand:DI 2 "immediate_operand" ""))) 20388 (clobber (reg:CC FLAGS_REG))])] 20389 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size 20390 && !satisfies_constraint_K (operands[2])" 20391 [(set (match_dup 3) (match_dup 1)) 20392 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2))) 20393 (clobber (reg:CC FLAGS_REG))])] 20394"") 20395 20396(define_peephole2 20397 [(match_scratch:SI 3 "r") 20398 (parallel [(set (match_operand:SI 0 "register_operand" "") 20399 (mult:SI (match_operand:SI 1 "memory_operand" "") 20400 (match_operand:SI 2 "immediate_operand" ""))) 20401 (clobber (reg:CC FLAGS_REG))])] 20402 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size 20403 && !satisfies_constraint_K (operands[2])" 20404 [(set (match_dup 3) (match_dup 1)) 20405 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2))) 20406 (clobber (reg:CC FLAGS_REG))])] 20407"") 20408 20409(define_peephole2 20410 [(match_scratch:SI 3 "r") 20411 (parallel [(set (match_operand:DI 0 "register_operand" "") 20412 (zero_extend:DI 20413 (mult:SI (match_operand:SI 1 "memory_operand" "") 20414 (match_operand:SI 2 "immediate_operand" "")))) 20415 (clobber (reg:CC FLAGS_REG))])] 20416 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size 20417 && !satisfies_constraint_K (operands[2])" 20418 [(set (match_dup 3) (match_dup 1)) 20419 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2)))) 20420 (clobber (reg:CC FLAGS_REG))])] 20421"") 20422 20423;; imul $8/16bit_imm, regmem, reg is vector decoded. 20424;; Convert it into imul reg, reg 20425;; It would be better to force assembler to encode instruction using long 20426;; immediate, but there is apparently no way to do so. 20427(define_peephole2 20428 [(parallel [(set (match_operand:DI 0 "register_operand" "") 20429 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "") 20430 (match_operand:DI 2 "const_int_operand" ""))) 20431 (clobber (reg:CC FLAGS_REG))]) 20432 (match_scratch:DI 3 "r")] 20433 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size 20434 && satisfies_constraint_K (operands[2])" 20435 [(set (match_dup 3) (match_dup 2)) 20436 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3))) 20437 (clobber (reg:CC FLAGS_REG))])] 20438{ 20439 if (!rtx_equal_p (operands[0], operands[1])) 20440 emit_move_insn (operands[0], operands[1]); 20441}) 20442 20443(define_peephole2 20444 [(parallel [(set (match_operand:SI 0 "register_operand" "") 20445 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "") 20446 (match_operand:SI 2 "const_int_operand" ""))) 20447 (clobber (reg:CC FLAGS_REG))]) 20448 (match_scratch:SI 3 "r")] 20449 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size 20450 && satisfies_constraint_K (operands[2])" 20451 [(set (match_dup 3) (match_dup 2)) 20452 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3))) 20453 (clobber (reg:CC FLAGS_REG))])] 20454{ 20455 if (!rtx_equal_p (operands[0], operands[1])) 20456 emit_move_insn (operands[0], operands[1]); 20457}) 20458 20459(define_peephole2 20460 [(parallel [(set (match_operand:HI 0 "register_operand" "") 20461 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "") 20462 (match_operand:HI 2 "immediate_operand" ""))) 20463 (clobber (reg:CC FLAGS_REG))]) 20464 (match_scratch:HI 3 "r")] 20465 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size" 20466 [(set (match_dup 3) (match_dup 2)) 20467 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3))) 20468 (clobber (reg:CC FLAGS_REG))])] 20469{ 20470 if (!rtx_equal_p (operands[0], operands[1])) 20471 emit_move_insn (operands[0], operands[1]); 20472}) 20473 20474;; After splitting up read-modify operations, array accesses with memory 20475;; operands might end up in form: 20476;; sall $2, %eax 20477;; movl 4(%esp), %edx 20478;; addl %edx, %eax 20479;; instead of pre-splitting: 20480;; sall $2, %eax 20481;; addl 4(%esp), %eax 20482;; Turn it into: 20483;; movl 4(%esp), %edx 20484;; leal (%edx,%eax,4), %eax 20485 20486(define_peephole2 20487 [(parallel [(set (match_operand 0 "register_operand" "") 20488 (ashift (match_operand 1 "register_operand" "") 20489 (match_operand 2 "const_int_operand" ""))) 20490 (clobber (reg:CC FLAGS_REG))]) 20491 (set (match_operand 3 "register_operand") 20492 (match_operand 4 "x86_64_general_operand" "")) 20493 (parallel [(set (match_operand 5 "register_operand" "") 20494 (plus (match_operand 6 "register_operand" "") 20495 (match_operand 7 "register_operand" ""))) 20496 (clobber (reg:CC FLAGS_REG))])] 20497 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3 20498 /* Validate MODE for lea. */ 20499 && ((!TARGET_PARTIAL_REG_STALL 20500 && (GET_MODE (operands[0]) == QImode 20501 || GET_MODE (operands[0]) == HImode)) 20502 || GET_MODE (operands[0]) == SImode 20503 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) 20504 /* We reorder load and the shift. */ 20505 && !rtx_equal_p (operands[1], operands[3]) 20506 && !reg_overlap_mentioned_p (operands[0], operands[4]) 20507 /* Last PLUS must consist of operand 0 and 3. */ 20508 && !rtx_equal_p (operands[0], operands[3]) 20509 && (rtx_equal_p (operands[3], operands[6]) 20510 || rtx_equal_p (operands[3], operands[7])) 20511 && (rtx_equal_p (operands[0], operands[6]) 20512 || rtx_equal_p (operands[0], operands[7])) 20513 /* The intermediate operand 0 must die or be same as output. */ 20514 && (rtx_equal_p (operands[0], operands[5]) 20515 || peep2_reg_dead_p (3, operands[0]))" 20516 [(set (match_dup 3) (match_dup 4)) 20517 (set (match_dup 0) (match_dup 1))] 20518{ 20519 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode; 20520 int scale = 1 << INTVAL (operands[2]); 20521 rtx index = gen_lowpart (Pmode, operands[1]); 20522 rtx base = gen_lowpart (Pmode, operands[3]); 20523 rtx dest = gen_lowpart (mode, operands[5]); 20524 20525 operands[1] = gen_rtx_PLUS (Pmode, base, 20526 gen_rtx_MULT (Pmode, index, GEN_INT (scale))); 20527 if (mode != Pmode) 20528 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); 20529 operands[0] = dest; 20530}) 20531 20532;; Call-value patterns last so that the wildcard operand does not 20533;; disrupt insn-recog's switch tables. 20534 20535(define_insn "*call_value_pop_0" 20536 [(set (match_operand 0 "" "") 20537 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) 20538 (match_operand:SI 2 "" ""))) 20539 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 20540 (match_operand:SI 3 "immediate_operand" "")))] 20541 "!TARGET_64BIT" 20542{ 20543 if (SIBLING_CALL_P (insn)) 20544 return "jmp\t%P1"; 20545 else 20546 return "call\t%P1"; 20547} 20548 [(set_attr "type" "callv")]) 20549 20550(define_insn "*call_value_pop_1" 20551 [(set (match_operand 0 "" "") 20552 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm")) 20553 (match_operand:SI 2 "" ""))) 20554 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 20555 (match_operand:SI 3 "immediate_operand" "i")))] 20556 "!TARGET_64BIT" 20557{ 20558 if (constant_call_address_operand (operands[1], Pmode)) 20559 { 20560 if (SIBLING_CALL_P (insn)) 20561 return "jmp\t%P1"; 20562 else 20563 return "call\t%P1"; 20564 } 20565 if (SIBLING_CALL_P (insn)) 20566 return "jmp\t%A1"; 20567 else 20568 return "call\t%A1"; 20569} 20570 [(set_attr "type" "callv")]) 20571 20572(define_insn "*call_value_0" 20573 [(set (match_operand 0 "" "") 20574 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) 20575 (match_operand:SI 2 "" "")))] 20576 "!TARGET_64BIT" 20577{ 20578 if (SIBLING_CALL_P (insn)) 20579 return "jmp\t%P1"; 20580 else 20581 return "call\t%P1"; 20582} 20583 [(set_attr "type" "callv")]) 20584 20585(define_insn "*call_value_0_rex64" 20586 [(set (match_operand 0 "" "") 20587 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) 20588 (match_operand:DI 2 "const_int_operand" "")))] 20589 "TARGET_64BIT" 20590{ 20591 if (SIBLING_CALL_P (insn)) 20592 return "jmp\t%P1"; 20593 else 20594 return "call\t%P1"; 20595} 20596 [(set_attr "type" "callv")]) 20597 20598(define_insn "*call_value_1" 20599 [(set (match_operand 0 "" "") 20600 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm")) 20601 (match_operand:SI 2 "" "")))] 20602 "!SIBLING_CALL_P (insn) && !TARGET_64BIT" 20603{ 20604 if (constant_call_address_operand (operands[1], Pmode)) 20605 return "call\t%P1"; 20606 return "call\t%A1"; 20607} 20608 [(set_attr "type" "callv")]) 20609 20610(define_insn "*sibcall_value_1" 20611 [(set (match_operand 0 "" "") 20612 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a")) 20613 (match_operand:SI 2 "" "")))] 20614 "SIBLING_CALL_P (insn) && !TARGET_64BIT" 20615{ 20616 if (constant_call_address_operand (operands[1], Pmode)) 20617 return "jmp\t%P1"; 20618 return "jmp\t%A1"; 20619} 20620 [(set_attr "type" "callv")]) 20621 20622(define_insn "*call_value_1_rex64" 20623 [(set (match_operand 0 "" "") 20624 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm")) 20625 (match_operand:DI 2 "" "")))] 20626 "!SIBLING_CALL_P (insn) && TARGET_64BIT" 20627{ 20628 if (constant_call_address_operand (operands[1], Pmode)) 20629 return "call\t%P1"; 20630 return "call\t%A1"; 20631} 20632 [(set_attr "type" "callv")]) 20633 20634(define_insn "*sibcall_value_1_rex64" 20635 [(set (match_operand 0 "" "") 20636 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) 20637 (match_operand:DI 2 "" "")))] 20638 "SIBLING_CALL_P (insn) && TARGET_64BIT" 20639 "jmp\t%P1" 20640 [(set_attr "type" "callv")]) 20641 20642(define_insn "*sibcall_value_1_rex64_v" 20643 [(set (match_operand 0 "" "") 20644 (call (mem:QI (reg:DI 40)) 20645 (match_operand:DI 1 "" "")))] 20646 "SIBLING_CALL_P (insn) && TARGET_64BIT" 20647 "jmp\t*%%r11" 20648 [(set_attr "type" "callv")]) 20649 20650;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5. 20651;; That, however, is usually mapped by the OS to SIGSEGV, which is often 20652;; caught for use by garbage collectors and the like. Using an insn that 20653;; maps to SIGILL makes it more likely the program will rightfully die. 20654;; Keeping with tradition, "6" is in honor of #UD. 20655(define_insn "trap" 20656 [(trap_if (const_int 1) (const_int 6))] 20657 "" 20658 { return ASM_SHORT "0x0b0f"; } 20659 [(set_attr "length" "2")]) 20660 20661(define_expand "sse_prologue_save" 20662 [(parallel [(set (match_operand:BLK 0 "" "") 20663 (unspec:BLK [(reg:DI 21) 20664 (reg:DI 22) 20665 (reg:DI 23) 20666 (reg:DI 24) 20667 (reg:DI 25) 20668 (reg:DI 26) 20669 (reg:DI 27) 20670 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE)) 20671 (use (match_operand:DI 1 "register_operand" "")) 20672 (use (match_operand:DI 2 "immediate_operand" "")) 20673 (use (label_ref:DI (match_operand 3 "" "")))])] 20674 "TARGET_64BIT" 20675 "") 20676 20677(define_insn "*sse_prologue_save_insn" 20678 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R") 20679 (match_operand:DI 4 "const_int_operand" "n"))) 20680 (unspec:BLK [(reg:DI 21) 20681 (reg:DI 22) 20682 (reg:DI 23) 20683 (reg:DI 24) 20684 (reg:DI 25) 20685 (reg:DI 26) 20686 (reg:DI 27) 20687 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE)) 20688 (use (match_operand:DI 1 "register_operand" "r")) 20689 (use (match_operand:DI 2 "const_int_operand" "i")) 20690 (use (label_ref:DI (match_operand 3 "" "X")))] 20691 "TARGET_64BIT 20692 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128 20693 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128" 20694 "* 20695{ 20696 int i; 20697 operands[0] = gen_rtx_MEM (Pmode, 20698 gen_rtx_PLUS (Pmode, operands[0], operands[4])); 20699 output_asm_insn (\"jmp\\t%A1\", operands); 20700 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--) 20701 { 20702 operands[4] = adjust_address (operands[0], DImode, i*16); 20703 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i)); 20704 PUT_MODE (operands[4], TImode); 20705 if (GET_CODE (XEXP (operands[0], 0)) != PLUS) 20706 output_asm_insn (\"rex\", operands); 20707 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands); 20708 } 20709 (*targetm.asm_out.internal_label) (asm_out_file, \"L\", 20710 CODE_LABEL_NUMBER (operands[3])); 20711 RET; 20712} 20713 " 20714 [(set_attr "type" "other") 20715 (set_attr "length_immediate" "0") 20716 (set_attr "length_address" "0") 20717 (set_attr "length" "135") 20718 (set_attr "memory" "store") 20719 (set_attr "modrm" "0") 20720 (set_attr "mode" "DI")]) 20721 20722(define_expand "prefetch" 20723 [(prefetch (match_operand 0 "address_operand" "") 20724 (match_operand:SI 1 "const_int_operand" "") 20725 (match_operand:SI 2 "const_int_operand" ""))] 20726 "TARGET_PREFETCH_SSE || TARGET_3DNOW" 20727{ 20728 int rw = INTVAL (operands[1]); 20729 int locality = INTVAL (operands[2]); 20730 20731 gcc_assert (rw == 0 || rw == 1); 20732 gcc_assert (locality >= 0 && locality <= 3); 20733 gcc_assert (GET_MODE (operands[0]) == Pmode 20734 || GET_MODE (operands[0]) == VOIDmode); 20735 20736 /* Use 3dNOW prefetch in case we are asking for write prefetch not 20737 supported by SSE counterpart or the SSE prefetch is not available 20738 (K6 machines). Otherwise use SSE prefetch as it allows specifying 20739 of locality. */ 20740 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw)) 20741 operands[2] = GEN_INT (3); 20742 else 20743 operands[1] = const0_rtx; 20744}) 20745 20746(define_insn "*prefetch_sse" 20747 [(prefetch (match_operand:SI 0 "address_operand" "p") 20748 (const_int 0) 20749 (match_operand:SI 1 "const_int_operand" ""))] 20750 "TARGET_PREFETCH_SSE && !TARGET_64BIT" 20751{ 20752 static const char * const patterns[4] = { 20753 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" 20754 }; 20755 20756 int locality = INTVAL (operands[1]); 20757 gcc_assert (locality >= 0 && locality <= 3); 20758 20759 return patterns[locality]; 20760} 20761 [(set_attr "type" "sse") 20762 (set_attr "memory" "none")]) 20763 20764(define_insn "*prefetch_sse_rex" 20765 [(prefetch (match_operand:DI 0 "address_operand" "p") 20766 (const_int 0) 20767 (match_operand:SI 1 "const_int_operand" ""))] 20768 "TARGET_PREFETCH_SSE && TARGET_64BIT" 20769{ 20770 static const char * const patterns[4] = { 20771 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" 20772 }; 20773 20774 int locality = INTVAL (operands[1]); 20775 gcc_assert (locality >= 0 && locality <= 3); 20776 20777 return patterns[locality]; 20778} 20779 [(set_attr "type" "sse") 20780 (set_attr "memory" "none")]) 20781 20782(define_insn "*prefetch_3dnow" 20783 [(prefetch (match_operand:SI 0 "address_operand" "p") 20784 (match_operand:SI 1 "const_int_operand" "n") 20785 (const_int 3))] 20786 "TARGET_3DNOW && !TARGET_64BIT" 20787{ 20788 if (INTVAL (operands[1]) == 0) 20789 return "prefetch\t%a0"; 20790 else 20791 return "prefetchw\t%a0"; 20792} 20793 [(set_attr "type" "mmx") 20794 (set_attr "memory" "none")]) 20795 20796(define_insn "*prefetch_3dnow_rex" 20797 [(prefetch (match_operand:DI 0 "address_operand" "p") 20798 (match_operand:SI 1 "const_int_operand" "n") 20799 (const_int 3))] 20800 "TARGET_3DNOW && TARGET_64BIT" 20801{ 20802 if (INTVAL (operands[1]) == 0) 20803 return "prefetch\t%a0"; 20804 else 20805 return "prefetchw\t%a0"; 20806} 20807 [(set_attr "type" "mmx") 20808 (set_attr "memory" "none")]) 20809 20810(define_expand "stack_protect_set" 20811 [(match_operand 0 "memory_operand" "") 20812 (match_operand 1 "memory_operand" "")] 20813 "" 20814{ 20815#ifdef TARGET_THREAD_SSP_OFFSET 20816 if (TARGET_64BIT) 20817 emit_insn (gen_stack_tls_protect_set_di (operands[0], 20818 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 20819 else 20820 emit_insn (gen_stack_tls_protect_set_si (operands[0], 20821 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 20822#else 20823 if (TARGET_64BIT) 20824 emit_insn (gen_stack_protect_set_di (operands[0], operands[1])); 20825 else 20826 emit_insn (gen_stack_protect_set_si (operands[0], operands[1])); 20827#endif 20828 DONE; 20829}) 20830 20831(define_insn "stack_protect_set_si" 20832 [(set (match_operand:SI 0 "memory_operand" "=m") 20833 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 20834 (set (match_scratch:SI 2 "=&r") (const_int 0)) 20835 (clobber (reg:CC FLAGS_REG))] 20836 "" 20837 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2" 20838 [(set_attr "type" "multi")]) 20839 20840(define_insn "stack_protect_set_di" 20841 [(set (match_operand:DI 0 "memory_operand" "=m") 20842 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 20843 (set (match_scratch:DI 2 "=&r") (const_int 0)) 20844 (clobber (reg:CC FLAGS_REG))] 20845 "TARGET_64BIT" 20846 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" 20847 [(set_attr "type" "multi")]) 20848 20849(define_insn "stack_tls_protect_set_si" 20850 [(set (match_operand:SI 0 "memory_operand" "=m") 20851 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET)) 20852 (set (match_scratch:SI 2 "=&r") (const_int 0)) 20853 (clobber (reg:CC FLAGS_REG))] 20854 "" 20855 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2" 20856 [(set_attr "type" "multi")]) 20857 20858(define_insn "stack_tls_protect_set_di" 20859 [(set (match_operand:DI 0 "memory_operand" "=m") 20860 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET)) 20861 (set (match_scratch:DI 2 "=&r") (const_int 0)) 20862 (clobber (reg:CC FLAGS_REG))] 20863 "TARGET_64BIT" 20864 { 20865 /* The kernel uses a different segment register for performance reasons; a 20866 system call would not have to trash the userspace segment register, 20867 which would be expensive */ 20868 if (ix86_cmodel != CM_KERNEL) 20869 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"; 20870 else 20871 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"; 20872 } 20873 [(set_attr "type" "multi")]) 20874 20875(define_expand "stack_protect_test" 20876 [(match_operand 0 "memory_operand" "") 20877 (match_operand 1 "memory_operand" "") 20878 (match_operand 2 "" "")] 20879 "" 20880{ 20881 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG); 20882 ix86_compare_op0 = operands[0]; 20883 ix86_compare_op1 = operands[1]; 20884 ix86_compare_emitted = flags; 20885 20886#ifdef TARGET_THREAD_SSP_OFFSET 20887 if (TARGET_64BIT) 20888 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0], 20889 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 20890 else 20891 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0], 20892 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 20893#else 20894 if (TARGET_64BIT) 20895 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1])); 20896 else 20897 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1])); 20898#endif 20899 emit_jump_insn (gen_beq (operands[2])); 20900 DONE; 20901}) 20902 20903(define_insn "stack_protect_test_si" 20904 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 20905 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m") 20906 (match_operand:SI 2 "memory_operand" "m")] 20907 UNSPEC_SP_TEST)) 20908 (clobber (match_scratch:SI 3 "=&r"))] 20909 "" 20910 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}" 20911 [(set_attr "type" "multi")]) 20912 20913(define_insn "stack_protect_test_di" 20914 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 20915 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m") 20916 (match_operand:DI 2 "memory_operand" "m")] 20917 UNSPEC_SP_TEST)) 20918 (clobber (match_scratch:DI 3 "=&r"))] 20919 "TARGET_64BIT" 20920 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}" 20921 [(set_attr "type" "multi")]) 20922 20923(define_insn "stack_tls_protect_test_si" 20924 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 20925 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m") 20926 (match_operand:SI 2 "const_int_operand" "i")] 20927 UNSPEC_SP_TLS_TEST)) 20928 (clobber (match_scratch:SI 3 "=r"))] 20929 "" 20930 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}" 20931 [(set_attr "type" "multi")]) 20932 20933(define_insn "stack_tls_protect_test_di" 20934 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 20935 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m") 20936 (match_operand:DI 2 "const_int_operand" "i")] 20937 UNSPEC_SP_TLS_TEST)) 20938 (clobber (match_scratch:DI 3 "=r"))] 20939 "TARGET_64BIT" 20940 { 20941 /* The kernel uses a different segment register for performance reasons; a 20942 system call would not have to trash the userspace segment register, 20943 which would be expensive */ 20944 if (ix86_cmodel != CM_KERNEL) 20945 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"; 20946 else 20947 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}"; 20948 } 20949 [(set_attr "type" "multi")]) 20950 20951(include "sse.md") 20952(include "mmx.md") 20953(include "sync.md") 20954