i386.md revision 256281
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 ; SSSE3 153 (UNSPEC_PSHUFB 120) 154 (UNSPEC_PSIGN 121) 155 (UNSPEC_PALIGNR 122) 156 157 ; For SSE4A support 158 (UNSPEC_EXTRQI 130) 159 (UNSPEC_EXTRQ 131) 160 (UNSPEC_INSERTQI 132) 161 (UNSPEC_INSERTQ 133) 162 ]) 163 164(define_constants 165 [(UNSPECV_BLOCKAGE 0) 166 (UNSPECV_STACK_PROBE 1) 167 (UNSPECV_EMMS 2) 168 (UNSPECV_LDMXCSR 3) 169 (UNSPECV_STMXCSR 4) 170 (UNSPECV_FEMMS 5) 171 (UNSPECV_CLFLUSH 6) 172 (UNSPECV_ALIGN 7) 173 (UNSPECV_MONITOR 8) 174 (UNSPECV_MWAIT 9) 175 (UNSPECV_CMPXCHG_1 10) 176 (UNSPECV_CMPXCHG_2 11) 177 (UNSPECV_XCHG 12) 178 (UNSPECV_LOCK 13) 179 ]) 180 181;; Registers by name. 182(define_constants 183 [(BP_REG 6) 184 (SP_REG 7) 185 (FLAGS_REG 17) 186 (FPSR_REG 18) 187 (DIRFLAG_REG 19) 188 ]) 189 190;; Insns whose names begin with "x86_" are emitted by gen_FOO calls 191;; from i386.c. 192 193;; In C guard expressions, put expressions which may be compile-time 194;; constants first. This allows for better optimization. For 195;; example, write "TARGET_64BIT && reload_completed", not 196;; "reload_completed && TARGET_64BIT". 197 198 199;; Processor type. This attribute must exactly match the processor_type 200;; enumeration in i386.h. 201(define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8, 202 nocona,core2,generic32,generic64,amdfam10" 203 (const (symbol_ref "ix86_tune"))) 204 205;; A basic instruction type. Refinements due to arguments to be 206;; provided in other attributes. 207(define_attr "type" 208 "other,multi, 209 alu,alu1,negnot,imov,imovx,lea, 210 incdec,ishift,ishift1,rotate,rotate1,imul,idiv, 211 icmp,test,ibr,setcc,icmov, 212 push,pop,call,callv,leave, 213 str,bitmanip,cld, 214 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint, 215 sselog,sselog1,sseiadd,sseishft,sseimul, 216 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins, 217 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft" 218 (const_string "other")) 219 220;; Main data type used by the insn 221(define_attr "mode" 222 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF" 223 (const_string "unknown")) 224 225;; The CPU unit operations uses. 226(define_attr "unit" "integer,i387,sse,mmx,unknown" 227 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint") 228 (const_string "i387") 229 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul, 230 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins") 231 (const_string "sse") 232 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft") 233 (const_string "mmx") 234 (eq_attr "type" "other") 235 (const_string "unknown")] 236 (const_string "integer"))) 237 238;; The (bounding maximum) length of an instruction immediate. 239(define_attr "length_immediate" "" 240 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave, 241 bitmanip") 242 (const_int 0) 243 (eq_attr "unit" "i387,sse,mmx") 244 (const_int 0) 245 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1, 246 imul,icmp,push,pop") 247 (symbol_ref "ix86_attr_length_immediate_default(insn,1)") 248 (eq_attr "type" "imov,test") 249 (symbol_ref "ix86_attr_length_immediate_default(insn,0)") 250 (eq_attr "type" "call") 251 (if_then_else (match_operand 0 "constant_call_address_operand" "") 252 (const_int 4) 253 (const_int 0)) 254 (eq_attr "type" "callv") 255 (if_then_else (match_operand 1 "constant_call_address_operand" "") 256 (const_int 4) 257 (const_int 0)) 258 ;; We don't know the size before shorten_branches. Expect 259 ;; the instruction to fit for better scheduling. 260 (eq_attr "type" "ibr") 261 (const_int 1) 262 ] 263 (symbol_ref "/* Update immediate_length and other attributes! */ 264 gcc_unreachable (),1"))) 265 266;; The (bounding maximum) length of an instruction address. 267(define_attr "length_address" "" 268 (cond [(eq_attr "type" "str,cld,other,multi,fxch") 269 (const_int 0) 270 (and (eq_attr "type" "call") 271 (match_operand 0 "constant_call_address_operand" "")) 272 (const_int 0) 273 (and (eq_attr "type" "callv") 274 (match_operand 1 "constant_call_address_operand" "")) 275 (const_int 0) 276 ] 277 (symbol_ref "ix86_attr_length_address_default (insn)"))) 278 279;; Set when length prefix is used. 280(define_attr "prefix_data16" "" 281 (if_then_else (ior (eq_attr "mode" "HI") 282 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF"))) 283 (const_int 1) 284 (const_int 0))) 285 286;; Set when string REP prefix is used. 287(define_attr "prefix_rep" "" 288 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF")) 289 (const_int 1) 290 (const_int 0))) 291 292;; Set when 0f opcode prefix is used. 293(define_attr "prefix_0f" "" 294 (if_then_else 295 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip") 296 (eq_attr "unit" "sse,mmx")) 297 (const_int 1) 298 (const_int 0))) 299 300;; Set when REX opcode prefix is used. 301(define_attr "prefix_rex" "" 302 (cond [(and (eq_attr "mode" "DI") 303 (eq_attr "type" "!push,pop,call,callv,leave,ibr")) 304 (const_int 1) 305 (and (eq_attr "mode" "QI") 306 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)") 307 (const_int 0))) 308 (const_int 1) 309 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)") 310 (const_int 0)) 311 (const_int 1) 312 ] 313 (const_int 0))) 314 315;; Set when modrm byte is used. 316(define_attr "modrm" "" 317 (cond [(eq_attr "type" "str,cld,leave") 318 (const_int 0) 319 (eq_attr "unit" "i387") 320 (const_int 0) 321 (and (eq_attr "type" "incdec") 322 (ior (match_operand:SI 1 "register_operand" "") 323 (match_operand:HI 1 "register_operand" ""))) 324 (const_int 0) 325 (and (eq_attr "type" "push") 326 (not (match_operand 1 "memory_operand" ""))) 327 (const_int 0) 328 (and (eq_attr "type" "pop") 329 (not (match_operand 0 "memory_operand" ""))) 330 (const_int 0) 331 (and (eq_attr "type" "imov") 332 (ior (and (match_operand 0 "register_operand" "") 333 (match_operand 1 "immediate_operand" "")) 334 (ior (and (match_operand 0 "ax_reg_operand" "") 335 (match_operand 1 "memory_displacement_only_operand" "")) 336 (and (match_operand 0 "memory_displacement_only_operand" "") 337 (match_operand 1 "ax_reg_operand" ""))))) 338 (const_int 0) 339 (and (eq_attr "type" "call") 340 (match_operand 0 "constant_call_address_operand" "")) 341 (const_int 0) 342 (and (eq_attr "type" "callv") 343 (match_operand 1 "constant_call_address_operand" "")) 344 (const_int 0) 345 ] 346 (const_int 1))) 347 348;; The (bounding maximum) length of an instruction in bytes. 349;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences. 350;; Later we may want to split them and compute proper length as for 351;; other insns. 352(define_attr "length" "" 353 (cond [(eq_attr "type" "other,multi,fistp,frndint") 354 (const_int 16) 355 (eq_attr "type" "fcmp") 356 (const_int 4) 357 (eq_attr "unit" "i387") 358 (plus (const_int 2) 359 (plus (attr "prefix_data16") 360 (attr "length_address")))] 361 (plus (plus (attr "modrm") 362 (plus (attr "prefix_0f") 363 (plus (attr "prefix_rex") 364 (const_int 1)))) 365 (plus (attr "prefix_rep") 366 (plus (attr "prefix_data16") 367 (plus (attr "length_immediate") 368 (attr "length_address"))))))) 369 370;; The `memory' attribute is `none' if no memory is referenced, `load' or 371;; `store' if there is a simple memory reference therein, or `unknown' 372;; if the instruction is complex. 373 374(define_attr "memory" "none,load,store,both,unknown" 375 (cond [(eq_attr "type" "other,multi,str") 376 (const_string "unknown") 377 (eq_attr "type" "lea,fcmov,fpspc,cld") 378 (const_string "none") 379 (eq_attr "type" "fistp,leave") 380 (const_string "both") 381 (eq_attr "type" "frndint") 382 (const_string "load") 383 (eq_attr "type" "push") 384 (if_then_else (match_operand 1 "memory_operand" "") 385 (const_string "both") 386 (const_string "store")) 387 (eq_attr "type" "pop") 388 (if_then_else (match_operand 0 "memory_operand" "") 389 (const_string "both") 390 (const_string "load")) 391 (eq_attr "type" "setcc") 392 (if_then_else (match_operand 0 "memory_operand" "") 393 (const_string "store") 394 (const_string "none")) 395 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp") 396 (if_then_else (ior (match_operand 0 "memory_operand" "") 397 (match_operand 1 "memory_operand" "")) 398 (const_string "load") 399 (const_string "none")) 400 (eq_attr "type" "ibr") 401 (if_then_else (match_operand 0 "memory_operand" "") 402 (const_string "load") 403 (const_string "none")) 404 (eq_attr "type" "call") 405 (if_then_else (match_operand 0 "constant_call_address_operand" "") 406 (const_string "none") 407 (const_string "load")) 408 (eq_attr "type" "callv") 409 (if_then_else (match_operand 1 "constant_call_address_operand" "") 410 (const_string "none") 411 (const_string "load")) 412 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1") 413 (match_operand 1 "memory_operand" "")) 414 (const_string "both") 415 (and (match_operand 0 "memory_operand" "") 416 (match_operand 1 "memory_operand" "")) 417 (const_string "both") 418 (match_operand 0 "memory_operand" "") 419 (const_string "store") 420 (match_operand 1 "memory_operand" "") 421 (const_string "load") 422 (and (eq_attr "type" 423 "!alu1,negnot,ishift1, 424 imov,imovx,icmp,test,bitmanip, 425 fmov,fcmp,fsgn, 426 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1, 427 mmx,mmxmov,mmxcmp,mmxcvt") 428 (match_operand 2 "memory_operand" "")) 429 (const_string "load") 430 (and (eq_attr "type" "icmov") 431 (match_operand 3 "memory_operand" "")) 432 (const_string "load") 433 ] 434 (const_string "none"))) 435 436;; Indicates if an instruction has both an immediate and a displacement. 437 438(define_attr "imm_disp" "false,true,unknown" 439 (cond [(eq_attr "type" "other,multi") 440 (const_string "unknown") 441 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1") 442 (and (match_operand 0 "memory_displacement_operand" "") 443 (match_operand 1 "immediate_operand" ""))) 444 (const_string "true") 445 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv") 446 (and (match_operand 0 "memory_displacement_operand" "") 447 (match_operand 2 "immediate_operand" ""))) 448 (const_string "true") 449 ] 450 (const_string "false"))) 451 452;; Indicates if an FP operation has an integer source. 453 454(define_attr "fp_int_src" "false,true" 455 (const_string "false")) 456 457;; Defines rounding mode of an FP operation. 458 459(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any" 460 (const_string "any")) 461 462;; Describe a user's asm statement. 463(define_asm_attributes 464 [(set_attr "length" "128") 465 (set_attr "type" "multi")]) 466 467;; All x87 floating point modes 468(define_mode_macro X87MODEF [SF DF XF]) 469 470;; All integer modes handled by x87 fisttp operator. 471(define_mode_macro X87MODEI [HI SI DI]) 472 473;; All integer modes handled by integer x87 operators. 474(define_mode_macro X87MODEI12 [HI SI]) 475 476;; All SSE floating point modes 477(define_mode_macro SSEMODEF [SF DF]) 478 479;; All integer modes handled by SSE cvtts?2si* operators. 480(define_mode_macro SSEMODEI24 [SI DI]) 481 482 483;; Scheduling descriptions 484 485(include "pentium.md") 486(include "ppro.md") 487(include "k6.md") 488(include "athlon.md") 489(include "geode.md") 490 491 492;; Operand and operator predicates and constraints 493 494(include "predicates.md") 495(include "constraints.md") 496 497 498;; Compare instructions. 499 500;; All compare insns have expanders that save the operands away without 501;; actually generating RTL. The bCOND or sCOND (emitted immediately 502;; after the cmp) will actually emit the cmpM. 503 504(define_expand "cmpti" 505 [(set (reg:CC FLAGS_REG) 506 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "") 507 (match_operand:TI 1 "x86_64_general_operand" "")))] 508 "TARGET_64BIT" 509{ 510 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 511 operands[0] = force_reg (TImode, operands[0]); 512 ix86_compare_op0 = operands[0]; 513 ix86_compare_op1 = operands[1]; 514 DONE; 515}) 516 517(define_expand "cmpdi" 518 [(set (reg:CC FLAGS_REG) 519 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "") 520 (match_operand:DI 1 "x86_64_general_operand" "")))] 521 "" 522{ 523 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 524 operands[0] = force_reg (DImode, operands[0]); 525 ix86_compare_op0 = operands[0]; 526 ix86_compare_op1 = operands[1]; 527 DONE; 528}) 529 530(define_expand "cmpsi" 531 [(set (reg:CC FLAGS_REG) 532 (compare:CC (match_operand:SI 0 "cmpsi_operand" "") 533 (match_operand:SI 1 "general_operand" "")))] 534 "" 535{ 536 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 537 operands[0] = force_reg (SImode, operands[0]); 538 ix86_compare_op0 = operands[0]; 539 ix86_compare_op1 = operands[1]; 540 DONE; 541}) 542 543(define_expand "cmphi" 544 [(set (reg:CC FLAGS_REG) 545 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "") 546 (match_operand:HI 1 "general_operand" "")))] 547 "" 548{ 549 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 550 operands[0] = force_reg (HImode, operands[0]); 551 ix86_compare_op0 = operands[0]; 552 ix86_compare_op1 = operands[1]; 553 DONE; 554}) 555 556(define_expand "cmpqi" 557 [(set (reg:CC FLAGS_REG) 558 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "") 559 (match_operand:QI 1 "general_operand" "")))] 560 "TARGET_QIMODE_MATH" 561{ 562 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 563 operands[0] = force_reg (QImode, operands[0]); 564 ix86_compare_op0 = operands[0]; 565 ix86_compare_op1 = operands[1]; 566 DONE; 567}) 568 569(define_insn "cmpdi_ccno_1_rex64" 570 [(set (reg FLAGS_REG) 571 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr") 572 (match_operand:DI 1 "const0_operand" "n,n")))] 573 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 574 "@ 575 test{q}\t{%0, %0|%0, %0} 576 cmp{q}\t{%1, %0|%0, %1}" 577 [(set_attr "type" "test,icmp") 578 (set_attr "length_immediate" "0,1") 579 (set_attr "mode" "DI")]) 580 581(define_insn "*cmpdi_minus_1_rex64" 582 [(set (reg FLAGS_REG) 583 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r") 584 (match_operand:DI 1 "x86_64_general_operand" "re,mr")) 585 (const_int 0)))] 586 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)" 587 "cmp{q}\t{%1, %0|%0, %1}" 588 [(set_attr "type" "icmp") 589 (set_attr "mode" "DI")]) 590 591(define_expand "cmpdi_1_rex64" 592 [(set (reg:CC FLAGS_REG) 593 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "") 594 (match_operand:DI 1 "general_operand" "")))] 595 "TARGET_64BIT" 596 "") 597 598(define_insn "cmpdi_1_insn_rex64" 599 [(set (reg FLAGS_REG) 600 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r") 601 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))] 602 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 603 "cmp{q}\t{%1, %0|%0, %1}" 604 [(set_attr "type" "icmp") 605 (set_attr "mode" "DI")]) 606 607 608(define_insn "*cmpsi_ccno_1" 609 [(set (reg FLAGS_REG) 610 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr") 611 (match_operand:SI 1 "const0_operand" "n,n")))] 612 "ix86_match_ccmode (insn, CCNOmode)" 613 "@ 614 test{l}\t{%0, %0|%0, %0} 615 cmp{l}\t{%1, %0|%0, %1}" 616 [(set_attr "type" "test,icmp") 617 (set_attr "length_immediate" "0,1") 618 (set_attr "mode" "SI")]) 619 620(define_insn "*cmpsi_minus_1" 621 [(set (reg FLAGS_REG) 622 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r") 623 (match_operand:SI 1 "general_operand" "ri,mr")) 624 (const_int 0)))] 625 "ix86_match_ccmode (insn, CCGOCmode)" 626 "cmp{l}\t{%1, %0|%0, %1}" 627 [(set_attr "type" "icmp") 628 (set_attr "mode" "SI")]) 629 630(define_expand "cmpsi_1" 631 [(set (reg:CC FLAGS_REG) 632 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r") 633 (match_operand:SI 1 "general_operand" "ri,mr")))] 634 "" 635 "") 636 637(define_insn "*cmpsi_1_insn" 638 [(set (reg FLAGS_REG) 639 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r") 640 (match_operand:SI 1 "general_operand" "ri,mr")))] 641 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 642 && ix86_match_ccmode (insn, CCmode)" 643 "cmp{l}\t{%1, %0|%0, %1}" 644 [(set_attr "type" "icmp") 645 (set_attr "mode" "SI")]) 646 647(define_insn "*cmphi_ccno_1" 648 [(set (reg FLAGS_REG) 649 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr") 650 (match_operand:HI 1 "const0_operand" "n,n")))] 651 "ix86_match_ccmode (insn, CCNOmode)" 652 "@ 653 test{w}\t{%0, %0|%0, %0} 654 cmp{w}\t{%1, %0|%0, %1}" 655 [(set_attr "type" "test,icmp") 656 (set_attr "length_immediate" "0,1") 657 (set_attr "mode" "HI")]) 658 659(define_insn "*cmphi_minus_1" 660 [(set (reg FLAGS_REG) 661 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r") 662 (match_operand:HI 1 "general_operand" "ri,mr")) 663 (const_int 0)))] 664 "ix86_match_ccmode (insn, CCGOCmode)" 665 "cmp{w}\t{%1, %0|%0, %1}" 666 [(set_attr "type" "icmp") 667 (set_attr "mode" "HI")]) 668 669(define_insn "*cmphi_1" 670 [(set (reg FLAGS_REG) 671 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r") 672 (match_operand:HI 1 "general_operand" "ri,mr")))] 673 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 674 && ix86_match_ccmode (insn, CCmode)" 675 "cmp{w}\t{%1, %0|%0, %1}" 676 [(set_attr "type" "icmp") 677 (set_attr "mode" "HI")]) 678 679(define_insn "*cmpqi_ccno_1" 680 [(set (reg FLAGS_REG) 681 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq") 682 (match_operand:QI 1 "const0_operand" "n,n")))] 683 "ix86_match_ccmode (insn, CCNOmode)" 684 "@ 685 test{b}\t{%0, %0|%0, %0} 686 cmp{b}\t{$0, %0|%0, 0}" 687 [(set_attr "type" "test,icmp") 688 (set_attr "length_immediate" "0,1") 689 (set_attr "mode" "QI")]) 690 691(define_insn "*cmpqi_1" 692 [(set (reg FLAGS_REG) 693 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q") 694 (match_operand:QI 1 "general_operand" "qi,mq")))] 695 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 696 && ix86_match_ccmode (insn, CCmode)" 697 "cmp{b}\t{%1, %0|%0, %1}" 698 [(set_attr "type" "icmp") 699 (set_attr "mode" "QI")]) 700 701(define_insn "*cmpqi_minus_1" 702 [(set (reg FLAGS_REG) 703 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q") 704 (match_operand:QI 1 "general_operand" "qi,mq")) 705 (const_int 0)))] 706 "ix86_match_ccmode (insn, CCGOCmode)" 707 "cmp{b}\t{%1, %0|%0, %1}" 708 [(set_attr "type" "icmp") 709 (set_attr "mode" "QI")]) 710 711(define_insn "*cmpqi_ext_1" 712 [(set (reg FLAGS_REG) 713 (compare 714 (match_operand:QI 0 "general_operand" "Qm") 715 (subreg:QI 716 (zero_extract:SI 717 (match_operand 1 "ext_register_operand" "Q") 718 (const_int 8) 719 (const_int 8)) 0)))] 720 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 721 "cmp{b}\t{%h1, %0|%0, %h1}" 722 [(set_attr "type" "icmp") 723 (set_attr "mode" "QI")]) 724 725(define_insn "*cmpqi_ext_1_rex64" 726 [(set (reg FLAGS_REG) 727 (compare 728 (match_operand:QI 0 "register_operand" "Q") 729 (subreg:QI 730 (zero_extract:SI 731 (match_operand 1 "ext_register_operand" "Q") 732 (const_int 8) 733 (const_int 8)) 0)))] 734 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 735 "cmp{b}\t{%h1, %0|%0, %h1}" 736 [(set_attr "type" "icmp") 737 (set_attr "mode" "QI")]) 738 739(define_insn "*cmpqi_ext_2" 740 [(set (reg FLAGS_REG) 741 (compare 742 (subreg:QI 743 (zero_extract:SI 744 (match_operand 0 "ext_register_operand" "Q") 745 (const_int 8) 746 (const_int 8)) 0) 747 (match_operand:QI 1 "const0_operand" "n")))] 748 "ix86_match_ccmode (insn, CCNOmode)" 749 "test{b}\t%h0, %h0" 750 [(set_attr "type" "test") 751 (set_attr "length_immediate" "0") 752 (set_attr "mode" "QI")]) 753 754(define_expand "cmpqi_ext_3" 755 [(set (reg:CC FLAGS_REG) 756 (compare:CC 757 (subreg:QI 758 (zero_extract:SI 759 (match_operand 0 "ext_register_operand" "") 760 (const_int 8) 761 (const_int 8)) 0) 762 (match_operand:QI 1 "general_operand" "")))] 763 "" 764 "") 765 766(define_insn "cmpqi_ext_3_insn" 767 [(set (reg FLAGS_REG) 768 (compare 769 (subreg:QI 770 (zero_extract:SI 771 (match_operand 0 "ext_register_operand" "Q") 772 (const_int 8) 773 (const_int 8)) 0) 774 (match_operand:QI 1 "general_operand" "Qmn")))] 775 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 776 "cmp{b}\t{%1, %h0|%h0, %1}" 777 [(set_attr "type" "icmp") 778 (set_attr "mode" "QI")]) 779 780(define_insn "cmpqi_ext_3_insn_rex64" 781 [(set (reg FLAGS_REG) 782 (compare 783 (subreg:QI 784 (zero_extract:SI 785 (match_operand 0 "ext_register_operand" "Q") 786 (const_int 8) 787 (const_int 8)) 0) 788 (match_operand:QI 1 "nonmemory_operand" "Qn")))] 789 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 790 "cmp{b}\t{%1, %h0|%h0, %1}" 791 [(set_attr "type" "icmp") 792 (set_attr "mode" "QI")]) 793 794(define_insn "*cmpqi_ext_4" 795 [(set (reg FLAGS_REG) 796 (compare 797 (subreg:QI 798 (zero_extract:SI 799 (match_operand 0 "ext_register_operand" "Q") 800 (const_int 8) 801 (const_int 8)) 0) 802 (subreg:QI 803 (zero_extract:SI 804 (match_operand 1 "ext_register_operand" "Q") 805 (const_int 8) 806 (const_int 8)) 0)))] 807 "ix86_match_ccmode (insn, CCmode)" 808 "cmp{b}\t{%h1, %h0|%h0, %h1}" 809 [(set_attr "type" "icmp") 810 (set_attr "mode" "QI")]) 811 812;; These implement float point compares. 813;; %%% See if we can get away with VOIDmode operands on the actual insns, 814;; which would allow mix and match FP modes on the compares. Which is what 815;; the old patterns did, but with many more of them. 816 817(define_expand "cmpxf" 818 [(set (reg:CC FLAGS_REG) 819 (compare:CC (match_operand:XF 0 "nonmemory_operand" "") 820 (match_operand:XF 1 "nonmemory_operand" "")))] 821 "TARGET_80387" 822{ 823 ix86_compare_op0 = operands[0]; 824 ix86_compare_op1 = operands[1]; 825 DONE; 826}) 827 828(define_expand "cmpdf" 829 [(set (reg:CC FLAGS_REG) 830 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "") 831 (match_operand:DF 1 "cmp_fp_expander_operand" "")))] 832 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 833{ 834 ix86_compare_op0 = operands[0]; 835 ix86_compare_op1 = operands[1]; 836 DONE; 837}) 838 839(define_expand "cmpsf" 840 [(set (reg:CC FLAGS_REG) 841 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "") 842 (match_operand:SF 1 "cmp_fp_expander_operand" "")))] 843 "TARGET_80387 || TARGET_SSE_MATH" 844{ 845 ix86_compare_op0 = operands[0]; 846 ix86_compare_op1 = operands[1]; 847 DONE; 848}) 849 850;; FP compares, step 1: 851;; Set the FP condition codes. 852;; 853;; CCFPmode compare with exceptions 854;; CCFPUmode compare with no exceptions 855 856;; We may not use "#" to split and emit these, since the REG_DEAD notes 857;; used to manage the reg stack popping would not be preserved. 858 859(define_insn "*cmpfp_0" 860 [(set (match_operand:HI 0 "register_operand" "=a") 861 (unspec:HI 862 [(compare:CCFP 863 (match_operand 1 "register_operand" "f") 864 (match_operand 2 "const0_operand" "X"))] 865 UNSPEC_FNSTSW))] 866 "TARGET_80387 867 && FLOAT_MODE_P (GET_MODE (operands[1])) 868 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 869 "* return output_fp_compare (insn, operands, 0, 0);" 870 [(set_attr "type" "multi") 871 (set_attr "unit" "i387") 872 (set (attr "mode") 873 (cond [(match_operand:SF 1 "" "") 874 (const_string "SF") 875 (match_operand:DF 1 "" "") 876 (const_string "DF") 877 ] 878 (const_string "XF")))]) 879 880(define_insn "*cmpfp_sf" 881 [(set (match_operand:HI 0 "register_operand" "=a") 882 (unspec:HI 883 [(compare:CCFP 884 (match_operand:SF 1 "register_operand" "f") 885 (match_operand:SF 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" "SF")]) 892 893(define_insn "*cmpfp_df" 894 [(set (match_operand:HI 0 "register_operand" "=a") 895 (unspec:HI 896 [(compare:CCFP 897 (match_operand:DF 1 "register_operand" "f") 898 (match_operand:DF 2 "nonimmediate_operand" "fm"))] 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" "DF")]) 905 906(define_insn "*cmpfp_xf" 907 [(set (match_operand:HI 0 "register_operand" "=a") 908 (unspec:HI 909 [(compare:CCFP 910 (match_operand:XF 1 "register_operand" "f") 911 (match_operand:XF 2 "register_operand" "f"))] 912 UNSPEC_FNSTSW))] 913 "TARGET_80387" 914 "* return output_fp_compare (insn, operands, 0, 0);" 915 [(set_attr "type" "multi") 916 (set_attr "unit" "i387") 917 (set_attr "mode" "XF")]) 918 919(define_insn "*cmpfp_u" 920 [(set (match_operand:HI 0 "register_operand" "=a") 921 (unspec:HI 922 [(compare:CCFPU 923 (match_operand 1 "register_operand" "f") 924 (match_operand 2 "register_operand" "f"))] 925 UNSPEC_FNSTSW))] 926 "TARGET_80387 927 && FLOAT_MODE_P (GET_MODE (operands[1])) 928 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 929 "* return output_fp_compare (insn, operands, 0, 1);" 930 [(set_attr "type" "multi") 931 (set_attr "unit" "i387") 932 (set (attr "mode") 933 (cond [(match_operand:SF 1 "" "") 934 (const_string "SF") 935 (match_operand:DF 1 "" "") 936 (const_string "DF") 937 ] 938 (const_string "XF")))]) 939 940(define_insn "*cmpfp_<mode>" 941 [(set (match_operand:HI 0 "register_operand" "=a") 942 (unspec:HI 943 [(compare:CCFP 944 (match_operand 1 "register_operand" "f") 945 (match_operator 3 "float_operator" 946 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))] 947 UNSPEC_FNSTSW))] 948 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 949 && FLOAT_MODE_P (GET_MODE (operands[1])) 950 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))" 951 "* return output_fp_compare (insn, operands, 0, 0);" 952 [(set_attr "type" "multi") 953 (set_attr "unit" "i387") 954 (set_attr "fp_int_src" "true") 955 (set_attr "mode" "<MODE>")]) 956 957;; FP compares, step 2 958;; Move the fpsw to ax. 959 960(define_insn "x86_fnstsw_1" 961 [(set (match_operand:HI 0 "register_operand" "=a") 962 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))] 963 "TARGET_80387" 964 "fnstsw\t%0" 965 [(set_attr "length" "2") 966 (set_attr "mode" "SI") 967 (set_attr "unit" "i387")]) 968 969;; FP compares, step 3 970;; Get ax into flags, general case. 971 972(define_insn "x86_sahf_1" 973 [(set (reg:CC FLAGS_REG) 974 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))] 975 "!TARGET_64BIT" 976 "sahf" 977 [(set_attr "length" "1") 978 (set_attr "athlon_decode" "vector") 979 (set_attr "amdfam10_decode" "direct") 980 (set_attr "mode" "SI")]) 981 982;; Pentium Pro can do steps 1 through 3 in one go. 983;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 984(define_insn "*cmpfp_i_mixed" 985 [(set (reg:CCFP FLAGS_REG) 986 (compare:CCFP (match_operand 0 "register_operand" "f,x") 987 (match_operand 1 "nonimmediate_operand" "f,xm")))] 988 "TARGET_MIX_SSE_I387 989 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 990 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 991 "* return output_fp_compare (insn, operands, 1, 0);" 992 [(set_attr "type" "fcmp,ssecomi") 993 (set (attr "mode") 994 (if_then_else (match_operand:SF 1 "" "") 995 (const_string "SF") 996 (const_string "DF"))) 997 (set_attr "athlon_decode" "vector") 998 (set_attr "amdfam10_decode" "direct")]) 999 1000(define_insn "*cmpfp_i_sse" 1001 [(set (reg:CCFP FLAGS_REG) 1002 (compare:CCFP (match_operand 0 "register_operand" "x") 1003 (match_operand 1 "nonimmediate_operand" "xm")))] 1004 "TARGET_SSE_MATH 1005 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1006 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1007 "* return output_fp_compare (insn, operands, 1, 0);" 1008 [(set_attr "type" "ssecomi") 1009 (set (attr "mode") 1010 (if_then_else (match_operand:SF 1 "" "") 1011 (const_string "SF") 1012 (const_string "DF"))) 1013 (set_attr "athlon_decode" "vector") 1014 (set_attr "amdfam10_decode" "direct")]) 1015 1016(define_insn "*cmpfp_i_i387" 1017 [(set (reg:CCFP FLAGS_REG) 1018 (compare:CCFP (match_operand 0 "register_operand" "f") 1019 (match_operand 1 "register_operand" "f")))] 1020 "TARGET_80387 && TARGET_CMOVE 1021 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))) 1022 && FLOAT_MODE_P (GET_MODE (operands[0])) 1023 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1024 "* return output_fp_compare (insn, operands, 1, 0);" 1025 [(set_attr "type" "fcmp") 1026 (set (attr "mode") 1027 (cond [(match_operand:SF 1 "" "") 1028 (const_string "SF") 1029 (match_operand:DF 1 "" "") 1030 (const_string "DF") 1031 ] 1032 (const_string "XF"))) 1033 (set_attr "athlon_decode" "vector") 1034 (set_attr "amdfam10_decode" "direct")]) 1035 1036(define_insn "*cmpfp_iu_mixed" 1037 [(set (reg:CCFPU FLAGS_REG) 1038 (compare:CCFPU (match_operand 0 "register_operand" "f,x") 1039 (match_operand 1 "nonimmediate_operand" "f,xm")))] 1040 "TARGET_MIX_SSE_I387 1041 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1042 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1043 "* return output_fp_compare (insn, operands, 1, 1);" 1044 [(set_attr "type" "fcmp,ssecomi") 1045 (set (attr "mode") 1046 (if_then_else (match_operand:SF 1 "" "") 1047 (const_string "SF") 1048 (const_string "DF"))) 1049 (set_attr "athlon_decode" "vector") 1050 (set_attr "amdfam10_decode" "direct")]) 1051 1052(define_insn "*cmpfp_iu_sse" 1053 [(set (reg:CCFPU FLAGS_REG) 1054 (compare:CCFPU (match_operand 0 "register_operand" "x") 1055 (match_operand 1 "nonimmediate_operand" "xm")))] 1056 "TARGET_SSE_MATH 1057 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1058 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1059 "* return output_fp_compare (insn, operands, 1, 1);" 1060 [(set_attr "type" "ssecomi") 1061 (set (attr "mode") 1062 (if_then_else (match_operand:SF 1 "" "") 1063 (const_string "SF") 1064 (const_string "DF"))) 1065 (set_attr "athlon_decode" "vector") 1066 (set_attr "amdfam10_decode" "direct")]) 1067 1068(define_insn "*cmpfp_iu_387" 1069 [(set (reg:CCFPU FLAGS_REG) 1070 (compare:CCFPU (match_operand 0 "register_operand" "f") 1071 (match_operand 1 "register_operand" "f")))] 1072 "TARGET_80387 && TARGET_CMOVE 1073 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))) 1074 && FLOAT_MODE_P (GET_MODE (operands[0])) 1075 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1076 "* return output_fp_compare (insn, operands, 1, 1);" 1077 [(set_attr "type" "fcmp") 1078 (set (attr "mode") 1079 (cond [(match_operand:SF 1 "" "") 1080 (const_string "SF") 1081 (match_operand:DF 1 "" "") 1082 (const_string "DF") 1083 ] 1084 (const_string "XF"))) 1085 (set_attr "athlon_decode" "vector") 1086 (set_attr "amdfam10_decode" "direct")]) 1087 1088;; Move instructions. 1089 1090;; General case of fullword move. 1091 1092(define_expand "movsi" 1093 [(set (match_operand:SI 0 "nonimmediate_operand" "") 1094 (match_operand:SI 1 "general_operand" ""))] 1095 "" 1096 "ix86_expand_move (SImode, operands); DONE;") 1097 1098;; Push/pop instructions. They are separate since autoinc/dec is not a 1099;; general_operand. 1100;; 1101;; %%% We don't use a post-inc memory reference because x86 is not a 1102;; general AUTO_INC_DEC host, which impacts how it is treated in flow. 1103;; Changing this impacts compiler performance on other non-AUTO_INC_DEC 1104;; targets without our curiosities, and it is just as easy to represent 1105;; this differently. 1106 1107(define_insn "*pushsi2" 1108 [(set (match_operand:SI 0 "push_operand" "=<") 1109 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))] 1110 "!TARGET_64BIT" 1111 "push{l}\t%1" 1112 [(set_attr "type" "push") 1113 (set_attr "mode" "SI")]) 1114 1115;; For 64BIT abi we always round up to 8 bytes. 1116(define_insn "*pushsi2_rex64" 1117 [(set (match_operand:SI 0 "push_operand" "=X") 1118 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))] 1119 "TARGET_64BIT" 1120 "push{q}\t%q1" 1121 [(set_attr "type" "push") 1122 (set_attr "mode" "SI")]) 1123 1124(define_insn "*pushsi2_prologue" 1125 [(set (match_operand:SI 0 "push_operand" "=<") 1126 (match_operand:SI 1 "general_no_elim_operand" "ri*m")) 1127 (clobber (mem:BLK (scratch)))] 1128 "!TARGET_64BIT" 1129 "push{l}\t%1" 1130 [(set_attr "type" "push") 1131 (set_attr "mode" "SI")]) 1132 1133(define_insn "*popsi1_epilogue" 1134 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m") 1135 (mem:SI (reg:SI SP_REG))) 1136 (set (reg:SI SP_REG) 1137 (plus:SI (reg:SI SP_REG) (const_int 4))) 1138 (clobber (mem:BLK (scratch)))] 1139 "!TARGET_64BIT" 1140 "pop{l}\t%0" 1141 [(set_attr "type" "pop") 1142 (set_attr "mode" "SI")]) 1143 1144(define_insn "popsi1" 1145 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m") 1146 (mem:SI (reg:SI SP_REG))) 1147 (set (reg:SI SP_REG) 1148 (plus:SI (reg:SI SP_REG) (const_int 4)))] 1149 "!TARGET_64BIT" 1150 "pop{l}\t%0" 1151 [(set_attr "type" "pop") 1152 (set_attr "mode" "SI")]) 1153 1154(define_insn "*movsi_xor" 1155 [(set (match_operand:SI 0 "register_operand" "=r") 1156 (match_operand:SI 1 "const0_operand" "i")) 1157 (clobber (reg:CC FLAGS_REG))] 1158 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)" 1159 "xor{l}\t{%0, %0|%0, %0}" 1160 [(set_attr "type" "alu1") 1161 (set_attr "mode" "SI") 1162 (set_attr "length_immediate" "0")]) 1163 1164(define_insn "*movsi_or" 1165 [(set (match_operand:SI 0 "register_operand" "=r") 1166 (match_operand:SI 1 "immediate_operand" "i")) 1167 (clobber (reg:CC FLAGS_REG))] 1168 "reload_completed 1169 && operands[1] == constm1_rtx 1170 && (TARGET_PENTIUM || optimize_size)" 1171{ 1172 operands[1] = constm1_rtx; 1173 return "or{l}\t{%1, %0|%0, %1}"; 1174} 1175 [(set_attr "type" "alu1") 1176 (set_attr "mode" "SI") 1177 (set_attr "length_immediate" "1")]) 1178 1179(define_insn "*movsi_1" 1180 [(set (match_operand:SI 0 "nonimmediate_operand" 1181 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x") 1182 (match_operand:SI 1 "general_operand" 1183 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))] 1184 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 1185{ 1186 switch (get_attr_type (insn)) 1187 { 1188 case TYPE_SSELOG1: 1189 if (get_attr_mode (insn) == MODE_TI) 1190 return "pxor\t%0, %0"; 1191 return "xorps\t%0, %0"; 1192 1193 case TYPE_SSEMOV: 1194 switch (get_attr_mode (insn)) 1195 { 1196 case MODE_TI: 1197 return "movdqa\t{%1, %0|%0, %1}"; 1198 case MODE_V4SF: 1199 return "movaps\t{%1, %0|%0, %1}"; 1200 case MODE_SI: 1201 return "movd\t{%1, %0|%0, %1}"; 1202 case MODE_SF: 1203 return "movss\t{%1, %0|%0, %1}"; 1204 default: 1205 gcc_unreachable (); 1206 } 1207 1208 case TYPE_MMXADD: 1209 return "pxor\t%0, %0"; 1210 1211 case TYPE_MMXMOV: 1212 if (get_attr_mode (insn) == MODE_DI) 1213 return "movq\t{%1, %0|%0, %1}"; 1214 return "movd\t{%1, %0|%0, %1}"; 1215 1216 case TYPE_LEA: 1217 return "lea{l}\t{%1, %0|%0, %1}"; 1218 1219 default: 1220 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 1221 return "mov{l}\t{%1, %0|%0, %1}"; 1222 } 1223} 1224 [(set (attr "type") 1225 (cond [(eq_attr "alternative" "2") 1226 (const_string "mmxadd") 1227 (eq_attr "alternative" "3,4,5") 1228 (const_string "mmxmov") 1229 (eq_attr "alternative" "6") 1230 (const_string "sselog1") 1231 (eq_attr "alternative" "7,8,9,10,11") 1232 (const_string "ssemov") 1233 (match_operand:DI 1 "pic_32bit_operand" "") 1234 (const_string "lea") 1235 ] 1236 (const_string "imov"))) 1237 (set (attr "mode") 1238 (cond [(eq_attr "alternative" "2,3") 1239 (const_string "DI") 1240 (eq_attr "alternative" "6,7") 1241 (if_then_else 1242 (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 1243 (const_string "V4SF") 1244 (const_string "TI")) 1245 (and (eq_attr "alternative" "8,9,10,11") 1246 (eq (symbol_ref "TARGET_SSE2") (const_int 0))) 1247 (const_string "SF") 1248 ] 1249 (const_string "SI")))]) 1250 1251;; Stores and loads of ax to arbitrary constant address. 1252;; We fake an second form of instruction to force reload to load address 1253;; into register when rax is not available 1254(define_insn "*movabssi_1_rex64" 1255 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 1256 (match_operand:SI 1 "nonmemory_operand" "a,er"))] 1257 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 1258 "@ 1259 movabs{l}\t{%1, %P0|%P0, %1} 1260 mov{l}\t{%1, %a0|%a0, %1}" 1261 [(set_attr "type" "imov") 1262 (set_attr "modrm" "0,*") 1263 (set_attr "length_address" "8,0") 1264 (set_attr "length_immediate" "0,*") 1265 (set_attr "memory" "store") 1266 (set_attr "mode" "SI")]) 1267 1268(define_insn "*movabssi_2_rex64" 1269 [(set (match_operand:SI 0 "register_operand" "=a,r") 1270 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 1271 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 1272 "@ 1273 movabs{l}\t{%P1, %0|%0, %P1} 1274 mov{l}\t{%a1, %0|%0, %a1}" 1275 [(set_attr "type" "imov") 1276 (set_attr "modrm" "0,*") 1277 (set_attr "length_address" "8,0") 1278 (set_attr "length_immediate" "0") 1279 (set_attr "memory" "load") 1280 (set_attr "mode" "SI")]) 1281 1282(define_insn "*swapsi" 1283 [(set (match_operand:SI 0 "register_operand" "+r") 1284 (match_operand:SI 1 "register_operand" "+r")) 1285 (set (match_dup 1) 1286 (match_dup 0))] 1287 "" 1288 "xchg{l}\t%1, %0" 1289 [(set_attr "type" "imov") 1290 (set_attr "mode" "SI") 1291 (set_attr "pent_pair" "np") 1292 (set_attr "athlon_decode" "vector") 1293 (set_attr "amdfam10_decode" "double")]) 1294 1295(define_expand "movhi" 1296 [(set (match_operand:HI 0 "nonimmediate_operand" "") 1297 (match_operand:HI 1 "general_operand" ""))] 1298 "" 1299 "ix86_expand_move (HImode, operands); DONE;") 1300 1301(define_insn "*pushhi2" 1302 [(set (match_operand:HI 0 "push_operand" "=X") 1303 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))] 1304 "!TARGET_64BIT" 1305 "push{l}\t%k1" 1306 [(set_attr "type" "push") 1307 (set_attr "mode" "SI")]) 1308 1309;; For 64BIT abi we always round up to 8 bytes. 1310(define_insn "*pushhi2_rex64" 1311 [(set (match_operand:HI 0 "push_operand" "=X") 1312 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))] 1313 "TARGET_64BIT" 1314 "push{q}\t%q1" 1315 [(set_attr "type" "push") 1316 (set_attr "mode" "DI")]) 1317 1318(define_insn "*movhi_1" 1319 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") 1320 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))] 1321 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 1322{ 1323 switch (get_attr_type (insn)) 1324 { 1325 case TYPE_IMOVX: 1326 /* movzwl is faster than movw on p2 due to partial word stalls, 1327 though not as fast as an aligned movl. */ 1328 return "movz{wl|x}\t{%1, %k0|%k0, %1}"; 1329 default: 1330 if (get_attr_mode (insn) == MODE_SI) 1331 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 1332 else 1333 return "mov{w}\t{%1, %0|%0, %1}"; 1334 } 1335} 1336 [(set (attr "type") 1337 (cond [(ne (symbol_ref "optimize_size") (const_int 0)) 1338 (const_string "imov") 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 "imov") 1345 (and (eq_attr "alternative" "1,2") 1346 (match_operand:HI 1 "aligned_operand" "")) 1347 (const_string "imov") 1348 (and (ne (symbol_ref "TARGET_MOVX") 1349 (const_int 0)) 1350 (eq_attr "alternative" "0,2")) 1351 (const_string "imovx") 1352 ] 1353 (const_string "imov"))) 1354 (set (attr "mode") 1355 (cond [(eq_attr "type" "imovx") 1356 (const_string "SI") 1357 (and (eq_attr "alternative" "1,2") 1358 (match_operand:HI 1 "aligned_operand" "")) 1359 (const_string "SI") 1360 (and (eq_attr "alternative" "0") 1361 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1362 (const_int 0)) 1363 (eq (symbol_ref "TARGET_HIMODE_MATH") 1364 (const_int 0)))) 1365 (const_string "SI") 1366 ] 1367 (const_string "HI")))]) 1368 1369;; Stores and loads of ax to arbitrary constant address. 1370;; We fake an second form of instruction to force reload to load address 1371;; into register when rax is not available 1372(define_insn "*movabshi_1_rex64" 1373 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 1374 (match_operand:HI 1 "nonmemory_operand" "a,er"))] 1375 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 1376 "@ 1377 movabs{w}\t{%1, %P0|%P0, %1} 1378 mov{w}\t{%1, %a0|%a0, %1}" 1379 [(set_attr "type" "imov") 1380 (set_attr "modrm" "0,*") 1381 (set_attr "length_address" "8,0") 1382 (set_attr "length_immediate" "0,*") 1383 (set_attr "memory" "store") 1384 (set_attr "mode" "HI")]) 1385 1386(define_insn "*movabshi_2_rex64" 1387 [(set (match_operand:HI 0 "register_operand" "=a,r") 1388 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 1389 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 1390 "@ 1391 movabs{w}\t{%P1, %0|%0, %P1} 1392 mov{w}\t{%a1, %0|%0, %a1}" 1393 [(set_attr "type" "imov") 1394 (set_attr "modrm" "0,*") 1395 (set_attr "length_address" "8,0") 1396 (set_attr "length_immediate" "0") 1397 (set_attr "memory" "load") 1398 (set_attr "mode" "HI")]) 1399 1400(define_insn "*swaphi_1" 1401 [(set (match_operand:HI 0 "register_operand" "+r") 1402 (match_operand:HI 1 "register_operand" "+r")) 1403 (set (match_dup 1) 1404 (match_dup 0))] 1405 "!TARGET_PARTIAL_REG_STALL || optimize_size" 1406 "xchg{l}\t%k1, %k0" 1407 [(set_attr "type" "imov") 1408 (set_attr "mode" "SI") 1409 (set_attr "pent_pair" "np") 1410 (set_attr "athlon_decode" "vector") 1411 (set_attr "amdfam10_decode" "double")]) 1412 1413;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10 1414(define_insn "*swaphi_2" 1415 [(set (match_operand:HI 0 "register_operand" "+r") 1416 (match_operand:HI 1 "register_operand" "+r")) 1417 (set (match_dup 1) 1418 (match_dup 0))] 1419 "TARGET_PARTIAL_REG_STALL" 1420 "xchg{w}\t%1, %0" 1421 [(set_attr "type" "imov") 1422 (set_attr "mode" "HI") 1423 (set_attr "pent_pair" "np") 1424 (set_attr "athlon_decode" "vector")]) 1425 1426(define_expand "movstricthi" 1427 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "")) 1428 (match_operand:HI 1 "general_operand" ""))] 1429 "! TARGET_PARTIAL_REG_STALL || optimize_size" 1430{ 1431 /* Don't generate memory->memory moves, go through a register */ 1432 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 1433 operands[1] = force_reg (HImode, operands[1]); 1434}) 1435 1436(define_insn "*movstricthi_1" 1437 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r")) 1438 (match_operand:HI 1 "general_operand" "rn,m"))] 1439 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 1440 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 1441 "mov{w}\t{%1, %0|%0, %1}" 1442 [(set_attr "type" "imov") 1443 (set_attr "mode" "HI")]) 1444 1445(define_insn "*movstricthi_xor" 1446 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) 1447 (match_operand:HI 1 "const0_operand" "i")) 1448 (clobber (reg:CC FLAGS_REG))] 1449 "reload_completed 1450 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)" 1451 "xor{w}\t{%0, %0|%0, %0}" 1452 [(set_attr "type" "alu1") 1453 (set_attr "mode" "HI") 1454 (set_attr "length_immediate" "0")]) 1455 1456(define_expand "movqi" 1457 [(set (match_operand:QI 0 "nonimmediate_operand" "") 1458 (match_operand:QI 1 "general_operand" ""))] 1459 "" 1460 "ix86_expand_move (QImode, operands); DONE;") 1461 1462;; emit_push_insn when it calls move_by_pieces requires an insn to 1463;; "push a byte". But actually we use pushl, which has the effect 1464;; of rounding the amount pushed up to a word. 1465 1466(define_insn "*pushqi2" 1467 [(set (match_operand:QI 0 "push_operand" "=X") 1468 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))] 1469 "!TARGET_64BIT" 1470 "push{l}\t%k1" 1471 [(set_attr "type" "push") 1472 (set_attr "mode" "SI")]) 1473 1474;; For 64BIT abi we always round up to 8 bytes. 1475(define_insn "*pushqi2_rex64" 1476 [(set (match_operand:QI 0 "push_operand" "=X") 1477 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))] 1478 "TARGET_64BIT" 1479 "push{q}\t%q1" 1480 [(set_attr "type" "push") 1481 (set_attr "mode" "DI")]) 1482 1483;; Situation is quite tricky about when to choose full sized (SImode) move 1484;; over QImode moves. For Q_REG -> Q_REG move we use full size only for 1485;; partial register dependency machines (such as AMD Athlon), where QImode 1486;; moves issue extra dependency and for partial register stalls machines 1487;; that don't use QImode patterns (and QImode move cause stall on the next 1488;; instruction). 1489;; 1490;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial 1491;; register stall machines with, where we use QImode instructions, since 1492;; partial register stall can be caused there. Then we use movzx. 1493(define_insn "*movqi_1" 1494 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m") 1495 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))] 1496 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 1497{ 1498 switch (get_attr_type (insn)) 1499 { 1500 case TYPE_IMOVX: 1501 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM); 1502 return "movz{bl|x}\t{%1, %k0|%k0, %1}"; 1503 default: 1504 if (get_attr_mode (insn) == MODE_SI) 1505 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 1506 else 1507 return "mov{b}\t{%1, %0|%0, %1}"; 1508 } 1509} 1510 [(set (attr "type") 1511 (cond [(and (eq_attr "alternative" "5") 1512 (not (match_operand:QI 1 "aligned_operand" ""))) 1513 (const_string "imovx") 1514 (ne (symbol_ref "optimize_size") (const_int 0)) 1515 (const_string "imov") 1516 (and (eq_attr "alternative" "3") 1517 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1518 (const_int 0)) 1519 (eq (symbol_ref "TARGET_QIMODE_MATH") 1520 (const_int 0)))) 1521 (const_string "imov") 1522 (eq_attr "alternative" "3,5") 1523 (const_string "imovx") 1524 (and (ne (symbol_ref "TARGET_MOVX") 1525 (const_int 0)) 1526 (eq_attr "alternative" "2")) 1527 (const_string "imovx") 1528 ] 1529 (const_string "imov"))) 1530 (set (attr "mode") 1531 (cond [(eq_attr "alternative" "3,4,5") 1532 (const_string "SI") 1533 (eq_attr "alternative" "6") 1534 (const_string "QI") 1535 (eq_attr "type" "imovx") 1536 (const_string "SI") 1537 (and (eq_attr "type" "imov") 1538 (and (eq_attr "alternative" "0,1") 1539 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY") 1540 (const_int 0)) 1541 (and (eq (symbol_ref "optimize_size") 1542 (const_int 0)) 1543 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1544 (const_int 0)))))) 1545 (const_string "SI") 1546 ;; Avoid partial register stalls when not using QImode arithmetic 1547 (and (eq_attr "type" "imov") 1548 (and (eq_attr "alternative" "0,1") 1549 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL") 1550 (const_int 0)) 1551 (eq (symbol_ref "TARGET_QIMODE_MATH") 1552 (const_int 0))))) 1553 (const_string "SI") 1554 ] 1555 (const_string "QI")))]) 1556 1557(define_expand "reload_outqi" 1558 [(parallel [(match_operand:QI 0 "" "=m") 1559 (match_operand:QI 1 "register_operand" "r") 1560 (match_operand:QI 2 "register_operand" "=&q")])] 1561 "" 1562{ 1563 rtx op0, op1, op2; 1564 op0 = operands[0]; op1 = operands[1]; op2 = operands[2]; 1565 1566 gcc_assert (!reg_overlap_mentioned_p (op2, op0)); 1567 if (! q_regs_operand (op1, QImode)) 1568 { 1569 emit_insn (gen_movqi (op2, op1)); 1570 op1 = op2; 1571 } 1572 emit_insn (gen_movqi (op0, op1)); 1573 DONE; 1574}) 1575 1576(define_insn "*swapqi_1" 1577 [(set (match_operand:QI 0 "register_operand" "+r") 1578 (match_operand:QI 1 "register_operand" "+r")) 1579 (set (match_dup 1) 1580 (match_dup 0))] 1581 "!TARGET_PARTIAL_REG_STALL || optimize_size" 1582 "xchg{l}\t%k1, %k0" 1583 [(set_attr "type" "imov") 1584 (set_attr "mode" "SI") 1585 (set_attr "pent_pair" "np") 1586 (set_attr "athlon_decode" "vector") 1587 (set_attr "amdfam10_decode" "vector")]) 1588 1589;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10 1590(define_insn "*swapqi_2" 1591 [(set (match_operand:QI 0 "register_operand" "+q") 1592 (match_operand:QI 1 "register_operand" "+q")) 1593 (set (match_dup 1) 1594 (match_dup 0))] 1595 "TARGET_PARTIAL_REG_STALL" 1596 "xchg{b}\t%1, %0" 1597 [(set_attr "type" "imov") 1598 (set_attr "mode" "QI") 1599 (set_attr "pent_pair" "np") 1600 (set_attr "athlon_decode" "vector")]) 1601 1602(define_expand "movstrictqi" 1603 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 1604 (match_operand:QI 1 "general_operand" ""))] 1605 "! TARGET_PARTIAL_REG_STALL || optimize_size" 1606{ 1607 /* Don't generate memory->memory moves, go through a register. */ 1608 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 1609 operands[1] = force_reg (QImode, operands[1]); 1610}) 1611 1612(define_insn "*movstrictqi_1" 1613 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 1614 (match_operand:QI 1 "general_operand" "*qn,m"))] 1615 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 1616 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 1617 "mov{b}\t{%1, %0|%0, %1}" 1618 [(set_attr "type" "imov") 1619 (set_attr "mode" "QI")]) 1620 1621(define_insn "*movstrictqi_xor" 1622 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q")) 1623 (match_operand:QI 1 "const0_operand" "i")) 1624 (clobber (reg:CC FLAGS_REG))] 1625 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)" 1626 "xor{b}\t{%0, %0|%0, %0}" 1627 [(set_attr "type" "alu1") 1628 (set_attr "mode" "QI") 1629 (set_attr "length_immediate" "0")]) 1630 1631(define_insn "*movsi_extv_1" 1632 [(set (match_operand:SI 0 "register_operand" "=R") 1633 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q") 1634 (const_int 8) 1635 (const_int 8)))] 1636 "" 1637 "movs{bl|x}\t{%h1, %0|%0, %h1}" 1638 [(set_attr "type" "imovx") 1639 (set_attr "mode" "SI")]) 1640 1641(define_insn "*movhi_extv_1" 1642 [(set (match_operand:HI 0 "register_operand" "=R") 1643 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q") 1644 (const_int 8) 1645 (const_int 8)))] 1646 "" 1647 "movs{bl|x}\t{%h1, %k0|%k0, %h1}" 1648 [(set_attr "type" "imovx") 1649 (set_attr "mode" "SI")]) 1650 1651(define_insn "*movqi_extv_1" 1652 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r") 1653 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") 1654 (const_int 8) 1655 (const_int 8)))] 1656 "!TARGET_64BIT" 1657{ 1658 switch (get_attr_type (insn)) 1659 { 1660 case TYPE_IMOVX: 1661 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; 1662 default: 1663 return "mov{b}\t{%h1, %0|%0, %h1}"; 1664 } 1665} 1666 [(set (attr "type") 1667 (if_then_else (and (match_operand:QI 0 "register_operand" "") 1668 (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1669 (ne (symbol_ref "TARGET_MOVX") 1670 (const_int 0)))) 1671 (const_string "imovx") 1672 (const_string "imov"))) 1673 (set (attr "mode") 1674 (if_then_else (eq_attr "type" "imovx") 1675 (const_string "SI") 1676 (const_string "QI")))]) 1677 1678(define_insn "*movqi_extv_1_rex64" 1679 [(set (match_operand:QI 0 "register_operand" "=Q,?R") 1680 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") 1681 (const_int 8) 1682 (const_int 8)))] 1683 "TARGET_64BIT" 1684{ 1685 switch (get_attr_type (insn)) 1686 { 1687 case TYPE_IMOVX: 1688 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; 1689 default: 1690 return "mov{b}\t{%h1, %0|%0, %h1}"; 1691 } 1692} 1693 [(set (attr "type") 1694 (if_then_else (and (match_operand:QI 0 "register_operand" "") 1695 (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1696 (ne (symbol_ref "TARGET_MOVX") 1697 (const_int 0)))) 1698 (const_string "imovx") 1699 (const_string "imov"))) 1700 (set (attr "mode") 1701 (if_then_else (eq_attr "type" "imovx") 1702 (const_string "SI") 1703 (const_string "QI")))]) 1704 1705;; Stores and loads of ax to arbitrary constant address. 1706;; We fake an second form of instruction to force reload to load address 1707;; into register when rax is not available 1708(define_insn "*movabsqi_1_rex64" 1709 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 1710 (match_operand:QI 1 "nonmemory_operand" "a,er"))] 1711 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 1712 "@ 1713 movabs{b}\t{%1, %P0|%P0, %1} 1714 mov{b}\t{%1, %a0|%a0, %1}" 1715 [(set_attr "type" "imov") 1716 (set_attr "modrm" "0,*") 1717 (set_attr "length_address" "8,0") 1718 (set_attr "length_immediate" "0,*") 1719 (set_attr "memory" "store") 1720 (set_attr "mode" "QI")]) 1721 1722(define_insn "*movabsqi_2_rex64" 1723 [(set (match_operand:QI 0 "register_operand" "=a,r") 1724 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 1725 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 1726 "@ 1727 movabs{b}\t{%P1, %0|%0, %P1} 1728 mov{b}\t{%a1, %0|%0, %a1}" 1729 [(set_attr "type" "imov") 1730 (set_attr "modrm" "0,*") 1731 (set_attr "length_address" "8,0") 1732 (set_attr "length_immediate" "0") 1733 (set_attr "memory" "load") 1734 (set_attr "mode" "QI")]) 1735 1736(define_insn "*movdi_extzv_1" 1737 [(set (match_operand:DI 0 "register_operand" "=R") 1738 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q") 1739 (const_int 8) 1740 (const_int 8)))] 1741 "TARGET_64BIT" 1742 "movz{bl|x}\t{%h1, %k0|%k0, %h1}" 1743 [(set_attr "type" "imovx") 1744 (set_attr "mode" "DI")]) 1745 1746(define_insn "*movsi_extzv_1" 1747 [(set (match_operand:SI 0 "register_operand" "=R") 1748 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q") 1749 (const_int 8) 1750 (const_int 8)))] 1751 "" 1752 "movz{bl|x}\t{%h1, %0|%0, %h1}" 1753 [(set_attr "type" "imovx") 1754 (set_attr "mode" "SI")]) 1755 1756(define_insn "*movqi_extzv_2" 1757 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R") 1758 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") 1759 (const_int 8) 1760 (const_int 8)) 0))] 1761 "!TARGET_64BIT" 1762{ 1763 switch (get_attr_type (insn)) 1764 { 1765 case TYPE_IMOVX: 1766 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 1767 default: 1768 return "mov{b}\t{%h1, %0|%0, %h1}"; 1769 } 1770} 1771 [(set (attr "type") 1772 (if_then_else (and (match_operand:QI 0 "register_operand" "") 1773 (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1774 (ne (symbol_ref "TARGET_MOVX") 1775 (const_int 0)))) 1776 (const_string "imovx") 1777 (const_string "imov"))) 1778 (set (attr "mode") 1779 (if_then_else (eq_attr "type" "imovx") 1780 (const_string "SI") 1781 (const_string "QI")))]) 1782 1783(define_insn "*movqi_extzv_2_rex64" 1784 [(set (match_operand:QI 0 "register_operand" "=Q,?R") 1785 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") 1786 (const_int 8) 1787 (const_int 8)) 0))] 1788 "TARGET_64BIT" 1789{ 1790 switch (get_attr_type (insn)) 1791 { 1792 case TYPE_IMOVX: 1793 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 1794 default: 1795 return "mov{b}\t{%h1, %0|%0, %h1}"; 1796 } 1797} 1798 [(set (attr "type") 1799 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1800 (ne (symbol_ref "TARGET_MOVX") 1801 (const_int 0))) 1802 (const_string "imovx") 1803 (const_string "imov"))) 1804 (set (attr "mode") 1805 (if_then_else (eq_attr "type" "imovx") 1806 (const_string "SI") 1807 (const_string "QI")))]) 1808 1809(define_insn "movsi_insv_1" 1810 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 1811 (const_int 8) 1812 (const_int 8)) 1813 (match_operand:SI 1 "general_operand" "Qmn"))] 1814 "!TARGET_64BIT" 1815 "mov{b}\t{%b1, %h0|%h0, %b1}" 1816 [(set_attr "type" "imov") 1817 (set_attr "mode" "QI")]) 1818 1819(define_insn "movdi_insv_1_rex64" 1820 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q") 1821 (const_int 8) 1822 (const_int 8)) 1823 (match_operand:DI 1 "nonmemory_operand" "Qn"))] 1824 "TARGET_64BIT" 1825 "mov{b}\t{%b1, %h0|%h0, %b1}" 1826 [(set_attr "type" "imov") 1827 (set_attr "mode" "QI")]) 1828 1829(define_insn "*movqi_insv_2" 1830 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 1831 (const_int 8) 1832 (const_int 8)) 1833 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q") 1834 (const_int 8)))] 1835 "" 1836 "mov{b}\t{%h1, %h0|%h0, %h1}" 1837 [(set_attr "type" "imov") 1838 (set_attr "mode" "QI")]) 1839 1840(define_expand "movdi" 1841 [(set (match_operand:DI 0 "nonimmediate_operand" "") 1842 (match_operand:DI 1 "general_operand" ""))] 1843 "" 1844 "ix86_expand_move (DImode, operands); DONE;") 1845 1846(define_insn "*pushdi" 1847 [(set (match_operand:DI 0 "push_operand" "=<") 1848 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))] 1849 "!TARGET_64BIT" 1850 "#") 1851 1852(define_insn "*pushdi2_rex64" 1853 [(set (match_operand:DI 0 "push_operand" "=<,!<") 1854 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))] 1855 "TARGET_64BIT" 1856 "@ 1857 push{q}\t%1 1858 #" 1859 [(set_attr "type" "push,multi") 1860 (set_attr "mode" "DI")]) 1861 1862;; Convert impossible pushes of immediate to existing instructions. 1863;; First try to get scratch register and go through it. In case this 1864;; fails, push sign extended lower part first and then overwrite 1865;; upper part by 32bit move. 1866(define_peephole2 1867 [(match_scratch:DI 2 "r") 1868 (set (match_operand:DI 0 "push_operand" "") 1869 (match_operand:DI 1 "immediate_operand" ""))] 1870 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1871 && !x86_64_immediate_operand (operands[1], DImode)" 1872 [(set (match_dup 2) (match_dup 1)) 1873 (set (match_dup 0) (match_dup 2))] 1874 "") 1875 1876;; We need to define this as both peepholer and splitter for case 1877;; peephole2 pass is not run. 1878;; "&& 1" is needed to keep it from matching the previous pattern. 1879(define_peephole2 1880 [(set (match_operand:DI 0 "push_operand" "") 1881 (match_operand:DI 1 "immediate_operand" ""))] 1882 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1883 && !x86_64_immediate_operand (operands[1], DImode) && 1" 1884 [(set (match_dup 0) (match_dup 1)) 1885 (set (match_dup 2) (match_dup 3))] 1886 "split_di (operands + 1, 1, operands + 2, operands + 3); 1887 operands[1] = gen_lowpart (DImode, operands[2]); 1888 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, 1889 GEN_INT (4))); 1890 ") 1891 1892(define_split 1893 [(set (match_operand:DI 0 "push_operand" "") 1894 (match_operand:DI 1 "immediate_operand" ""))] 1895 "TARGET_64BIT && ((optimize > 0 && flag_peephole2) 1896 ? flow2_completed : reload_completed) 1897 && !symbolic_operand (operands[1], DImode) 1898 && !x86_64_immediate_operand (operands[1], DImode)" 1899 [(set (match_dup 0) (match_dup 1)) 1900 (set (match_dup 2) (match_dup 3))] 1901 "split_di (operands + 1, 1, operands + 2, operands + 3); 1902 operands[1] = gen_lowpart (DImode, operands[2]); 1903 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, 1904 GEN_INT (4))); 1905 ") 1906 1907(define_insn "*pushdi2_prologue_rex64" 1908 [(set (match_operand:DI 0 "push_operand" "=<") 1909 (match_operand:DI 1 "general_no_elim_operand" "re*m")) 1910 (clobber (mem:BLK (scratch)))] 1911 "TARGET_64BIT" 1912 "push{q}\t%1" 1913 [(set_attr "type" "push") 1914 (set_attr "mode" "DI")]) 1915 1916(define_insn "*popdi1_epilogue_rex64" 1917 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m") 1918 (mem:DI (reg:DI SP_REG))) 1919 (set (reg:DI SP_REG) 1920 (plus:DI (reg:DI SP_REG) (const_int 8))) 1921 (clobber (mem:BLK (scratch)))] 1922 "TARGET_64BIT" 1923 "pop{q}\t%0" 1924 [(set_attr "type" "pop") 1925 (set_attr "mode" "DI")]) 1926 1927(define_insn "popdi1" 1928 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m") 1929 (mem:DI (reg:DI SP_REG))) 1930 (set (reg:DI SP_REG) 1931 (plus:DI (reg:DI SP_REG) (const_int 8)))] 1932 "TARGET_64BIT" 1933 "pop{q}\t%0" 1934 [(set_attr "type" "pop") 1935 (set_attr "mode" "DI")]) 1936 1937(define_insn "*movdi_xor_rex64" 1938 [(set (match_operand:DI 0 "register_operand" "=r") 1939 (match_operand:DI 1 "const0_operand" "i")) 1940 (clobber (reg:CC FLAGS_REG))] 1941 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size) 1942 && reload_completed" 1943 "xor{l}\t{%k0, %k0|%k0, %k0}" 1944 [(set_attr "type" "alu1") 1945 (set_attr "mode" "SI") 1946 (set_attr "length_immediate" "0")]) 1947 1948(define_insn "*movdi_or_rex64" 1949 [(set (match_operand:DI 0 "register_operand" "=r") 1950 (match_operand:DI 1 "const_int_operand" "i")) 1951 (clobber (reg:CC FLAGS_REG))] 1952 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size) 1953 && reload_completed 1954 && operands[1] == constm1_rtx" 1955{ 1956 operands[1] = constm1_rtx; 1957 return "or{q}\t{%1, %0|%0, %1}"; 1958} 1959 [(set_attr "type" "alu1") 1960 (set_attr "mode" "DI") 1961 (set_attr "length_immediate" "1")]) 1962 1963(define_insn "*movdi_2" 1964 [(set (match_operand:DI 0 "nonimmediate_operand" 1965 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x") 1966 (match_operand:DI 1 "general_operand" 1967 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))] 1968 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1969 "@ 1970 # 1971 # 1972 pxor\t%0, %0 1973 movq\t{%1, %0|%0, %1} 1974 movq\t{%1, %0|%0, %1} 1975 pxor\t%0, %0 1976 movq\t{%1, %0|%0, %1} 1977 movdqa\t{%1, %0|%0, %1} 1978 movq\t{%1, %0|%0, %1} 1979 xorps\t%0, %0 1980 movlps\t{%1, %0|%0, %1} 1981 movaps\t{%1, %0|%0, %1} 1982 movlps\t{%1, %0|%0, %1}" 1983 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov") 1984 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")]) 1985 1986(define_split 1987 [(set (match_operand:DI 0 "push_operand" "") 1988 (match_operand:DI 1 "general_operand" ""))] 1989 "!TARGET_64BIT && reload_completed 1990 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))" 1991 [(const_int 0)] 1992 "ix86_split_long_move (operands); DONE;") 1993 1994;; %%% This multiword shite has got to go. 1995(define_split 1996 [(set (match_operand:DI 0 "nonimmediate_operand" "") 1997 (match_operand:DI 1 "general_operand" ""))] 1998 "!TARGET_64BIT && reload_completed 1999 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0])) 2000 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))" 2001 [(const_int 0)] 2002 "ix86_split_long_move (operands); DONE;") 2003 2004(define_insn "*movdi_1_rex64" 2005 [(set (match_operand:DI 0 "nonimmediate_operand" 2006 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y") 2007 (match_operand:DI 1 "general_operand" 2008 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))] 2009 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 2010{ 2011 switch (get_attr_type (insn)) 2012 { 2013 case TYPE_SSECVT: 2014 if (which_alternative == 13) 2015 return "movq2dq\t{%1, %0|%0, %1}"; 2016 else 2017 return "movdq2q\t{%1, %0|%0, %1}"; 2018 case TYPE_SSEMOV: 2019 if (get_attr_mode (insn) == MODE_TI) 2020 return "movdqa\t{%1, %0|%0, %1}"; 2021 /* FALLTHRU */ 2022 case TYPE_MMXMOV: 2023 /* Moves from and into integer register is done using movd opcode with 2024 REX prefix. */ 2025 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])) 2026 return "movd\t{%1, %0|%0, %1}"; 2027 return "movq\t{%1, %0|%0, %1}"; 2028 case TYPE_SSELOG1: 2029 case TYPE_MMXADD: 2030 return "pxor\t%0, %0"; 2031 case TYPE_MULTI: 2032 return "#"; 2033 case TYPE_LEA: 2034 return "lea{q}\t{%a1, %0|%0, %a1}"; 2035 default: 2036 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 2037 if (get_attr_mode (insn) == MODE_SI) 2038 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2039 else if (which_alternative == 2) 2040 return "movabs{q}\t{%1, %0|%0, %1}"; 2041 else 2042 return "mov{q}\t{%1, %0|%0, %1}"; 2043 } 2044} 2045 [(set (attr "type") 2046 (cond [(eq_attr "alternative" "5") 2047 (const_string "mmxadd") 2048 (eq_attr "alternative" "6,7,8") 2049 (const_string "mmxmov") 2050 (eq_attr "alternative" "9") 2051 (const_string "sselog1") 2052 (eq_attr "alternative" "10,11,12") 2053 (const_string "ssemov") 2054 (eq_attr "alternative" "13,14") 2055 (const_string "ssecvt") 2056 (eq_attr "alternative" "4") 2057 (const_string "multi") 2058 (match_operand:DI 1 "pic_32bit_operand" "") 2059 (const_string "lea") 2060 ] 2061 (const_string "imov"))) 2062 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*") 2063 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*") 2064 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")]) 2065 2066;; Stores and loads of ax to arbitrary constant address. 2067;; We fake an second form of instruction to force reload to load address 2068;; into register when rax is not available 2069(define_insn "*movabsdi_1_rex64" 2070 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 2071 (match_operand:DI 1 "nonmemory_operand" "a,er"))] 2072 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 2073 "@ 2074 movabs{q}\t{%1, %P0|%P0, %1} 2075 mov{q}\t{%1, %a0|%a0, %1}" 2076 [(set_attr "type" "imov") 2077 (set_attr "modrm" "0,*") 2078 (set_attr "length_address" "8,0") 2079 (set_attr "length_immediate" "0,*") 2080 (set_attr "memory" "store") 2081 (set_attr "mode" "DI")]) 2082 2083(define_insn "*movabsdi_2_rex64" 2084 [(set (match_operand:DI 0 "register_operand" "=a,r") 2085 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 2086 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 2087 "@ 2088 movabs{q}\t{%P1, %0|%0, %P1} 2089 mov{q}\t{%a1, %0|%0, %a1}" 2090 [(set_attr "type" "imov") 2091 (set_attr "modrm" "0,*") 2092 (set_attr "length_address" "8,0") 2093 (set_attr "length_immediate" "0") 2094 (set_attr "memory" "load") 2095 (set_attr "mode" "DI")]) 2096 2097;; Convert impossible stores of immediate to existing instructions. 2098;; First try to get scratch register and go through it. In case this 2099;; fails, move by 32bit parts. 2100(define_peephole2 2101 [(match_scratch:DI 2 "r") 2102 (set (match_operand:DI 0 "memory_operand" "") 2103 (match_operand:DI 1 "immediate_operand" ""))] 2104 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 2105 && !x86_64_immediate_operand (operands[1], DImode)" 2106 [(set (match_dup 2) (match_dup 1)) 2107 (set (match_dup 0) (match_dup 2))] 2108 "") 2109 2110;; We need to define this as both peepholer and splitter for case 2111;; peephole2 pass is not run. 2112;; "&& 1" is needed to keep it from matching the previous pattern. 2113(define_peephole2 2114 [(set (match_operand:DI 0 "memory_operand" "") 2115 (match_operand:DI 1 "immediate_operand" ""))] 2116 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 2117 && !x86_64_immediate_operand (operands[1], DImode) && 1" 2118 [(set (match_dup 2) (match_dup 3)) 2119 (set (match_dup 4) (match_dup 5))] 2120 "split_di (operands, 2, operands + 2, operands + 4);") 2121 2122(define_split 2123 [(set (match_operand:DI 0 "memory_operand" "") 2124 (match_operand:DI 1 "immediate_operand" ""))] 2125 "TARGET_64BIT && ((optimize > 0 && flag_peephole2) 2126 ? flow2_completed : reload_completed) 2127 && !symbolic_operand (operands[1], DImode) 2128 && !x86_64_immediate_operand (operands[1], DImode)" 2129 [(set (match_dup 2) (match_dup 3)) 2130 (set (match_dup 4) (match_dup 5))] 2131 "split_di (operands, 2, operands + 2, operands + 4);") 2132 2133(define_insn "*swapdi_rex64" 2134 [(set (match_operand:DI 0 "register_operand" "+r") 2135 (match_operand:DI 1 "register_operand" "+r")) 2136 (set (match_dup 1) 2137 (match_dup 0))] 2138 "TARGET_64BIT" 2139 "xchg{q}\t%1, %0" 2140 [(set_attr "type" "imov") 2141 (set_attr "mode" "DI") 2142 (set_attr "pent_pair" "np") 2143 (set_attr "athlon_decode" "vector") 2144 (set_attr "amdfam10_decode" "double")]) 2145 2146(define_expand "movti" 2147 [(set (match_operand:TI 0 "nonimmediate_operand" "") 2148 (match_operand:TI 1 "nonimmediate_operand" ""))] 2149 "TARGET_SSE || TARGET_64BIT" 2150{ 2151 if (TARGET_64BIT) 2152 ix86_expand_move (TImode, operands); 2153 else 2154 ix86_expand_vector_move (TImode, operands); 2155 DONE; 2156}) 2157 2158(define_insn "*movti_internal" 2159 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m") 2160 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))] 2161 "TARGET_SSE && !TARGET_64BIT 2162 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 2163{ 2164 switch (which_alternative) 2165 { 2166 case 0: 2167 if (get_attr_mode (insn) == MODE_V4SF) 2168 return "xorps\t%0, %0"; 2169 else 2170 return "pxor\t%0, %0"; 2171 case 1: 2172 case 2: 2173 if (get_attr_mode (insn) == MODE_V4SF) 2174 return "movaps\t{%1, %0|%0, %1}"; 2175 else 2176 return "movdqa\t{%1, %0|%0, %1}"; 2177 default: 2178 gcc_unreachable (); 2179 } 2180} 2181 [(set_attr "type" "sselog1,ssemov,ssemov") 2182 (set (attr "mode") 2183 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 2184 (ne (symbol_ref "optimize_size") (const_int 0))) 2185 (const_string "V4SF") 2186 (and (eq_attr "alternative" "2") 2187 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") 2188 (const_int 0))) 2189 (const_string "V4SF")] 2190 (const_string "TI")))]) 2191 2192(define_insn "*movti_rex64" 2193 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm") 2194 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))] 2195 "TARGET_64BIT 2196 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 2197{ 2198 switch (which_alternative) 2199 { 2200 case 0: 2201 case 1: 2202 return "#"; 2203 case 2: 2204 if (get_attr_mode (insn) == MODE_V4SF) 2205 return "xorps\t%0, %0"; 2206 else 2207 return "pxor\t%0, %0"; 2208 case 3: 2209 case 4: 2210 if (get_attr_mode (insn) == MODE_V4SF) 2211 return "movaps\t{%1, %0|%0, %1}"; 2212 else 2213 return "movdqa\t{%1, %0|%0, %1}"; 2214 default: 2215 gcc_unreachable (); 2216 } 2217} 2218 [(set_attr "type" "*,*,sselog1,ssemov,ssemov") 2219 (set (attr "mode") 2220 (cond [(eq_attr "alternative" "2,3") 2221 (if_then_else 2222 (ne (symbol_ref "optimize_size") 2223 (const_int 0)) 2224 (const_string "V4SF") 2225 (const_string "TI")) 2226 (eq_attr "alternative" "4") 2227 (if_then_else 2228 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") 2229 (const_int 0)) 2230 (ne (symbol_ref "optimize_size") 2231 (const_int 0))) 2232 (const_string "V4SF") 2233 (const_string "TI"))] 2234 (const_string "DI")))]) 2235 2236(define_split 2237 [(set (match_operand:TI 0 "nonimmediate_operand" "") 2238 (match_operand:TI 1 "general_operand" ""))] 2239 "reload_completed && !SSE_REG_P (operands[0]) 2240 && !SSE_REG_P (operands[1])" 2241 [(const_int 0)] 2242 "ix86_split_long_move (operands); DONE;") 2243 2244(define_expand "movsf" 2245 [(set (match_operand:SF 0 "nonimmediate_operand" "") 2246 (match_operand:SF 1 "general_operand" ""))] 2247 "" 2248 "ix86_expand_move (SFmode, operands); DONE;") 2249 2250(define_insn "*pushsf" 2251 [(set (match_operand:SF 0 "push_operand" "=<,<,<") 2252 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))] 2253 "!TARGET_64BIT" 2254{ 2255 /* Anything else should be already split before reg-stack. */ 2256 gcc_assert (which_alternative == 1); 2257 return "push{l}\t%1"; 2258} 2259 [(set_attr "type" "multi,push,multi") 2260 (set_attr "unit" "i387,*,*") 2261 (set_attr "mode" "SF,SI,SF")]) 2262 2263(define_insn "*pushsf_rex64" 2264 [(set (match_operand:SF 0 "push_operand" "=X,X,X") 2265 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))] 2266 "TARGET_64BIT" 2267{ 2268 /* Anything else should be already split before reg-stack. */ 2269 gcc_assert (which_alternative == 1); 2270 return "push{q}\t%q1"; 2271} 2272 [(set_attr "type" "multi,push,multi") 2273 (set_attr "unit" "i387,*,*") 2274 (set_attr "mode" "SF,DI,SF")]) 2275 2276(define_split 2277 [(set (match_operand:SF 0 "push_operand" "") 2278 (match_operand:SF 1 "memory_operand" ""))] 2279 "reload_completed 2280 && GET_CODE (operands[1]) == MEM 2281 && constant_pool_reference_p (operands[1])" 2282 [(set (match_dup 0) 2283 (match_dup 1))] 2284 "operands[1] = avoid_constant_pool_reference (operands[1]);") 2285 2286 2287;; %%% Kill this when call knows how to work this out. 2288(define_split 2289 [(set (match_operand:SF 0 "push_operand" "") 2290 (match_operand:SF 1 "any_fp_register_operand" ""))] 2291 "!TARGET_64BIT" 2292 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) 2293 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))]) 2294 2295(define_split 2296 [(set (match_operand:SF 0 "push_operand" "") 2297 (match_operand:SF 1 "any_fp_register_operand" ""))] 2298 "TARGET_64BIT" 2299 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 2300 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))]) 2301 2302(define_insn "*movsf_1" 2303 [(set (match_operand:SF 0 "nonimmediate_operand" 2304 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y") 2305 (match_operand:SF 1 "general_operand" 2306 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))] 2307 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 2308 && (reload_in_progress || reload_completed 2309 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2310 || GET_CODE (operands[1]) != CONST_DOUBLE 2311 || memory_operand (operands[0], SFmode))" 2312{ 2313 switch (which_alternative) 2314 { 2315 case 0: 2316 return output_387_reg_move (insn, operands); 2317 2318 case 1: 2319 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2320 return "fstp%z0\t%y0"; 2321 else 2322 return "fst%z0\t%y0"; 2323 2324 case 2: 2325 return standard_80387_constant_opcode (operands[1]); 2326 2327 case 3: 2328 case 4: 2329 return "mov{l}\t{%1, %0|%0, %1}"; 2330 case 5: 2331 if (get_attr_mode (insn) == MODE_TI) 2332 return "pxor\t%0, %0"; 2333 else 2334 return "xorps\t%0, %0"; 2335 case 6: 2336 if (get_attr_mode (insn) == MODE_V4SF) 2337 return "movaps\t{%1, %0|%0, %1}"; 2338 else 2339 return "movss\t{%1, %0|%0, %1}"; 2340 case 7: 2341 case 8: 2342 return "movss\t{%1, %0|%0, %1}"; 2343 2344 case 9: 2345 case 10: 2346 return "movd\t{%1, %0|%0, %1}"; 2347 2348 case 11: 2349 return "movq\t{%1, %0|%0, %1}"; 2350 2351 default: 2352 gcc_unreachable (); 2353 } 2354} 2355 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov") 2356 (set (attr "mode") 2357 (cond [(eq_attr "alternative" "3,4,9,10") 2358 (const_string "SI") 2359 (eq_attr "alternative" "5") 2360 (if_then_else 2361 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") 2362 (const_int 0)) 2363 (ne (symbol_ref "TARGET_SSE2") 2364 (const_int 0))) 2365 (eq (symbol_ref "optimize_size") 2366 (const_int 0))) 2367 (const_string "TI") 2368 (const_string "V4SF")) 2369 /* For architectures resolving dependencies on 2370 whole SSE registers use APS move to break dependency 2371 chains, otherwise use short move to avoid extra work. 2372 2373 Do the same for architectures resolving dependencies on 2374 the parts. While in DF mode it is better to always handle 2375 just register parts, the SF mode is different due to lack 2376 of instructions to load just part of the register. It is 2377 better to maintain the whole registers in single format 2378 to avoid problems on using packed logical operations. */ 2379 (eq_attr "alternative" "6") 2380 (if_then_else 2381 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 2382 (const_int 0)) 2383 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") 2384 (const_int 0))) 2385 (const_string "V4SF") 2386 (const_string "SF")) 2387 (eq_attr "alternative" "11") 2388 (const_string "DI")] 2389 (const_string "SF")))]) 2390 2391(define_insn "*swapsf" 2392 [(set (match_operand:SF 0 "fp_register_operand" "+f") 2393 (match_operand:SF 1 "fp_register_operand" "+f")) 2394 (set (match_dup 1) 2395 (match_dup 0))] 2396 "reload_completed || TARGET_80387" 2397{ 2398 if (STACK_TOP_P (operands[0])) 2399 return "fxch\t%1"; 2400 else 2401 return "fxch\t%0"; 2402} 2403 [(set_attr "type" "fxch") 2404 (set_attr "mode" "SF")]) 2405 2406(define_expand "movdf" 2407 [(set (match_operand:DF 0 "nonimmediate_operand" "") 2408 (match_operand:DF 1 "general_operand" ""))] 2409 "" 2410 "ix86_expand_move (DFmode, operands); DONE;") 2411 2412;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. 2413;; Size of pushdf using integer instructions is 2+2*memory operand size 2414;; On the average, pushdf using integers can be still shorter. Allow this 2415;; pattern for optimize_size too. 2416 2417(define_insn "*pushdf_nointeger" 2418 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<") 2419 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))] 2420 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES" 2421{ 2422 /* This insn should be already split before reg-stack. */ 2423 gcc_unreachable (); 2424} 2425 [(set_attr "type" "multi") 2426 (set_attr "unit" "i387,*,*,*") 2427 (set_attr "mode" "DF,SI,SI,DF")]) 2428 2429(define_insn "*pushdf_integer" 2430 [(set (match_operand:DF 0 "push_operand" "=<,<,<") 2431 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))] 2432 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES" 2433{ 2434 /* This insn should be already split before reg-stack. */ 2435 gcc_unreachable (); 2436} 2437 [(set_attr "type" "multi") 2438 (set_attr "unit" "i387,*,*") 2439 (set_attr "mode" "DF,SI,DF")]) 2440 2441;; %%% Kill this when call knows how to work this out. 2442(define_split 2443 [(set (match_operand:DF 0 "push_operand" "") 2444 (match_operand:DF 1 "any_fp_register_operand" ""))] 2445 "!TARGET_64BIT && reload_completed" 2446 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 2447 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))] 2448 "") 2449 2450(define_split 2451 [(set (match_operand:DF 0 "push_operand" "") 2452 (match_operand:DF 1 "any_fp_register_operand" ""))] 2453 "TARGET_64BIT && reload_completed" 2454 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 2455 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))] 2456 "") 2457 2458(define_split 2459 [(set (match_operand:DF 0 "push_operand" "") 2460 (match_operand:DF 1 "general_operand" ""))] 2461 "reload_completed" 2462 [(const_int 0)] 2463 "ix86_split_long_move (operands); DONE;") 2464 2465;; Moving is usually shorter when only FP registers are used. This separate 2466;; movdf pattern avoids the use of integer registers for FP operations 2467;; when optimizing for size. 2468 2469(define_insn "*movdf_nointeger" 2470 [(set (match_operand:DF 0 "nonimmediate_operand" 2471 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ") 2472 (match_operand:DF 1 "general_operand" 2473 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))] 2474 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2475 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT) 2476 && (reload_in_progress || reload_completed 2477 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2478 || GET_CODE (operands[1]) != CONST_DOUBLE 2479 || memory_operand (operands[0], DFmode))" 2480{ 2481 switch (which_alternative) 2482 { 2483 case 0: 2484 return output_387_reg_move (insn, operands); 2485 2486 case 1: 2487 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2488 return "fstp%z0\t%y0"; 2489 else 2490 return "fst%z0\t%y0"; 2491 2492 case 2: 2493 return standard_80387_constant_opcode (operands[1]); 2494 2495 case 3: 2496 case 4: 2497 return "#"; 2498 case 5: 2499 switch (get_attr_mode (insn)) 2500 { 2501 case MODE_V4SF: 2502 return "xorps\t%0, %0"; 2503 case MODE_V2DF: 2504 return "xorpd\t%0, %0"; 2505 case MODE_TI: 2506 return "pxor\t%0, %0"; 2507 default: 2508 gcc_unreachable (); 2509 } 2510 case 6: 2511 case 7: 2512 case 8: 2513 switch (get_attr_mode (insn)) 2514 { 2515 case MODE_V4SF: 2516 return "movaps\t{%1, %0|%0, %1}"; 2517 case MODE_V2DF: 2518 return "movapd\t{%1, %0|%0, %1}"; 2519 case MODE_TI: 2520 return "movdqa\t{%1, %0|%0, %1}"; 2521 case MODE_DI: 2522 return "movq\t{%1, %0|%0, %1}"; 2523 case MODE_DF: 2524 return "movsd\t{%1, %0|%0, %1}"; 2525 case MODE_V1DF: 2526 return "movlpd\t{%1, %0|%0, %1}"; 2527 case MODE_V2SF: 2528 return "movlps\t{%1, %0|%0, %1}"; 2529 default: 2530 gcc_unreachable (); 2531 } 2532 2533 default: 2534 gcc_unreachable (); 2535 } 2536} 2537 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov") 2538 (set (attr "mode") 2539 (cond [(eq_attr "alternative" "0,1,2") 2540 (const_string "DF") 2541 (eq_attr "alternative" "3,4") 2542 (const_string "SI") 2543 2544 /* For SSE1, we have many fewer alternatives. */ 2545 (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 2546 (cond [(eq_attr "alternative" "5,6") 2547 (const_string "V4SF") 2548 ] 2549 (const_string "V2SF")) 2550 2551 /* xorps is one byte shorter. */ 2552 (eq_attr "alternative" "5") 2553 (cond [(ne (symbol_ref "optimize_size") 2554 (const_int 0)) 2555 (const_string "V4SF") 2556 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") 2557 (const_int 0)) 2558 (const_string "TI") 2559 ] 2560 (const_string "V2DF")) 2561 2562 /* For architectures resolving dependencies on 2563 whole SSE registers use APD move to break dependency 2564 chains, otherwise use short move to avoid extra work. 2565 2566 movaps encodes one byte shorter. */ 2567 (eq_attr "alternative" "6") 2568 (cond 2569 [(ne (symbol_ref "optimize_size") 2570 (const_int 0)) 2571 (const_string "V4SF") 2572 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 2573 (const_int 0)) 2574 (const_string "V2DF") 2575 ] 2576 (const_string "DF")) 2577 /* For architectures resolving dependencies on register 2578 parts we may avoid extra work to zero out upper part 2579 of register. */ 2580 (eq_attr "alternative" "7") 2581 (if_then_else 2582 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") 2583 (const_int 0)) 2584 (const_string "V1DF") 2585 (const_string "DF")) 2586 ] 2587 (const_string "DF")))]) 2588 2589(define_insn "*movdf_integer" 2590 [(set (match_operand:DF 0 "nonimmediate_operand" 2591 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ") 2592 (match_operand:DF 1 "general_operand" 2593 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))] 2594 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2595 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT) 2596 && (reload_in_progress || reload_completed 2597 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2598 || GET_CODE (operands[1]) != CONST_DOUBLE 2599 || memory_operand (operands[0], DFmode))" 2600{ 2601 switch (which_alternative) 2602 { 2603 case 0: 2604 return output_387_reg_move (insn, operands); 2605 2606 case 1: 2607 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2608 return "fstp%z0\t%y0"; 2609 else 2610 return "fst%z0\t%y0"; 2611 2612 case 2: 2613 return standard_80387_constant_opcode (operands[1]); 2614 2615 case 3: 2616 case 4: 2617 return "#"; 2618 2619 case 5: 2620 switch (get_attr_mode (insn)) 2621 { 2622 case MODE_V4SF: 2623 return "xorps\t%0, %0"; 2624 case MODE_V2DF: 2625 return "xorpd\t%0, %0"; 2626 case MODE_TI: 2627 return "pxor\t%0, %0"; 2628 default: 2629 gcc_unreachable (); 2630 } 2631 case 6: 2632 case 7: 2633 case 8: 2634 switch (get_attr_mode (insn)) 2635 { 2636 case MODE_V4SF: 2637 return "movaps\t{%1, %0|%0, %1}"; 2638 case MODE_V2DF: 2639 return "movapd\t{%1, %0|%0, %1}"; 2640 case MODE_TI: 2641 return "movdqa\t{%1, %0|%0, %1}"; 2642 case MODE_DI: 2643 return "movq\t{%1, %0|%0, %1}"; 2644 case MODE_DF: 2645 return "movsd\t{%1, %0|%0, %1}"; 2646 case MODE_V1DF: 2647 return "movlpd\t{%1, %0|%0, %1}"; 2648 case MODE_V2SF: 2649 return "movlps\t{%1, %0|%0, %1}"; 2650 default: 2651 gcc_unreachable (); 2652 } 2653 2654 default: 2655 gcc_unreachable(); 2656 } 2657} 2658 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov") 2659 (set (attr "mode") 2660 (cond [(eq_attr "alternative" "0,1,2") 2661 (const_string "DF") 2662 (eq_attr "alternative" "3,4") 2663 (const_string "SI") 2664 2665 /* For SSE1, we have many fewer alternatives. */ 2666 (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 2667 (cond [(eq_attr "alternative" "5,6") 2668 (const_string "V4SF") 2669 ] 2670 (const_string "V2SF")) 2671 2672 /* xorps is one byte shorter. */ 2673 (eq_attr "alternative" "5") 2674 (cond [(ne (symbol_ref "optimize_size") 2675 (const_int 0)) 2676 (const_string "V4SF") 2677 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") 2678 (const_int 0)) 2679 (const_string "TI") 2680 ] 2681 (const_string "V2DF")) 2682 2683 /* For architectures resolving dependencies on 2684 whole SSE registers use APD move to break dependency 2685 chains, otherwise use short move to avoid extra work. 2686 2687 movaps encodes one byte shorter. */ 2688 (eq_attr "alternative" "6") 2689 (cond 2690 [(ne (symbol_ref "optimize_size") 2691 (const_int 0)) 2692 (const_string "V4SF") 2693 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 2694 (const_int 0)) 2695 (const_string "V2DF") 2696 ] 2697 (const_string "DF")) 2698 /* For architectures resolving dependencies on register 2699 parts we may avoid extra work to zero out upper part 2700 of register. */ 2701 (eq_attr "alternative" "7") 2702 (if_then_else 2703 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") 2704 (const_int 0)) 2705 (const_string "V1DF") 2706 (const_string "DF")) 2707 ] 2708 (const_string "DF")))]) 2709 2710(define_split 2711 [(set (match_operand:DF 0 "nonimmediate_operand" "") 2712 (match_operand:DF 1 "general_operand" ""))] 2713 "reload_completed 2714 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2715 && ! (ANY_FP_REG_P (operands[0]) || 2716 (GET_CODE (operands[0]) == SUBREG 2717 && ANY_FP_REG_P (SUBREG_REG (operands[0])))) 2718 && ! (ANY_FP_REG_P (operands[1]) || 2719 (GET_CODE (operands[1]) == SUBREG 2720 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))" 2721 [(const_int 0)] 2722 "ix86_split_long_move (operands); DONE;") 2723 2724(define_insn "*swapdf" 2725 [(set (match_operand:DF 0 "fp_register_operand" "+f") 2726 (match_operand:DF 1 "fp_register_operand" "+f")) 2727 (set (match_dup 1) 2728 (match_dup 0))] 2729 "reload_completed || TARGET_80387" 2730{ 2731 if (STACK_TOP_P (operands[0])) 2732 return "fxch\t%1"; 2733 else 2734 return "fxch\t%0"; 2735} 2736 [(set_attr "type" "fxch") 2737 (set_attr "mode" "DF")]) 2738 2739(define_expand "movxf" 2740 [(set (match_operand:XF 0 "nonimmediate_operand" "") 2741 (match_operand:XF 1 "general_operand" ""))] 2742 "" 2743 "ix86_expand_move (XFmode, operands); DONE;") 2744 2745;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. 2746;; Size of pushdf using integer instructions is 3+3*memory operand size 2747;; Pushing using integer instructions is longer except for constants 2748;; and direct memory references. 2749;; (assuming that any given constant is pushed only once, but this ought to be 2750;; handled elsewhere). 2751 2752(define_insn "*pushxf_nointeger" 2753 [(set (match_operand:XF 0 "push_operand" "=X,X,X") 2754 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))] 2755 "optimize_size" 2756{ 2757 /* This insn should be already split before reg-stack. */ 2758 gcc_unreachable (); 2759} 2760 [(set_attr "type" "multi") 2761 (set_attr "unit" "i387,*,*") 2762 (set_attr "mode" "XF,SI,SI")]) 2763 2764(define_insn "*pushxf_integer" 2765 [(set (match_operand:XF 0 "push_operand" "=<,<") 2766 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))] 2767 "!optimize_size" 2768{ 2769 /* This insn should be already split before reg-stack. */ 2770 gcc_unreachable (); 2771} 2772 [(set_attr "type" "multi") 2773 (set_attr "unit" "i387,*") 2774 (set_attr "mode" "XF,SI")]) 2775 2776(define_split 2777 [(set (match_operand 0 "push_operand" "") 2778 (match_operand 1 "general_operand" ""))] 2779 "reload_completed 2780 && (GET_MODE (operands[0]) == XFmode 2781 || GET_MODE (operands[0]) == DFmode) 2782 && !ANY_FP_REG_P (operands[1])" 2783 [(const_int 0)] 2784 "ix86_split_long_move (operands); DONE;") 2785 2786(define_split 2787 [(set (match_operand:XF 0 "push_operand" "") 2788 (match_operand:XF 1 "any_fp_register_operand" ""))] 2789 "!TARGET_64BIT" 2790 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2))) 2791 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))] 2792 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 2793 2794(define_split 2795 [(set (match_operand:XF 0 "push_operand" "") 2796 (match_operand:XF 1 "any_fp_register_operand" ""))] 2797 "TARGET_64BIT" 2798 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2))) 2799 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))] 2800 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 2801 2802;; Do not use integer registers when optimizing for size 2803(define_insn "*movxf_nointeger" 2804 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o") 2805 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))] 2806 "optimize_size 2807 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2808 && (reload_in_progress || reload_completed 2809 || GET_CODE (operands[1]) != CONST_DOUBLE 2810 || memory_operand (operands[0], XFmode))" 2811{ 2812 switch (which_alternative) 2813 { 2814 case 0: 2815 return output_387_reg_move (insn, operands); 2816 2817 case 1: 2818 /* There is no non-popping store to memory for XFmode. So if 2819 we need one, follow the store with a load. */ 2820 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2821 return "fstp%z0\t%y0\;fld%z0\t%y0"; 2822 else 2823 return "fstp%z0\t%y0"; 2824 2825 case 2: 2826 return standard_80387_constant_opcode (operands[1]); 2827 2828 case 3: case 4: 2829 return "#"; 2830 default: 2831 gcc_unreachable (); 2832 } 2833} 2834 [(set_attr "type" "fmov,fmov,fmov,multi,multi") 2835 (set_attr "mode" "XF,XF,XF,SI,SI")]) 2836 2837(define_insn "*movxf_integer" 2838 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o") 2839 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))] 2840 "!optimize_size 2841 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2842 && (reload_in_progress || reload_completed 2843 || GET_CODE (operands[1]) != CONST_DOUBLE 2844 || memory_operand (operands[0], XFmode))" 2845{ 2846 switch (which_alternative) 2847 { 2848 case 0: 2849 return output_387_reg_move (insn, operands); 2850 2851 case 1: 2852 /* There is no non-popping store to memory for XFmode. So if 2853 we need one, follow the store with a load. */ 2854 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2855 return "fstp%z0\t%y0\;fld%z0\t%y0"; 2856 else 2857 return "fstp%z0\t%y0"; 2858 2859 case 2: 2860 return standard_80387_constant_opcode (operands[1]); 2861 2862 case 3: case 4: 2863 return "#"; 2864 2865 default: 2866 gcc_unreachable (); 2867 } 2868} 2869 [(set_attr "type" "fmov,fmov,fmov,multi,multi") 2870 (set_attr "mode" "XF,XF,XF,SI,SI")]) 2871 2872(define_split 2873 [(set (match_operand 0 "nonimmediate_operand" "") 2874 (match_operand 1 "general_operand" ""))] 2875 "reload_completed 2876 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2877 && GET_MODE (operands[0]) == XFmode 2878 && ! (ANY_FP_REG_P (operands[0]) || 2879 (GET_CODE (operands[0]) == SUBREG 2880 && ANY_FP_REG_P (SUBREG_REG (operands[0])))) 2881 && ! (ANY_FP_REG_P (operands[1]) || 2882 (GET_CODE (operands[1]) == SUBREG 2883 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))" 2884 [(const_int 0)] 2885 "ix86_split_long_move (operands); DONE;") 2886 2887(define_split 2888 [(set (match_operand 0 "register_operand" "") 2889 (match_operand 1 "memory_operand" ""))] 2890 "reload_completed 2891 && GET_CODE (operands[1]) == MEM 2892 && (GET_MODE (operands[0]) == XFmode 2893 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode) 2894 && constant_pool_reference_p (operands[1])" 2895 [(set (match_dup 0) (match_dup 1))] 2896{ 2897 rtx c = avoid_constant_pool_reference (operands[1]); 2898 rtx r = operands[0]; 2899 2900 if (GET_CODE (r) == SUBREG) 2901 r = SUBREG_REG (r); 2902 2903 if (SSE_REG_P (r)) 2904 { 2905 if (!standard_sse_constant_p (c)) 2906 FAIL; 2907 } 2908 else if (FP_REG_P (r)) 2909 { 2910 if (!standard_80387_constant_p (c)) 2911 FAIL; 2912 } 2913 else if (MMX_REG_P (r)) 2914 FAIL; 2915 2916 operands[1] = c; 2917}) 2918 2919(define_insn "swapxf" 2920 [(set (match_operand:XF 0 "register_operand" "+f") 2921 (match_operand:XF 1 "register_operand" "+f")) 2922 (set (match_dup 1) 2923 (match_dup 0))] 2924 "TARGET_80387" 2925{ 2926 if (STACK_TOP_P (operands[0])) 2927 return "fxch\t%1"; 2928 else 2929 return "fxch\t%0"; 2930} 2931 [(set_attr "type" "fxch") 2932 (set_attr "mode" "XF")]) 2933 2934(define_expand "movtf" 2935 [(set (match_operand:TF 0 "nonimmediate_operand" "") 2936 (match_operand:TF 1 "nonimmediate_operand" ""))] 2937 "TARGET_64BIT" 2938{ 2939 ix86_expand_move (TFmode, operands); 2940 DONE; 2941}) 2942 2943(define_insn "*movtf_internal" 2944 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm") 2945 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))] 2946 "TARGET_64BIT 2947 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 2948{ 2949 switch (which_alternative) 2950 { 2951 case 0: 2952 case 1: 2953 return "#"; 2954 case 2: 2955 if (get_attr_mode (insn) == MODE_V4SF) 2956 return "xorps\t%0, %0"; 2957 else 2958 return "pxor\t%0, %0"; 2959 case 3: 2960 case 4: 2961 if (get_attr_mode (insn) == MODE_V4SF) 2962 return "movaps\t{%1, %0|%0, %1}"; 2963 else 2964 return "movdqa\t{%1, %0|%0, %1}"; 2965 default: 2966 gcc_unreachable (); 2967 } 2968} 2969 [(set_attr "type" "*,*,sselog1,ssemov,ssemov") 2970 (set (attr "mode") 2971 (cond [(eq_attr "alternative" "2,3") 2972 (if_then_else 2973 (ne (symbol_ref "optimize_size") 2974 (const_int 0)) 2975 (const_string "V4SF") 2976 (const_string "TI")) 2977 (eq_attr "alternative" "4") 2978 (if_then_else 2979 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") 2980 (const_int 0)) 2981 (ne (symbol_ref "optimize_size") 2982 (const_int 0))) 2983 (const_string "V4SF") 2984 (const_string "TI"))] 2985 (const_string "DI")))]) 2986 2987(define_split 2988 [(set (match_operand:TF 0 "nonimmediate_operand" "") 2989 (match_operand:TF 1 "general_operand" ""))] 2990 "reload_completed && !SSE_REG_P (operands[0]) 2991 && !SSE_REG_P (operands[1])" 2992 [(const_int 0)] 2993 "ix86_split_long_move (operands); DONE;") 2994 2995;; Zero extension instructions 2996 2997(define_expand "zero_extendhisi2" 2998 [(set (match_operand:SI 0 "register_operand" "") 2999 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 3000 "" 3001{ 3002 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) 3003 { 3004 operands[1] = force_reg (HImode, operands[1]); 3005 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1])); 3006 DONE; 3007 } 3008}) 3009 3010(define_insn "zero_extendhisi2_and" 3011 [(set (match_operand:SI 0 "register_operand" "=r") 3012 (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))) 3013 (clobber (reg:CC FLAGS_REG))] 3014 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 3015 "#" 3016 [(set_attr "type" "alu1") 3017 (set_attr "mode" "SI")]) 3018 3019(define_split 3020 [(set (match_operand:SI 0 "register_operand" "") 3021 (zero_extend:SI (match_operand:HI 1 "register_operand" ""))) 3022 (clobber (reg:CC FLAGS_REG))] 3023 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 3024 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535))) 3025 (clobber (reg:CC FLAGS_REG))])] 3026 "") 3027 3028(define_insn "*zero_extendhisi2_movzwl" 3029 [(set (match_operand:SI 0 "register_operand" "=r") 3030 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3031 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" 3032 "movz{wl|x}\t{%1, %0|%0, %1}" 3033 [(set_attr "type" "imovx") 3034 (set_attr "mode" "SI")]) 3035 3036(define_expand "zero_extendqihi2" 3037 [(parallel 3038 [(set (match_operand:HI 0 "register_operand" "") 3039 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) 3040 (clobber (reg:CC FLAGS_REG))])] 3041 "" 3042 "") 3043 3044(define_insn "*zero_extendqihi2_and" 3045 [(set (match_operand:HI 0 "register_operand" "=r,?&q") 3046 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) 3047 (clobber (reg:CC FLAGS_REG))] 3048 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 3049 "#" 3050 [(set_attr "type" "alu1") 3051 (set_attr "mode" "HI")]) 3052 3053(define_insn "*zero_extendqihi2_movzbw_and" 3054 [(set (match_operand:HI 0 "register_operand" "=r,r") 3055 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) 3056 (clobber (reg:CC FLAGS_REG))] 3057 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" 3058 "#" 3059 [(set_attr "type" "imovx,alu1") 3060 (set_attr "mode" "HI")]) 3061 3062; zero extend to SImode here to avoid partial register stalls 3063(define_insn "*zero_extendqihi2_movzbl" 3064 [(set (match_operand:HI 0 "register_operand" "=r") 3065 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3066 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed" 3067 "movz{bl|x}\t{%1, %k0|%k0, %k1}" 3068 [(set_attr "type" "imovx") 3069 (set_attr "mode" "SI")]) 3070 3071;; For the movzbw case strip only the clobber 3072(define_split 3073 [(set (match_operand:HI 0 "register_operand" "") 3074 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) 3075 (clobber (reg:CC FLAGS_REG))] 3076 "reload_completed 3077 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) 3078 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" 3079 [(set (match_operand:HI 0 "register_operand" "") 3080 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]) 3081 3082;; When source and destination does not overlap, clear destination 3083;; first and then do the movb 3084(define_split 3085 [(set (match_operand:HI 0 "register_operand" "") 3086 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) 3087 (clobber (reg:CC FLAGS_REG))] 3088 "reload_completed 3089 && ANY_QI_REG_P (operands[0]) 3090 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) 3091 && !reg_overlap_mentioned_p (operands[0], operands[1])" 3092 [(set (match_dup 0) (const_int 0)) 3093 (set (strict_low_part (match_dup 2)) (match_dup 1))] 3094 "operands[2] = gen_lowpart (QImode, operands[0]);") 3095 3096;; Rest is handled by single and. 3097(define_split 3098 [(set (match_operand:HI 0 "register_operand" "") 3099 (zero_extend:HI (match_operand:QI 1 "register_operand" ""))) 3100 (clobber (reg:CC FLAGS_REG))] 3101 "reload_completed 3102 && true_regnum (operands[0]) == true_regnum (operands[1])" 3103 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255))) 3104 (clobber (reg:CC FLAGS_REG))])] 3105 "") 3106 3107(define_expand "zero_extendqisi2" 3108 [(parallel 3109 [(set (match_operand:SI 0 "register_operand" "") 3110 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) 3111 (clobber (reg:CC FLAGS_REG))])] 3112 "" 3113 "") 3114 3115(define_insn "*zero_extendqisi2_and" 3116 [(set (match_operand:SI 0 "register_operand" "=r,?&q") 3117 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) 3118 (clobber (reg:CC FLAGS_REG))] 3119 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 3120 "#" 3121 [(set_attr "type" "alu1") 3122 (set_attr "mode" "SI")]) 3123 3124(define_insn "*zero_extendqisi2_movzbw_and" 3125 [(set (match_operand:SI 0 "register_operand" "=r,r") 3126 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) 3127 (clobber (reg:CC FLAGS_REG))] 3128 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" 3129 "#" 3130 [(set_attr "type" "imovx,alu1") 3131 (set_attr "mode" "SI")]) 3132 3133(define_insn "*zero_extendqisi2_movzbw" 3134 [(set (match_operand:SI 0 "register_operand" "=r") 3135 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3136 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed" 3137 "movz{bl|x}\t{%1, %0|%0, %1}" 3138 [(set_attr "type" "imovx") 3139 (set_attr "mode" "SI")]) 3140 3141;; For the movzbl case strip only the clobber 3142(define_split 3143 [(set (match_operand:SI 0 "register_operand" "") 3144 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) 3145 (clobber (reg:CC FLAGS_REG))] 3146 "reload_completed 3147 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) 3148 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" 3149 [(set (match_dup 0) 3150 (zero_extend:SI (match_dup 1)))]) 3151 3152;; When source and destination does not overlap, clear destination 3153;; first and then do the movb 3154(define_split 3155 [(set (match_operand:SI 0 "register_operand" "") 3156 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) 3157 (clobber (reg:CC FLAGS_REG))] 3158 "reload_completed 3159 && ANY_QI_REG_P (operands[0]) 3160 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM) 3161 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) 3162 && !reg_overlap_mentioned_p (operands[0], operands[1])" 3163 [(set (match_dup 0) (const_int 0)) 3164 (set (strict_low_part (match_dup 2)) (match_dup 1))] 3165 "operands[2] = gen_lowpart (QImode, operands[0]);") 3166 3167;; Rest is handled by single and. 3168(define_split 3169 [(set (match_operand:SI 0 "register_operand" "") 3170 (zero_extend:SI (match_operand:QI 1 "register_operand" ""))) 3171 (clobber (reg:CC FLAGS_REG))] 3172 "reload_completed 3173 && true_regnum (operands[0]) == true_regnum (operands[1])" 3174 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255))) 3175 (clobber (reg:CC FLAGS_REG))])] 3176 "") 3177 3178;; %%% Kill me once multi-word ops are sane. 3179(define_expand "zero_extendsidi2" 3180 [(set (match_operand:DI 0 "register_operand" "=r") 3181 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))] 3182 "" 3183 "if (!TARGET_64BIT) 3184 { 3185 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1])); 3186 DONE; 3187 } 3188 ") 3189 3190(define_insn "zero_extendsidi2_32" 3191 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y") 3192 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm"))) 3193 (clobber (reg:CC FLAGS_REG))] 3194 "!TARGET_64BIT" 3195 "@ 3196 # 3197 # 3198 # 3199 movd\t{%1, %0|%0, %1} 3200 movd\t{%1, %0|%0, %1}" 3201 [(set_attr "mode" "SI,SI,SI,DI,TI") 3202 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")]) 3203 3204(define_insn "zero_extendsidi2_rex64" 3205 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y") 3206 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))] 3207 "TARGET_64BIT" 3208 "@ 3209 mov\t{%k1, %k0|%k0, %k1} 3210 # 3211 movd\t{%1, %0|%0, %1} 3212 movd\t{%1, %0|%0, %1}" 3213 [(set_attr "type" "imovx,imov,mmxmov,ssemov") 3214 (set_attr "mode" "SI,DI,SI,SI")]) 3215 3216(define_split 3217 [(set (match_operand:DI 0 "memory_operand" "") 3218 (zero_extend:DI (match_dup 0)))] 3219 "TARGET_64BIT" 3220 [(set (match_dup 4) (const_int 0))] 3221 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3222 3223(define_split 3224 [(set (match_operand:DI 0 "register_operand" "") 3225 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) 3226 (clobber (reg:CC FLAGS_REG))] 3227 "!TARGET_64BIT && reload_completed 3228 && true_regnum (operands[0]) == true_regnum (operands[1])" 3229 [(set (match_dup 4) (const_int 0))] 3230 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3231 3232(define_split 3233 [(set (match_operand:DI 0 "nonimmediate_operand" "") 3234 (zero_extend:DI (match_operand:SI 1 "general_operand" ""))) 3235 (clobber (reg:CC FLAGS_REG))] 3236 "!TARGET_64BIT && reload_completed 3237 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])" 3238 [(set (match_dup 3) (match_dup 1)) 3239 (set (match_dup 4) (const_int 0))] 3240 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3241 3242(define_insn "zero_extendhidi2" 3243 [(set (match_operand:DI 0 "register_operand" "=r") 3244 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3245 "TARGET_64BIT" 3246 "movz{wl|x}\t{%1, %k0|%k0, %1}" 3247 [(set_attr "type" "imovx") 3248 (set_attr "mode" "DI")]) 3249 3250(define_insn "zero_extendqidi2" 3251 [(set (match_operand:DI 0 "register_operand" "=r") 3252 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))] 3253 "TARGET_64BIT" 3254 "movz{bl|x}\t{%1, %k0|%k0, %1}" 3255 [(set_attr "type" "imovx") 3256 (set_attr "mode" "DI")]) 3257 3258;; Sign extension instructions 3259 3260(define_expand "extendsidi2" 3261 [(parallel [(set (match_operand:DI 0 "register_operand" "") 3262 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3263 (clobber (reg:CC FLAGS_REG)) 3264 (clobber (match_scratch:SI 2 ""))])] 3265 "" 3266{ 3267 if (TARGET_64BIT) 3268 { 3269 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1])); 3270 DONE; 3271 } 3272}) 3273 3274(define_insn "*extendsidi2_1" 3275 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o") 3276 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r"))) 3277 (clobber (reg:CC FLAGS_REG)) 3278 (clobber (match_scratch:SI 2 "=X,X,X,&r"))] 3279 "!TARGET_64BIT" 3280 "#") 3281 3282(define_insn "extendsidi2_rex64" 3283 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3284 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))] 3285 "TARGET_64BIT" 3286 "@ 3287 {cltq|cdqe} 3288 movs{lq|x}\t{%1,%0|%0, %1}" 3289 [(set_attr "type" "imovx") 3290 (set_attr "mode" "DI") 3291 (set_attr "prefix_0f" "0") 3292 (set_attr "modrm" "0,1")]) 3293 3294(define_insn "extendhidi2" 3295 [(set (match_operand:DI 0 "register_operand" "=r") 3296 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3297 "TARGET_64BIT" 3298 "movs{wq|x}\t{%1,%0|%0, %1}" 3299 [(set_attr "type" "imovx") 3300 (set_attr "mode" "DI")]) 3301 3302(define_insn "extendqidi2" 3303 [(set (match_operand:DI 0 "register_operand" "=r") 3304 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3305 "TARGET_64BIT" 3306 "movs{bq|x}\t{%1,%0|%0, %1}" 3307 [(set_attr "type" "imovx") 3308 (set_attr "mode" "DI")]) 3309 3310;; Extend to memory case when source register does die. 3311(define_split 3312 [(set (match_operand:DI 0 "memory_operand" "") 3313 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3314 (clobber (reg:CC FLAGS_REG)) 3315 (clobber (match_operand:SI 2 "register_operand" ""))] 3316 "(reload_completed 3317 && dead_or_set_p (insn, operands[1]) 3318 && !reg_mentioned_p (operands[1], operands[0]))" 3319 [(set (match_dup 3) (match_dup 1)) 3320 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) 3321 (clobber (reg:CC FLAGS_REG))]) 3322 (set (match_dup 4) (match_dup 1))] 3323 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3324 3325;; Extend to memory case when source register does not die. 3326(define_split 3327 [(set (match_operand:DI 0 "memory_operand" "") 3328 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3329 (clobber (reg:CC FLAGS_REG)) 3330 (clobber (match_operand:SI 2 "register_operand" ""))] 3331 "reload_completed" 3332 [(const_int 0)] 3333{ 3334 split_di (&operands[0], 1, &operands[3], &operands[4]); 3335 3336 emit_move_insn (operands[3], operands[1]); 3337 3338 /* Generate a cltd if possible and doing so it profitable. */ 3339 if (true_regnum (operands[1]) == 0 3340 && true_regnum (operands[2]) == 1 3341 && (optimize_size || TARGET_USE_CLTD)) 3342 { 3343 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31))); 3344 } 3345 else 3346 { 3347 emit_move_insn (operands[2], operands[1]); 3348 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31))); 3349 } 3350 emit_move_insn (operands[4], operands[2]); 3351 DONE; 3352}) 3353 3354;; Extend to register case. Optimize case where source and destination 3355;; registers match and cases where we can use cltd. 3356(define_split 3357 [(set (match_operand:DI 0 "register_operand" "") 3358 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3359 (clobber (reg:CC FLAGS_REG)) 3360 (clobber (match_scratch:SI 2 ""))] 3361 "reload_completed" 3362 [(const_int 0)] 3363{ 3364 split_di (&operands[0], 1, &operands[3], &operands[4]); 3365 3366 if (true_regnum (operands[3]) != true_regnum (operands[1])) 3367 emit_move_insn (operands[3], operands[1]); 3368 3369 /* Generate a cltd if possible and doing so it profitable. */ 3370 if (true_regnum (operands[3]) == 0 3371 && (optimize_size || TARGET_USE_CLTD)) 3372 { 3373 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31))); 3374 DONE; 3375 } 3376 3377 if (true_regnum (operands[4]) != true_regnum (operands[1])) 3378 emit_move_insn (operands[4], operands[1]); 3379 3380 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31))); 3381 DONE; 3382}) 3383 3384(define_insn "extendhisi2" 3385 [(set (match_operand:SI 0 "register_operand" "=*a,r") 3386 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))] 3387 "" 3388{ 3389 switch (get_attr_prefix_0f (insn)) 3390 { 3391 case 0: 3392 return "{cwtl|cwde}"; 3393 default: 3394 return "movs{wl|x}\t{%1,%0|%0, %1}"; 3395 } 3396} 3397 [(set_attr "type" "imovx") 3398 (set_attr "mode" "SI") 3399 (set (attr "prefix_0f") 3400 ;; movsx is short decodable while cwtl is vector decoded. 3401 (if_then_else (and (eq_attr "cpu" "!k6") 3402 (eq_attr "alternative" "0")) 3403 (const_string "0") 3404 (const_string "1"))) 3405 (set (attr "modrm") 3406 (if_then_else (eq_attr "prefix_0f" "0") 3407 (const_string "0") 3408 (const_string "1")))]) 3409 3410(define_insn "*extendhisi2_zext" 3411 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3412 (zero_extend:DI 3413 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))] 3414 "TARGET_64BIT" 3415{ 3416 switch (get_attr_prefix_0f (insn)) 3417 { 3418 case 0: 3419 return "{cwtl|cwde}"; 3420 default: 3421 return "movs{wl|x}\t{%1,%k0|%k0, %1}"; 3422 } 3423} 3424 [(set_attr "type" "imovx") 3425 (set_attr "mode" "SI") 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 "extendqihi2" 3438 [(set (match_operand:HI 0 "register_operand" "=*a,r") 3439 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))] 3440 "" 3441{ 3442 switch (get_attr_prefix_0f (insn)) 3443 { 3444 case 0: 3445 return "{cbtw|cbw}"; 3446 default: 3447 return "movs{bw|x}\t{%1,%0|%0, %1}"; 3448 } 3449} 3450 [(set_attr "type" "imovx") 3451 (set_attr "mode" "HI") 3452 (set (attr "prefix_0f") 3453 ;; movsx is short decodable while cwtl is vector decoded. 3454 (if_then_else (and (eq_attr "cpu" "!k6") 3455 (eq_attr "alternative" "0")) 3456 (const_string "0") 3457 (const_string "1"))) 3458 (set (attr "modrm") 3459 (if_then_else (eq_attr "prefix_0f" "0") 3460 (const_string "0") 3461 (const_string "1")))]) 3462 3463(define_insn "extendqisi2" 3464 [(set (match_operand:SI 0 "register_operand" "=r") 3465 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3466 "" 3467 "movs{bl|x}\t{%1,%0|%0, %1}" 3468 [(set_attr "type" "imovx") 3469 (set_attr "mode" "SI")]) 3470 3471(define_insn "*extendqisi2_zext" 3472 [(set (match_operand:DI 0 "register_operand" "=r") 3473 (zero_extend:DI 3474 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))] 3475 "TARGET_64BIT" 3476 "movs{bl|x}\t{%1,%k0|%k0, %1}" 3477 [(set_attr "type" "imovx") 3478 (set_attr "mode" "SI")]) 3479 3480;; Conversions between float and double. 3481 3482;; These are all no-ops in the model used for the 80387. So just 3483;; emit moves. 3484 3485;; %%% Kill these when call knows how to work out a DFmode push earlier. 3486(define_insn "*dummy_extendsfdf2" 3487 [(set (match_operand:DF 0 "push_operand" "=<") 3488 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))] 3489 "0" 3490 "#") 3491 3492(define_split 3493 [(set (match_operand:DF 0 "push_operand" "") 3494 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))] 3495 "!TARGET_64BIT" 3496 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 3497 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))]) 3498 3499(define_split 3500 [(set (match_operand:DF 0 "push_operand" "") 3501 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))] 3502 "TARGET_64BIT" 3503 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 3504 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))]) 3505 3506(define_insn "*dummy_extendsfxf2" 3507 [(set (match_operand:XF 0 "push_operand" "=<") 3508 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))] 3509 "0" 3510 "#") 3511 3512(define_split 3513 [(set (match_operand:XF 0 "push_operand" "") 3514 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))] 3515 "" 3516 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2))) 3517 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))] 3518 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3519 3520(define_split 3521 [(set (match_operand:XF 0 "push_operand" "") 3522 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))] 3523 "TARGET_64BIT" 3524 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2))) 3525 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))] 3526 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3527 3528(define_split 3529 [(set (match_operand:XF 0 "push_operand" "") 3530 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))] 3531 "" 3532 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2))) 3533 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))] 3534 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3535 3536(define_split 3537 [(set (match_operand:XF 0 "push_operand" "") 3538 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))] 3539 "TARGET_64BIT" 3540 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2))) 3541 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))] 3542 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3543 3544(define_expand "extendsfdf2" 3545 [(set (match_operand:DF 0 "nonimmediate_operand" "") 3546 (float_extend:DF (match_operand:SF 1 "general_operand" "")))] 3547 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 3548{ 3549 /* ??? Needed for compress_float_constant since all fp constants 3550 are LEGITIMATE_CONSTANT_P. */ 3551 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3552 { 3553 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387) 3554 && standard_80387_constant_p (operands[1]) > 0) 3555 { 3556 operands[1] = simplify_const_unary_operation 3557 (FLOAT_EXTEND, DFmode, operands[1], SFmode); 3558 emit_move_insn_1 (operands[0], operands[1]); 3559 DONE; 3560 } 3561 operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 3562 } 3563 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 3564 operands[1] = force_reg (SFmode, operands[1]); 3565}) 3566 3567(define_insn "*extendsfdf2_mixed" 3568 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y") 3569 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))] 3570 "TARGET_SSE2 && TARGET_MIX_SSE_I387 3571 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3572{ 3573 switch (which_alternative) 3574 { 3575 case 0: 3576 return output_387_reg_move (insn, operands); 3577 3578 case 1: 3579 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3580 return "fstp%z0\t%y0"; 3581 else 3582 return "fst%z0\t%y0"; 3583 3584 case 2: 3585 return "cvtss2sd\t{%1, %0|%0, %1}"; 3586 3587 default: 3588 gcc_unreachable (); 3589 } 3590} 3591 [(set_attr "type" "fmov,fmov,ssecvt") 3592 (set_attr "mode" "SF,XF,DF")]) 3593 3594(define_insn "*extendsfdf2_sse" 3595 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y") 3596 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))] 3597 "TARGET_SSE2 && TARGET_SSE_MATH 3598 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3599 "cvtss2sd\t{%1, %0|%0, %1}" 3600 [(set_attr "type" "ssecvt") 3601 (set_attr "mode" "DF")]) 3602 3603(define_insn "*extendsfdf2_i387" 3604 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m") 3605 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 3606 "TARGET_80387 3607 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3608{ 3609 switch (which_alternative) 3610 { 3611 case 0: 3612 return output_387_reg_move (insn, operands); 3613 3614 case 1: 3615 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3616 return "fstp%z0\t%y0"; 3617 else 3618 return "fst%z0\t%y0"; 3619 3620 default: 3621 gcc_unreachable (); 3622 } 3623} 3624 [(set_attr "type" "fmov") 3625 (set_attr "mode" "SF,XF")]) 3626 3627(define_expand "extendsfxf2" 3628 [(set (match_operand:XF 0 "nonimmediate_operand" "") 3629 (float_extend:XF (match_operand:SF 1 "general_operand" "")))] 3630 "TARGET_80387" 3631{ 3632 /* ??? Needed for compress_float_constant since all fp constants 3633 are LEGITIMATE_CONSTANT_P. */ 3634 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3635 { 3636 if (standard_80387_constant_p (operands[1]) > 0) 3637 { 3638 operands[1] = simplify_const_unary_operation 3639 (FLOAT_EXTEND, XFmode, operands[1], SFmode); 3640 emit_move_insn_1 (operands[0], operands[1]); 3641 DONE; 3642 } 3643 operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 3644 } 3645 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 3646 operands[1] = force_reg (SFmode, operands[1]); 3647}) 3648 3649(define_insn "*extendsfxf2_i387" 3650 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 3651 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 3652 "TARGET_80387 3653 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3654{ 3655 switch (which_alternative) 3656 { 3657 case 0: 3658 return output_387_reg_move (insn, operands); 3659 3660 case 1: 3661 /* There is no non-popping store to memory for XFmode. So if 3662 we need one, follow the store with a load. */ 3663 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3664 return "fstp%z0\t%y0"; 3665 else 3666 return "fstp%z0\t%y0\n\tfld%z0\t%y0"; 3667 3668 default: 3669 gcc_unreachable (); 3670 } 3671} 3672 [(set_attr "type" "fmov") 3673 (set_attr "mode" "SF,XF")]) 3674 3675(define_expand "extenddfxf2" 3676 [(set (match_operand:XF 0 "nonimmediate_operand" "") 3677 (float_extend:XF (match_operand:DF 1 "general_operand" "")))] 3678 "TARGET_80387" 3679{ 3680 /* ??? Needed for compress_float_constant since all fp constants 3681 are LEGITIMATE_CONSTANT_P. */ 3682 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3683 { 3684 if (standard_80387_constant_p (operands[1]) > 0) 3685 { 3686 operands[1] = simplify_const_unary_operation 3687 (FLOAT_EXTEND, XFmode, operands[1], DFmode); 3688 emit_move_insn_1 (operands[0], operands[1]); 3689 DONE; 3690 } 3691 operands[1] = validize_mem (force_const_mem (DFmode, operands[1])); 3692 } 3693 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 3694 operands[1] = force_reg (DFmode, operands[1]); 3695}) 3696 3697(define_insn "*extenddfxf2_i387" 3698 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 3699 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))] 3700 "TARGET_80387 3701 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3702{ 3703 switch (which_alternative) 3704 { 3705 case 0: 3706 return output_387_reg_move (insn, operands); 3707 3708 case 1: 3709 /* There is no non-popping store to memory for XFmode. So if 3710 we need one, follow the store with a load. */ 3711 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3712 return "fstp%z0\t%y0\n\tfld%z0\t%y0"; 3713 else 3714 return "fstp%z0\t%y0"; 3715 3716 default: 3717 gcc_unreachable (); 3718 } 3719} 3720 [(set_attr "type" "fmov") 3721 (set_attr "mode" "DF,XF")]) 3722 3723;; %%% This seems bad bad news. 3724;; This cannot output into an f-reg because there is no way to be sure 3725;; of truncating in that case. Otherwise this is just like a simple move 3726;; insn. So we pretend we can output to a reg in order to get better 3727;; register preferencing, but we really use a stack slot. 3728 3729;; Conversion from DFmode to SFmode. 3730 3731(define_expand "truncdfsf2" 3732 [(set (match_operand:SF 0 "nonimmediate_operand" "") 3733 (float_truncate:SF 3734 (match_operand:DF 1 "nonimmediate_operand" "")))] 3735 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 3736{ 3737 if (MEM_P (operands[0]) && MEM_P (operands[1])) 3738 operands[1] = force_reg (DFmode, operands[1]); 3739 3740 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387) 3741 ; 3742 else if (flag_unsafe_math_optimizations) 3743 ; 3744 else 3745 { 3746 rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL); 3747 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp)); 3748 DONE; 3749 } 3750}) 3751 3752(define_expand "truncdfsf2_with_temp" 3753 [(parallel [(set (match_operand:SF 0 "" "") 3754 (float_truncate:SF (match_operand:DF 1 "" ""))) 3755 (clobber (match_operand:SF 2 "" ""))])] 3756 "") 3757 3758(define_insn "*truncdfsf_fast_mixed" 3759 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y") 3760 (float_truncate:SF 3761 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))] 3762 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations" 3763{ 3764 switch (which_alternative) 3765 { 3766 case 0: 3767 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3768 return "fstp%z0\t%y0"; 3769 else 3770 return "fst%z0\t%y0"; 3771 case 1: 3772 return output_387_reg_move (insn, operands); 3773 case 2: 3774 return "cvtsd2ss\t{%1, %0|%0, %1}"; 3775 default: 3776 gcc_unreachable (); 3777 } 3778} 3779 [(set_attr "type" "fmov,fmov,ssecvt") 3780 (set_attr "mode" "SF")]) 3781 3782;; Yes, this one doesn't depend on flag_unsafe_math_optimizations, 3783;; because nothing we do here is unsafe. 3784(define_insn "*truncdfsf_fast_sse" 3785 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y") 3786 (float_truncate:SF 3787 (match_operand:DF 1 "nonimmediate_operand" "Ym")))] 3788 "TARGET_SSE2 && TARGET_SSE_MATH" 3789 "cvtsd2ss\t{%1, %0|%0, %1}" 3790 [(set_attr "type" "ssecvt") 3791 (set_attr "mode" "SF")]) 3792 3793(define_insn "*truncdfsf_fast_i387" 3794 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm") 3795 (float_truncate:SF 3796 (match_operand:DF 1 "nonimmediate_operand" "f")))] 3797 "TARGET_80387 && flag_unsafe_math_optimizations" 3798 "* return output_387_reg_move (insn, operands);" 3799 [(set_attr "type" "fmov") 3800 (set_attr "mode" "SF")]) 3801 3802(define_insn "*truncdfsf_mixed" 3803 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y") 3804 (float_truncate:SF 3805 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym"))) 3806 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))] 3807 "TARGET_MIX_SSE_I387" 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 case 2: 3819 return "cvtsd2ss\t{%1, %0|%0, %1}"; 3820 default: 3821 gcc_unreachable (); 3822 } 3823} 3824 [(set_attr "type" "fmov,multi,ssecvt") 3825 (set_attr "unit" "*,i387,*") 3826 (set_attr "mode" "SF")]) 3827 3828(define_insn "*truncdfsf_i387" 3829 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r") 3830 (float_truncate:SF 3831 (match_operand:DF 1 "nonimmediate_operand" "f,f"))) 3832 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))] 3833 "TARGET_80387" 3834{ 3835 switch (which_alternative) 3836 { 3837 case 0: 3838 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3839 return "fstp%z0\t%y0"; 3840 else 3841 return "fst%z0\t%y0"; 3842 case 1: 3843 return "#"; 3844 default: 3845 gcc_unreachable (); 3846 } 3847} 3848 [(set_attr "type" "fmov,multi") 3849 (set_attr "unit" "*,i387") 3850 (set_attr "mode" "SF")]) 3851 3852(define_insn "*truncdfsf2_i387_1" 3853 [(set (match_operand:SF 0 "memory_operand" "=m") 3854 (float_truncate:SF 3855 (match_operand:DF 1 "register_operand" "f")))] 3856 "TARGET_80387 3857 && !(TARGET_SSE2 && TARGET_SSE_MATH) 3858 && !TARGET_MIX_SSE_I387" 3859{ 3860 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3861 return "fstp%z0\t%y0"; 3862 else 3863 return "fst%z0\t%y0"; 3864} 3865 [(set_attr "type" "fmov") 3866 (set_attr "mode" "SF")]) 3867 3868(define_split 3869 [(set (match_operand:SF 0 "register_operand" "") 3870 (float_truncate:SF 3871 (match_operand:DF 1 "fp_register_operand" ""))) 3872 (clobber (match_operand 2 "" ""))] 3873 "reload_completed" 3874 [(set (match_dup 2) (match_dup 1)) 3875 (set (match_dup 0) (match_dup 2))] 3876{ 3877 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1])); 3878}) 3879 3880;; Conversion from XFmode to SFmode. 3881 3882(define_expand "truncxfsf2" 3883 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") 3884 (float_truncate:SF 3885 (match_operand:XF 1 "register_operand" ""))) 3886 (clobber (match_dup 2))])] 3887 "TARGET_80387" 3888{ 3889 if (flag_unsafe_math_optimizations) 3890 { 3891 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode); 3892 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1])); 3893 if (reg != operands[0]) 3894 emit_move_insn (operands[0], reg); 3895 DONE; 3896 } 3897 else 3898 operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL); 3899}) 3900 3901(define_insn "*truncxfsf2_mixed" 3902 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x") 3903 (float_truncate:SF 3904 (match_operand:XF 1 "register_operand" "f,f,f,f"))) 3905 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))] 3906 "TARGET_MIX_SSE_I387" 3907{ 3908 gcc_assert (!which_alternative); 3909 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3910 return "fstp%z0\t%y0"; 3911 else 3912 return "fst%z0\t%y0"; 3913} 3914 [(set_attr "type" "fmov,multi,multi,multi") 3915 (set_attr "unit" "*,i387,i387,i387") 3916 (set_attr "mode" "SF")]) 3917 3918(define_insn "truncxfsf2_i387_noop" 3919 [(set (match_operand:SF 0 "register_operand" "=f") 3920 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))] 3921 "TARGET_80387 && flag_unsafe_math_optimizations" 3922{ 3923 return output_387_reg_move (insn, operands); 3924} 3925 [(set_attr "type" "fmov") 3926 (set_attr "mode" "SF")]) 3927 3928(define_insn "*truncxfsf2_i387" 3929 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r") 3930 (float_truncate:SF 3931 (match_operand:XF 1 "register_operand" "f,f,f"))) 3932 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))] 3933 "TARGET_80387" 3934{ 3935 gcc_assert (!which_alternative); 3936 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3937 return "fstp%z0\t%y0"; 3938 else 3939 return "fst%z0\t%y0"; 3940} 3941 [(set_attr "type" "fmov,multi,multi") 3942 (set_attr "unit" "*,i387,i387") 3943 (set_attr "mode" "SF")]) 3944 3945(define_insn "*truncxfsf2_i387_1" 3946 [(set (match_operand:SF 0 "memory_operand" "=m") 3947 (float_truncate:SF 3948 (match_operand:XF 1 "register_operand" "f")))] 3949 "TARGET_80387" 3950{ 3951 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3952 return "fstp%z0\t%y0"; 3953 else 3954 return "fst%z0\t%y0"; 3955} 3956 [(set_attr "type" "fmov") 3957 (set_attr "mode" "SF")]) 3958 3959(define_split 3960 [(set (match_operand:SF 0 "register_operand" "") 3961 (float_truncate:SF 3962 (match_operand:XF 1 "register_operand" ""))) 3963 (clobber (match_operand:SF 2 "memory_operand" ""))] 3964 "TARGET_80387 && reload_completed" 3965 [(set (match_dup 2) (float_truncate:SF (match_dup 1))) 3966 (set (match_dup 0) (match_dup 2))] 3967 "") 3968 3969(define_split 3970 [(set (match_operand:SF 0 "memory_operand" "") 3971 (float_truncate:SF 3972 (match_operand:XF 1 "register_operand" ""))) 3973 (clobber (match_operand:SF 2 "memory_operand" ""))] 3974 "TARGET_80387" 3975 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))] 3976 "") 3977 3978;; Conversion from XFmode to DFmode. 3979 3980(define_expand "truncxfdf2" 3981 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "") 3982 (float_truncate:DF 3983 (match_operand:XF 1 "register_operand" ""))) 3984 (clobber (match_dup 2))])] 3985 "TARGET_80387" 3986{ 3987 if (flag_unsafe_math_optimizations) 3988 { 3989 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode); 3990 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1])); 3991 if (reg != operands[0]) 3992 emit_move_insn (operands[0], reg); 3993 DONE; 3994 } 3995 else 3996 operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL); 3997}) 3998 3999(define_insn "*truncxfdf2_mixed" 4000 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y") 4001 (float_truncate:DF 4002 (match_operand:XF 1 "register_operand" "f,f,f,f"))) 4003 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))] 4004 "TARGET_SSE2 && TARGET_MIX_SSE_I387" 4005{ 4006 gcc_assert (!which_alternative); 4007 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 4008 return "fstp%z0\t%y0"; 4009 else 4010 return "fst%z0\t%y0"; 4011} 4012 [(set_attr "type" "fmov,multi,multi,multi") 4013 (set_attr "unit" "*,i387,i387,i387") 4014 (set_attr "mode" "DF")]) 4015 4016(define_insn "truncxfdf2_i387_noop" 4017 [(set (match_operand:DF 0 "register_operand" "=f") 4018 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))] 4019 "TARGET_80387 && flag_unsafe_math_optimizations" 4020{ 4021 return output_387_reg_move (insn, operands); 4022} 4023 [(set_attr "type" "fmov") 4024 (set_attr "mode" "DF")]) 4025 4026(define_insn "*truncxfdf2_i387" 4027 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r") 4028 (float_truncate:DF 4029 (match_operand:XF 1 "register_operand" "f,f,f"))) 4030 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))] 4031 "TARGET_80387" 4032{ 4033 gcc_assert (!which_alternative); 4034 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 4035 return "fstp%z0\t%y0"; 4036 else 4037 return "fst%z0\t%y0"; 4038} 4039 [(set_attr "type" "fmov,multi,multi") 4040 (set_attr "unit" "*,i387,i387") 4041 (set_attr "mode" "DF")]) 4042 4043(define_insn "*truncxfdf2_i387_1" 4044 [(set (match_operand:DF 0 "memory_operand" "=m") 4045 (float_truncate:DF 4046 (match_operand:XF 1 "register_operand" "f")))] 4047 "TARGET_80387" 4048{ 4049 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 4050 return "fstp%z0\t%y0"; 4051 else 4052 return "fst%z0\t%y0"; 4053} 4054 [(set_attr "type" "fmov") 4055 (set_attr "mode" "DF")]) 4056 4057(define_split 4058 [(set (match_operand:DF 0 "register_operand" "") 4059 (float_truncate:DF 4060 (match_operand:XF 1 "register_operand" ""))) 4061 (clobber (match_operand:DF 2 "memory_operand" ""))] 4062 "TARGET_80387 && reload_completed" 4063 [(set (match_dup 2) (float_truncate:DF (match_dup 1))) 4064 (set (match_dup 0) (match_dup 2))] 4065 "") 4066 4067(define_split 4068 [(set (match_operand:DF 0 "memory_operand" "") 4069 (float_truncate:DF 4070 (match_operand:XF 1 "register_operand" ""))) 4071 (clobber (match_operand:DF 2 "memory_operand" ""))] 4072 "TARGET_80387" 4073 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))] 4074 "") 4075 4076;; Signed conversion to DImode. 4077 4078(define_expand "fix_truncxfdi2" 4079 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 4080 (fix:DI (match_operand:XF 1 "register_operand" ""))) 4081 (clobber (reg:CC FLAGS_REG))])] 4082 "TARGET_80387" 4083{ 4084 if (TARGET_FISTTP) 4085 { 4086 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4087 DONE; 4088 } 4089}) 4090 4091(define_expand "fix_trunc<mode>di2" 4092 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 4093 (fix:DI (match_operand:SSEMODEF 1 "register_operand" ""))) 4094 (clobber (reg:CC FLAGS_REG))])] 4095 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))" 4096{ 4097 if (TARGET_FISTTP 4098 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4099 { 4100 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4101 DONE; 4102 } 4103 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)) 4104 { 4105 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode); 4106 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1])); 4107 if (out != operands[0]) 4108 emit_move_insn (operands[0], out); 4109 DONE; 4110 } 4111}) 4112 4113;; Signed conversion to SImode. 4114 4115(define_expand "fix_truncxfsi2" 4116 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4117 (fix:SI (match_operand:XF 1 "register_operand" ""))) 4118 (clobber (reg:CC FLAGS_REG))])] 4119 "TARGET_80387" 4120{ 4121 if (TARGET_FISTTP) 4122 { 4123 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4124 DONE; 4125 } 4126}) 4127 4128(define_expand "fix_trunc<mode>si2" 4129 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4130 (fix:SI (match_operand:SSEMODEF 1 "register_operand" ""))) 4131 (clobber (reg:CC FLAGS_REG))])] 4132 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)" 4133{ 4134 if (TARGET_FISTTP 4135 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4136 { 4137 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4138 DONE; 4139 } 4140 if (SSE_FLOAT_MODE_P (<MODE>mode)) 4141 { 4142 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode); 4143 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1])); 4144 if (out != operands[0]) 4145 emit_move_insn (operands[0], out); 4146 DONE; 4147 } 4148}) 4149 4150;; Signed conversion to HImode. 4151 4152(define_expand "fix_trunc<mode>hi2" 4153 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 4154 (fix:HI (match_operand:X87MODEF 1 "register_operand" ""))) 4155 (clobber (reg:CC FLAGS_REG))])] 4156 "TARGET_80387 4157 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))" 4158{ 4159 if (TARGET_FISTTP) 4160 { 4161 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1])); 4162 DONE; 4163 } 4164}) 4165 4166;; When SSE is available, it is always faster to use it! 4167(define_insn "fix_truncsfdi_sse" 4168 [(set (match_operand:DI 0 "register_operand" "=r,r") 4169 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))] 4170 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4171 "cvttss2si{q}\t{%1, %0|%0, %1}" 4172 [(set_attr "type" "sseicvt") 4173 (set_attr "mode" "SF") 4174 (set_attr "athlon_decode" "double,vector") 4175 (set_attr "amdfam10_decode" "double,double")]) 4176 4177(define_insn "fix_truncdfdi_sse" 4178 [(set (match_operand:DI 0 "register_operand" "=r,r") 4179 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))] 4180 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4181 "cvttsd2si{q}\t{%1, %0|%0, %1}" 4182 [(set_attr "type" "sseicvt") 4183 (set_attr "mode" "DF") 4184 (set_attr "athlon_decode" "double,vector") 4185 (set_attr "amdfam10_decode" "double,double")]) 4186 4187(define_insn "fix_truncsfsi_sse" 4188 [(set (match_operand:SI 0 "register_operand" "=r,r") 4189 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))] 4190 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4191 "cvttss2si\t{%1, %0|%0, %1}" 4192 [(set_attr "type" "sseicvt") 4193 (set_attr "mode" "DF") 4194 (set_attr "athlon_decode" "double,vector") 4195 (set_attr "amdfam10_decode" "double,double")]) 4196 4197(define_insn "fix_truncdfsi_sse" 4198 [(set (match_operand:SI 0 "register_operand" "=r,r") 4199 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))] 4200 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4201 "cvttsd2si\t{%1, %0|%0, %1}" 4202 [(set_attr "type" "sseicvt") 4203 (set_attr "mode" "DF") 4204 (set_attr "athlon_decode" "double,vector") 4205 (set_attr "amdfam10_decode" "double,double")]) 4206 4207;; Avoid vector decoded forms of the instruction. 4208(define_peephole2 4209 [(match_scratch:DF 2 "Y") 4210 (set (match_operand:SSEMODEI24 0 "register_operand" "") 4211 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))] 4212 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size" 4213 [(set (match_dup 2) (match_dup 1)) 4214 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))] 4215 "") 4216 4217(define_peephole2 4218 [(match_scratch:SF 2 "x") 4219 (set (match_operand:SSEMODEI24 0 "register_operand" "") 4220 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))] 4221 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size" 4222 [(set (match_dup 2) (match_dup 1)) 4223 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))] 4224 "") 4225 4226(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1" 4227 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 4228 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))] 4229 "TARGET_FISTTP 4230 && FLOAT_MODE_P (GET_MODE (operands[1])) 4231 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4232 && (TARGET_64BIT || <MODE>mode != DImode)) 4233 && TARGET_SSE_MATH) 4234 && !(reload_completed || reload_in_progress)" 4235 "#" 4236 "&& 1" 4237 [(const_int 0)] 4238{ 4239 if (memory_operand (operands[0], VOIDmode)) 4240 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1])); 4241 else 4242 { 4243 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4244 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0], 4245 operands[1], 4246 operands[2])); 4247 } 4248 DONE; 4249} 4250 [(set_attr "type" "fisttp") 4251 (set_attr "mode" "<MODE>")]) 4252 4253(define_insn "fix_trunc<mode>_i387_fisttp" 4254 [(set (match_operand:X87MODEI 0 "memory_operand" "=m") 4255 (fix:X87MODEI (match_operand 1 "register_operand" "f"))) 4256 (clobber (match_scratch:XF 2 "=&1f"))] 4257 "TARGET_FISTTP 4258 && FLOAT_MODE_P (GET_MODE (operands[1])) 4259 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4260 && (TARGET_64BIT || <MODE>mode != DImode)) 4261 && TARGET_SSE_MATH)" 4262 "* return output_fix_trunc (insn, operands, 1);" 4263 [(set_attr "type" "fisttp") 4264 (set_attr "mode" "<MODE>")]) 4265 4266(define_insn "fix_trunc<mode>_i387_fisttp_with_temp" 4267 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 4268 (fix:X87MODEI (match_operand 1 "register_operand" "f,f"))) 4269 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m")) 4270 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 4271 "TARGET_FISTTP 4272 && FLOAT_MODE_P (GET_MODE (operands[1])) 4273 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4274 && (TARGET_64BIT || <MODE>mode != DImode)) 4275 && TARGET_SSE_MATH)" 4276 "#" 4277 [(set_attr "type" "fisttp") 4278 (set_attr "mode" "<MODE>")]) 4279 4280(define_split 4281 [(set (match_operand:X87MODEI 0 "register_operand" "") 4282 (fix:X87MODEI (match_operand 1 "register_operand" ""))) 4283 (clobber (match_operand:X87MODEI 2 "memory_operand" "")) 4284 (clobber (match_scratch 3 ""))] 4285 "reload_completed" 4286 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1))) 4287 (clobber (match_dup 3))]) 4288 (set (match_dup 0) (match_dup 2))] 4289 "") 4290 4291(define_split 4292 [(set (match_operand:X87MODEI 0 "memory_operand" "") 4293 (fix:X87MODEI (match_operand 1 "register_operand" ""))) 4294 (clobber (match_operand:X87MODEI 2 "memory_operand" "")) 4295 (clobber (match_scratch 3 ""))] 4296 "reload_completed" 4297 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1))) 4298 (clobber (match_dup 3))])] 4299 "") 4300 4301;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description 4302;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control 4303;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG 4304;; clobbering insns can be used. Look at emit_i387_cw_initialization () 4305;; function in i386.c. 4306(define_insn_and_split "*fix_trunc<mode>_i387_1" 4307 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 4308 (fix:X87MODEI (match_operand 1 "register_operand" "f,f"))) 4309 (clobber (reg:CC FLAGS_REG))] 4310 "TARGET_80387 && !TARGET_FISTTP 4311 && FLOAT_MODE_P (GET_MODE (operands[1])) 4312 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4313 && (TARGET_64BIT || <MODE>mode != DImode)) 4314 && !(reload_completed || reload_in_progress)" 4315 "#" 4316 "&& 1" 4317 [(const_int 0)] 4318{ 4319 ix86_optimize_mode_switching[I387_TRUNC] = 1; 4320 4321 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 4322 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 4323 if (memory_operand (operands[0], VOIDmode)) 4324 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1], 4325 operands[2], operands[3])); 4326 else 4327 { 4328 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4329 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1], 4330 operands[2], operands[3], 4331 operands[4])); 4332 } 4333 DONE; 4334} 4335 [(set_attr "type" "fistp") 4336 (set_attr "i387_cw" "trunc") 4337 (set_attr "mode" "<MODE>")]) 4338 4339(define_insn "fix_truncdi_i387" 4340 [(set (match_operand:DI 0 "memory_operand" "=m") 4341 (fix:DI (match_operand 1 "register_operand" "f"))) 4342 (use (match_operand:HI 2 "memory_operand" "m")) 4343 (use (match_operand:HI 3 "memory_operand" "m")) 4344 (clobber (match_scratch:XF 4 "=&1f"))] 4345 "TARGET_80387 && !TARGET_FISTTP 4346 && FLOAT_MODE_P (GET_MODE (operands[1])) 4347 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4348 "* return output_fix_trunc (insn, operands, 0);" 4349 [(set_attr "type" "fistp") 4350 (set_attr "i387_cw" "trunc") 4351 (set_attr "mode" "DI")]) 4352 4353(define_insn "fix_truncdi_i387_with_temp" 4354 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 4355 (fix:DI (match_operand 1 "register_operand" "f,f"))) 4356 (use (match_operand:HI 2 "memory_operand" "m,m")) 4357 (use (match_operand:HI 3 "memory_operand" "m,m")) 4358 (clobber (match_operand:DI 4 "memory_operand" "=m,m")) 4359 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 4360 "TARGET_80387 && !TARGET_FISTTP 4361 && FLOAT_MODE_P (GET_MODE (operands[1])) 4362 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4363 "#" 4364 [(set_attr "type" "fistp") 4365 (set_attr "i387_cw" "trunc") 4366 (set_attr "mode" "DI")]) 4367 4368(define_split 4369 [(set (match_operand:DI 0 "register_operand" "") 4370 (fix:DI (match_operand 1 "register_operand" ""))) 4371 (use (match_operand:HI 2 "memory_operand" "")) 4372 (use (match_operand:HI 3 "memory_operand" "")) 4373 (clobber (match_operand:DI 4 "memory_operand" "")) 4374 (clobber (match_scratch 5 ""))] 4375 "reload_completed" 4376 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1))) 4377 (use (match_dup 2)) 4378 (use (match_dup 3)) 4379 (clobber (match_dup 5))]) 4380 (set (match_dup 0) (match_dup 4))] 4381 "") 4382 4383(define_split 4384 [(set (match_operand:DI 0 "memory_operand" "") 4385 (fix:DI (match_operand 1 "register_operand" ""))) 4386 (use (match_operand:HI 2 "memory_operand" "")) 4387 (use (match_operand:HI 3 "memory_operand" "")) 4388 (clobber (match_operand:DI 4 "memory_operand" "")) 4389 (clobber (match_scratch 5 ""))] 4390 "reload_completed" 4391 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1))) 4392 (use (match_dup 2)) 4393 (use (match_dup 3)) 4394 (clobber (match_dup 5))])] 4395 "") 4396 4397(define_insn "fix_trunc<mode>_i387" 4398 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 4399 (fix:X87MODEI12 (match_operand 1 "register_operand" "f"))) 4400 (use (match_operand:HI 2 "memory_operand" "m")) 4401 (use (match_operand:HI 3 "memory_operand" "m"))] 4402 "TARGET_80387 && !TARGET_FISTTP 4403 && FLOAT_MODE_P (GET_MODE (operands[1])) 4404 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4405 "* return output_fix_trunc (insn, operands, 0);" 4406 [(set_attr "type" "fistp") 4407 (set_attr "i387_cw" "trunc") 4408 (set_attr "mode" "<MODE>")]) 4409 4410(define_insn "fix_trunc<mode>_i387_with_temp" 4411 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") 4412 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f"))) 4413 (use (match_operand:HI 2 "memory_operand" "m,m")) 4414 (use (match_operand:HI 3 "memory_operand" "m,m")) 4415 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))] 4416 "TARGET_80387 && !TARGET_FISTTP 4417 && FLOAT_MODE_P (GET_MODE (operands[1])) 4418 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4419 "#" 4420 [(set_attr "type" "fistp") 4421 (set_attr "i387_cw" "trunc") 4422 (set_attr "mode" "<MODE>")]) 4423 4424(define_split 4425 [(set (match_operand:X87MODEI12 0 "register_operand" "") 4426 (fix:X87MODEI12 (match_operand 1 "register_operand" ""))) 4427 (use (match_operand:HI 2 "memory_operand" "")) 4428 (use (match_operand:HI 3 "memory_operand" "")) 4429 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 4430 "reload_completed" 4431 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1))) 4432 (use (match_dup 2)) 4433 (use (match_dup 3))]) 4434 (set (match_dup 0) (match_dup 4))] 4435 "") 4436 4437(define_split 4438 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 4439 (fix:X87MODEI12 (match_operand 1 "register_operand" ""))) 4440 (use (match_operand:HI 2 "memory_operand" "")) 4441 (use (match_operand:HI 3 "memory_operand" "")) 4442 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 4443 "reload_completed" 4444 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1))) 4445 (use (match_dup 2)) 4446 (use (match_dup 3))])] 4447 "") 4448 4449(define_insn "x86_fnstcw_1" 4450 [(set (match_operand:HI 0 "memory_operand" "=m") 4451 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))] 4452 "TARGET_80387" 4453 "fnstcw\t%0" 4454 [(set_attr "length" "2") 4455 (set_attr "mode" "HI") 4456 (set_attr "unit" "i387")]) 4457 4458(define_insn "x86_fldcw_1" 4459 [(set (reg:HI FPSR_REG) 4460 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))] 4461 "TARGET_80387" 4462 "fldcw\t%0" 4463 [(set_attr "length" "2") 4464 (set_attr "mode" "HI") 4465 (set_attr "unit" "i387") 4466 (set_attr "athlon_decode" "vector") 4467 (set_attr "amdfam10_decode" "vector")]) 4468 4469;; Conversion between fixed point and floating point. 4470 4471;; Even though we only accept memory inputs, the backend _really_ 4472;; wants to be able to do this between registers. 4473 4474(define_expand "floathisf2" 4475 [(set (match_operand:SF 0 "register_operand" "") 4476 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))] 4477 "TARGET_80387 || TARGET_SSE_MATH" 4478{ 4479 if (TARGET_SSE_MATH) 4480 { 4481 emit_insn (gen_floatsisf2 (operands[0], 4482 convert_to_mode (SImode, operands[1], 0))); 4483 DONE; 4484 } 4485}) 4486 4487(define_insn "*floathisf2_i387" 4488 [(set (match_operand:SF 0 "register_operand" "=f,f") 4489 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))] 4490 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 4491 "@ 4492 fild%z1\t%1 4493 #" 4494 [(set_attr "type" "fmov,multi") 4495 (set_attr "mode" "SF") 4496 (set_attr "unit" "*,i387") 4497 (set_attr "fp_int_src" "true")]) 4498 4499(define_expand "floatsisf2" 4500 [(set (match_operand:SF 0 "register_operand" "") 4501 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))] 4502 "TARGET_80387 || TARGET_SSE_MATH" 4503 "") 4504 4505(define_insn "*floatsisf2_mixed" 4506 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x") 4507 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))] 4508 "TARGET_MIX_SSE_I387" 4509 "@ 4510 fild%z1\t%1 4511 # 4512 cvtsi2ss\t{%1, %0|%0, %1} 4513 cvtsi2ss\t{%1, %0|%0, %1}" 4514 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4515 (set_attr "mode" "SF") 4516 (set_attr "unit" "*,i387,*,*") 4517 (set_attr "athlon_decode" "*,*,vector,double") 4518 (set_attr "amdfam10_decode" "*,*,vector,double") 4519 (set_attr "fp_int_src" "true")]) 4520 4521(define_insn "*floatsisf2_sse" 4522 [(set (match_operand:SF 0 "register_operand" "=x,x") 4523 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))] 4524 "TARGET_SSE_MATH" 4525 "cvtsi2ss\t{%1, %0|%0, %1}" 4526 [(set_attr "type" "sseicvt") 4527 (set_attr "mode" "SF") 4528 (set_attr "athlon_decode" "vector,double") 4529 (set_attr "amdfam10_decode" "vector,double") 4530 (set_attr "fp_int_src" "true")]) 4531 4532(define_insn "*floatsisf2_i387" 4533 [(set (match_operand:SF 0 "register_operand" "=f,f") 4534 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))] 4535 "TARGET_80387" 4536 "@ 4537 fild%z1\t%1 4538 #" 4539 [(set_attr "type" "fmov,multi") 4540 (set_attr "mode" "SF") 4541 (set_attr "unit" "*,i387") 4542 (set_attr "fp_int_src" "true")]) 4543 4544(define_expand "floatdisf2" 4545 [(set (match_operand:SF 0 "register_operand" "") 4546 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))] 4547 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)" 4548 "") 4549 4550(define_insn "*floatdisf2_mixed" 4551 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x") 4552 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))] 4553 "TARGET_64BIT && TARGET_MIX_SSE_I387" 4554 "@ 4555 fild%z1\t%1 4556 # 4557 cvtsi2ss{q}\t{%1, %0|%0, %1} 4558 cvtsi2ss{q}\t{%1, %0|%0, %1}" 4559 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4560 (set_attr "mode" "SF") 4561 (set_attr "unit" "*,i387,*,*") 4562 (set_attr "athlon_decode" "*,*,vector,double") 4563 (set_attr "amdfam10_decode" "*,*,vector,double") 4564 (set_attr "fp_int_src" "true")]) 4565 4566(define_insn "*floatdisf2_sse" 4567 [(set (match_operand:SF 0 "register_operand" "=x,x") 4568 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))] 4569 "TARGET_64BIT && TARGET_SSE_MATH" 4570 "cvtsi2ss{q}\t{%1, %0|%0, %1}" 4571 [(set_attr "type" "sseicvt") 4572 (set_attr "mode" "SF") 4573 (set_attr "athlon_decode" "vector,double") 4574 (set_attr "amdfam10_decode" "vector,double") 4575 (set_attr "fp_int_src" "true")]) 4576 4577(define_insn "*floatdisf2_i387" 4578 [(set (match_operand:SF 0 "register_operand" "=f,f") 4579 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))] 4580 "TARGET_80387" 4581 "@ 4582 fild%z1\t%1 4583 #" 4584 [(set_attr "type" "fmov,multi") 4585 (set_attr "mode" "SF") 4586 (set_attr "unit" "*,i387") 4587 (set_attr "fp_int_src" "true")]) 4588 4589(define_expand "floathidf2" 4590 [(set (match_operand:DF 0 "register_operand" "") 4591 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))] 4592 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4593{ 4594 if (TARGET_SSE2 && TARGET_SSE_MATH) 4595 { 4596 emit_insn (gen_floatsidf2 (operands[0], 4597 convert_to_mode (SImode, operands[1], 0))); 4598 DONE; 4599 } 4600}) 4601 4602(define_insn "*floathidf2_i387" 4603 [(set (match_operand:DF 0 "register_operand" "=f,f") 4604 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))] 4605 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)" 4606 "@ 4607 fild%z1\t%1 4608 #" 4609 [(set_attr "type" "fmov,multi") 4610 (set_attr "mode" "DF") 4611 (set_attr "unit" "*,i387") 4612 (set_attr "fp_int_src" "true")]) 4613 4614(define_expand "floatsidf2" 4615 [(set (match_operand:DF 0 "register_operand" "") 4616 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))] 4617 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4618 "") 4619 4620(define_insn "*floatsidf2_mixed" 4621 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y") 4622 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))] 4623 "TARGET_SSE2 && TARGET_MIX_SSE_I387" 4624 "@ 4625 fild%z1\t%1 4626 # 4627 cvtsi2sd\t{%1, %0|%0, %1} 4628 cvtsi2sd\t{%1, %0|%0, %1}" 4629 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4630 (set_attr "mode" "DF") 4631 (set_attr "unit" "*,i387,*,*") 4632 (set_attr "athlon_decode" "*,*,double,direct") 4633 (set_attr "amdfam10_decode" "*,*,vector,double") 4634 (set_attr "fp_int_src" "true")]) 4635 4636(define_insn "*floatsidf2_sse" 4637 [(set (match_operand:DF 0 "register_operand" "=Y,Y") 4638 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))] 4639 "TARGET_SSE2 && TARGET_SSE_MATH" 4640 "cvtsi2sd\t{%1, %0|%0, %1}" 4641 [(set_attr "type" "sseicvt") 4642 (set_attr "mode" "DF") 4643 (set_attr "athlon_decode" "double,direct") 4644 (set_attr "amdfam10_decode" "vector,double") 4645 (set_attr "fp_int_src" "true")]) 4646 4647(define_insn "*floatsidf2_i387" 4648 [(set (match_operand:DF 0 "register_operand" "=f,f") 4649 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))] 4650 "TARGET_80387" 4651 "@ 4652 fild%z1\t%1 4653 #" 4654 [(set_attr "type" "fmov,multi") 4655 (set_attr "mode" "DF") 4656 (set_attr "unit" "*,i387") 4657 (set_attr "fp_int_src" "true")]) 4658 4659(define_expand "floatdidf2" 4660 [(set (match_operand:DF 0 "register_operand" "") 4661 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))] 4662 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)" 4663 "") 4664 4665(define_insn "*floatdidf2_mixed" 4666 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y") 4667 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))] 4668 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387" 4669 "@ 4670 fild%z1\t%1 4671 # 4672 cvtsi2sd{q}\t{%1, %0|%0, %1} 4673 cvtsi2sd{q}\t{%1, %0|%0, %1}" 4674 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4675 (set_attr "mode" "DF") 4676 (set_attr "unit" "*,i387,*,*") 4677 (set_attr "athlon_decode" "*,*,double,direct") 4678 (set_attr "amdfam10_decode" "*,*,vector,double") 4679 (set_attr "fp_int_src" "true")]) 4680 4681(define_insn "*floatdidf2_sse" 4682 [(set (match_operand:DF 0 "register_operand" "=Y,Y") 4683 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))] 4684 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH" 4685 "cvtsi2sd{q}\t{%1, %0|%0, %1}" 4686 [(set_attr "type" "sseicvt") 4687 (set_attr "mode" "DF") 4688 (set_attr "athlon_decode" "double,direct") 4689 (set_attr "amdfam10_decode" "vector,double") 4690 (set_attr "fp_int_src" "true")]) 4691 4692(define_insn "*floatdidf2_i387" 4693 [(set (match_operand:DF 0 "register_operand" "=f,f") 4694 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))] 4695 "TARGET_80387" 4696 "@ 4697 fild%z1\t%1 4698 #" 4699 [(set_attr "type" "fmov,multi") 4700 (set_attr "mode" "DF") 4701 (set_attr "unit" "*,i387") 4702 (set_attr "fp_int_src" "true")]) 4703 4704(define_insn "floathixf2" 4705 [(set (match_operand:XF 0 "register_operand" "=f,f") 4706 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))] 4707 "TARGET_80387" 4708 "@ 4709 fild%z1\t%1 4710 #" 4711 [(set_attr "type" "fmov,multi") 4712 (set_attr "mode" "XF") 4713 (set_attr "unit" "*,i387") 4714 (set_attr "fp_int_src" "true")]) 4715 4716(define_insn "floatsixf2" 4717 [(set (match_operand:XF 0 "register_operand" "=f,f") 4718 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))] 4719 "TARGET_80387" 4720 "@ 4721 fild%z1\t%1 4722 #" 4723 [(set_attr "type" "fmov,multi") 4724 (set_attr "mode" "XF") 4725 (set_attr "unit" "*,i387") 4726 (set_attr "fp_int_src" "true")]) 4727 4728(define_insn "floatdixf2" 4729 [(set (match_operand:XF 0 "register_operand" "=f,f") 4730 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))] 4731 "TARGET_80387" 4732 "@ 4733 fild%z1\t%1 4734 #" 4735 [(set_attr "type" "fmov,multi") 4736 (set_attr "mode" "XF") 4737 (set_attr "unit" "*,i387") 4738 (set_attr "fp_int_src" "true")]) 4739 4740;; %%% Kill these when reload knows how to do it. 4741(define_split 4742 [(set (match_operand 0 "fp_register_operand" "") 4743 (float (match_operand 1 "register_operand" "")))] 4744 "reload_completed 4745 && TARGET_80387 4746 && FLOAT_MODE_P (GET_MODE (operands[0]))" 4747 [(const_int 0)] 4748{ 4749 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]); 4750 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]); 4751 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2])); 4752 ix86_free_from_memory (GET_MODE (operands[1])); 4753 DONE; 4754}) 4755 4756(define_expand "floatunssisf2" 4757 [(use (match_operand:SF 0 "register_operand" "")) 4758 (use (match_operand:SI 1 "register_operand" ""))] 4759 "!TARGET_64BIT && TARGET_SSE_MATH" 4760 "x86_emit_floatuns (operands); DONE;") 4761 4762(define_expand "floatunsdisf2" 4763 [(use (match_operand:SF 0 "register_operand" "")) 4764 (use (match_operand:DI 1 "register_operand" ""))] 4765 "TARGET_64BIT && TARGET_SSE_MATH" 4766 "x86_emit_floatuns (operands); DONE;") 4767 4768(define_expand "floatunsdidf2" 4769 [(use (match_operand:DF 0 "register_operand" "")) 4770 (use (match_operand:DI 1 "register_operand" ""))] 4771 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH" 4772 "x86_emit_floatuns (operands); DONE;") 4773 4774;; SSE extract/set expanders 4775 4776 4777;; Add instructions 4778 4779;; %%% splits for addditi3 4780 4781(define_expand "addti3" 4782 [(set (match_operand:TI 0 "nonimmediate_operand" "") 4783 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "") 4784 (match_operand:TI 2 "x86_64_general_operand" ""))) 4785 (clobber (reg:CC FLAGS_REG))] 4786 "TARGET_64BIT" 4787 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;") 4788 4789(define_insn "*addti3_1" 4790 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o") 4791 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0") 4792 (match_operand:TI 2 "x86_64_general_operand" "roe,re"))) 4793 (clobber (reg:CC FLAGS_REG))] 4794 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)" 4795 "#") 4796 4797(define_split 4798 [(set (match_operand:TI 0 "nonimmediate_operand" "") 4799 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "") 4800 (match_operand:TI 2 "x86_64_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:DI (match_dup 1) (match_dup 2)))]) 4806 (parallel [(set (match_dup 3) 4807 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) 4808 (match_dup 4)) 4809 (match_dup 5))) 4810 (clobber (reg:CC FLAGS_REG))])] 4811 "split_ti (operands+0, 1, operands+0, operands+3); 4812 split_ti (operands+1, 1, operands+1, operands+4); 4813 split_ti (operands+2, 1, operands+2, operands+5);") 4814 4815;; %%% splits for addsidi3 4816; [(set (match_operand:DI 0 "nonimmediate_operand" "") 4817; (plus:DI (match_operand:DI 1 "general_operand" "") 4818; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))] 4819 4820(define_expand "adddi3" 4821 [(set (match_operand:DI 0 "nonimmediate_operand" "") 4822 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") 4823 (match_operand:DI 2 "x86_64_general_operand" ""))) 4824 (clobber (reg:CC FLAGS_REG))] 4825 "" 4826 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;") 4827 4828(define_insn "*adddi3_1" 4829 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") 4830 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 4831 (match_operand:DI 2 "general_operand" "roiF,riF"))) 4832 (clobber (reg:CC FLAGS_REG))] 4833 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 4834 "#") 4835 4836(define_split 4837 [(set (match_operand:DI 0 "nonimmediate_operand" "") 4838 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") 4839 (match_operand:DI 2 "general_operand" ""))) 4840 (clobber (reg:CC FLAGS_REG))] 4841 "!TARGET_64BIT && reload_completed" 4842 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)] 4843 UNSPEC_ADD_CARRY)) 4844 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) 4845 (parallel [(set (match_dup 3) 4846 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) 4847 (match_dup 4)) 4848 (match_dup 5))) 4849 (clobber (reg:CC FLAGS_REG))])] 4850 "split_di (operands+0, 1, operands+0, operands+3); 4851 split_di (operands+1, 1, operands+1, operands+4); 4852 split_di (operands+2, 1, operands+2, operands+5);") 4853 4854(define_insn "adddi3_carry_rex64" 4855 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 4856 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "") 4857 (match_operand:DI 1 "nonimmediate_operand" "%0,0")) 4858 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 4859 (clobber (reg:CC FLAGS_REG))] 4860 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 4861 "adc{q}\t{%2, %0|%0, %2}" 4862 [(set_attr "type" "alu") 4863 (set_attr "pent_pair" "pu") 4864 (set_attr "mode" "DI")]) 4865 4866(define_insn "*adddi3_cc_rex64" 4867 [(set (reg:CC FLAGS_REG) 4868 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0") 4869 (match_operand:DI 2 "x86_64_general_operand" "re,rm")] 4870 UNSPEC_ADD_CARRY)) 4871 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 4872 (plus:DI (match_dup 1) (match_dup 2)))] 4873 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 4874 "add{q}\t{%2, %0|%0, %2}" 4875 [(set_attr "type" "alu") 4876 (set_attr "mode" "DI")]) 4877 4878(define_insn "addqi3_carry" 4879 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 4880 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "") 4881 (match_operand:QI 1 "nonimmediate_operand" "%0,0")) 4882 (match_operand:QI 2 "general_operand" "qi,qm"))) 4883 (clobber (reg:CC FLAGS_REG))] 4884 "ix86_binary_operator_ok (PLUS, QImode, operands)" 4885 "adc{b}\t{%2, %0|%0, %2}" 4886 [(set_attr "type" "alu") 4887 (set_attr "pent_pair" "pu") 4888 (set_attr "mode" "QI")]) 4889 4890(define_insn "addhi3_carry" 4891 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 4892 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "") 4893 (match_operand:HI 1 "nonimmediate_operand" "%0,0")) 4894 (match_operand:HI 2 "general_operand" "ri,rm"))) 4895 (clobber (reg:CC FLAGS_REG))] 4896 "ix86_binary_operator_ok (PLUS, HImode, operands)" 4897 "adc{w}\t{%2, %0|%0, %2}" 4898 [(set_attr "type" "alu") 4899 (set_attr "pent_pair" "pu") 4900 (set_attr "mode" "HI")]) 4901 4902(define_insn "addsi3_carry" 4903 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 4904 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 4905 (match_operand:SI 1 "nonimmediate_operand" "%0,0")) 4906 (match_operand:SI 2 "general_operand" "ri,rm"))) 4907 (clobber (reg:CC FLAGS_REG))] 4908 "ix86_binary_operator_ok (PLUS, SImode, operands)" 4909 "adc{l}\t{%2, %0|%0, %2}" 4910 [(set_attr "type" "alu") 4911 (set_attr "pent_pair" "pu") 4912 (set_attr "mode" "SI")]) 4913 4914(define_insn "*addsi3_carry_zext" 4915 [(set (match_operand:DI 0 "register_operand" "=r") 4916 (zero_extend:DI 4917 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 4918 (match_operand:SI 1 "nonimmediate_operand" "%0")) 4919 (match_operand:SI 2 "general_operand" "rim")))) 4920 (clobber (reg:CC FLAGS_REG))] 4921 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 4922 "adc{l}\t{%2, %k0|%k0, %2}" 4923 [(set_attr "type" "alu") 4924 (set_attr "pent_pair" "pu") 4925 (set_attr "mode" "SI")]) 4926 4927(define_insn "*addsi3_cc" 4928 [(set (reg:CC FLAGS_REG) 4929 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0") 4930 (match_operand:SI 2 "general_operand" "ri,rm")] 4931 UNSPEC_ADD_CARRY)) 4932 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 4933 (plus:SI (match_dup 1) (match_dup 2)))] 4934 "ix86_binary_operator_ok (PLUS, SImode, operands)" 4935 "add{l}\t{%2, %0|%0, %2}" 4936 [(set_attr "type" "alu") 4937 (set_attr "mode" "SI")]) 4938 4939(define_insn "addqi3_cc" 4940 [(set (reg:CC FLAGS_REG) 4941 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0") 4942 (match_operand:QI 2 "general_operand" "qi,qm")] 4943 UNSPEC_ADD_CARRY)) 4944 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 4945 (plus:QI (match_dup 1) (match_dup 2)))] 4946 "ix86_binary_operator_ok (PLUS, QImode, operands)" 4947 "add{b}\t{%2, %0|%0, %2}" 4948 [(set_attr "type" "alu") 4949 (set_attr "mode" "QI")]) 4950 4951(define_expand "addsi3" 4952 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4953 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "") 4954 (match_operand:SI 2 "general_operand" ""))) 4955 (clobber (reg:CC FLAGS_REG))])] 4956 "" 4957 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;") 4958 4959(define_insn "*lea_1" 4960 [(set (match_operand:SI 0 "register_operand" "=r") 4961 (match_operand:SI 1 "no_seg_address_operand" "p"))] 4962 "!TARGET_64BIT" 4963 "lea{l}\t{%a1, %0|%0, %a1}" 4964 [(set_attr "type" "lea") 4965 (set_attr "mode" "SI")]) 4966 4967(define_insn "*lea_1_rex64" 4968 [(set (match_operand:SI 0 "register_operand" "=r") 4969 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))] 4970 "TARGET_64BIT" 4971 "lea{l}\t{%a1, %0|%0, %a1}" 4972 [(set_attr "type" "lea") 4973 (set_attr "mode" "SI")]) 4974 4975(define_insn "*lea_1_zext" 4976 [(set (match_operand:DI 0 "register_operand" "=r") 4977 (zero_extend:DI 4978 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))] 4979 "TARGET_64BIT" 4980 "lea{l}\t{%a1, %k0|%k0, %a1}" 4981 [(set_attr "type" "lea") 4982 (set_attr "mode" "SI")]) 4983 4984(define_insn "*lea_2_rex64" 4985 [(set (match_operand:DI 0 "register_operand" "=r") 4986 (match_operand:DI 1 "no_seg_address_operand" "p"))] 4987 "TARGET_64BIT" 4988 "lea{q}\t{%a1, %0|%0, %a1}" 4989 [(set_attr "type" "lea") 4990 (set_attr "mode" "DI")]) 4991 4992;; The lea patterns for non-Pmodes needs to be matched by several 4993;; insns converted to real lea by splitters. 4994 4995(define_insn_and_split "*lea_general_1" 4996 [(set (match_operand 0 "register_operand" "=r") 4997 (plus (plus (match_operand 1 "index_register_operand" "l") 4998 (match_operand 2 "register_operand" "r")) 4999 (match_operand 3 "immediate_operand" "i")))] 5000 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode 5001 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) 5002 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 5003 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 5004 && GET_MODE (operands[0]) == GET_MODE (operands[2]) 5005 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 5006 || GET_MODE (operands[3]) == VOIDmode)" 5007 "#" 5008 "&& reload_completed" 5009 [(const_int 0)] 5010{ 5011 rtx pat; 5012 operands[0] = gen_lowpart (SImode, operands[0]); 5013 operands[1] = gen_lowpart (Pmode, operands[1]); 5014 operands[2] = gen_lowpart (Pmode, operands[2]); 5015 operands[3] = gen_lowpart (Pmode, operands[3]); 5016 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]), 5017 operands[3]); 5018 if (Pmode != SImode) 5019 pat = gen_rtx_SUBREG (SImode, pat, 0); 5020 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5021 DONE; 5022} 5023 [(set_attr "type" "lea") 5024 (set_attr "mode" "SI")]) 5025 5026(define_insn_and_split "*lea_general_1_zext" 5027 [(set (match_operand:DI 0 "register_operand" "=r") 5028 (zero_extend:DI 5029 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l") 5030 (match_operand:SI 2 "register_operand" "r")) 5031 (match_operand:SI 3 "immediate_operand" "i"))))] 5032 "TARGET_64BIT" 5033 "#" 5034 "&& reload_completed" 5035 [(set (match_dup 0) 5036 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1) 5037 (match_dup 2)) 5038 (match_dup 3)) 0)))] 5039{ 5040 operands[1] = gen_lowpart (Pmode, operands[1]); 5041 operands[2] = gen_lowpart (Pmode, operands[2]); 5042 operands[3] = gen_lowpart (Pmode, operands[3]); 5043} 5044 [(set_attr "type" "lea") 5045 (set_attr "mode" "SI")]) 5046 5047(define_insn_and_split "*lea_general_2" 5048 [(set (match_operand 0 "register_operand" "=r") 5049 (plus (mult (match_operand 1 "index_register_operand" "l") 5050 (match_operand 2 "const248_operand" "i")) 5051 (match_operand 3 "nonmemory_operand" "ri")))] 5052 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode 5053 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) 5054 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 5055 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 5056 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 5057 || GET_MODE (operands[3]) == VOIDmode)" 5058 "#" 5059 "&& reload_completed" 5060 [(const_int 0)] 5061{ 5062 rtx pat; 5063 operands[0] = gen_lowpart (SImode, operands[0]); 5064 operands[1] = gen_lowpart (Pmode, operands[1]); 5065 operands[3] = gen_lowpart (Pmode, operands[3]); 5066 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]), 5067 operands[3]); 5068 if (Pmode != SImode) 5069 pat = gen_rtx_SUBREG (SImode, pat, 0); 5070 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5071 DONE; 5072} 5073 [(set_attr "type" "lea") 5074 (set_attr "mode" "SI")]) 5075 5076(define_insn_and_split "*lea_general_2_zext" 5077 [(set (match_operand:DI 0 "register_operand" "=r") 5078 (zero_extend:DI 5079 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l") 5080 (match_operand:SI 2 "const248_operand" "n")) 5081 (match_operand:SI 3 "nonmemory_operand" "ri"))))] 5082 "TARGET_64BIT" 5083 "#" 5084 "&& reload_completed" 5085 [(set (match_dup 0) 5086 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1) 5087 (match_dup 2)) 5088 (match_dup 3)) 0)))] 5089{ 5090 operands[1] = gen_lowpart (Pmode, operands[1]); 5091 operands[3] = gen_lowpart (Pmode, operands[3]); 5092} 5093 [(set_attr "type" "lea") 5094 (set_attr "mode" "SI")]) 5095 5096(define_insn_and_split "*lea_general_3" 5097 [(set (match_operand 0 "register_operand" "=r") 5098 (plus (plus (mult (match_operand 1 "index_register_operand" "l") 5099 (match_operand 2 "const248_operand" "i")) 5100 (match_operand 3 "register_operand" "r")) 5101 (match_operand 4 "immediate_operand" "i")))] 5102 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode 5103 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) 5104 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 5105 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 5106 && GET_MODE (operands[0]) == GET_MODE (operands[3])" 5107 "#" 5108 "&& reload_completed" 5109 [(const_int 0)] 5110{ 5111 rtx pat; 5112 operands[0] = gen_lowpart (SImode, operands[0]); 5113 operands[1] = gen_lowpart (Pmode, operands[1]); 5114 operands[3] = gen_lowpart (Pmode, operands[3]); 5115 operands[4] = gen_lowpart (Pmode, operands[4]); 5116 pat = gen_rtx_PLUS (Pmode, 5117 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], 5118 operands[2]), 5119 operands[3]), 5120 operands[4]); 5121 if (Pmode != SImode) 5122 pat = gen_rtx_SUBREG (SImode, pat, 0); 5123 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5124 DONE; 5125} 5126 [(set_attr "type" "lea") 5127 (set_attr "mode" "SI")]) 5128 5129(define_insn_and_split "*lea_general_3_zext" 5130 [(set (match_operand:DI 0 "register_operand" "=r") 5131 (zero_extend:DI 5132 (plus:SI (plus:SI (mult:SI 5133 (match_operand:SI 1 "index_register_operand" "l") 5134 (match_operand:SI 2 "const248_operand" "n")) 5135 (match_operand:SI 3 "register_operand" "r")) 5136 (match_operand:SI 4 "immediate_operand" "i"))))] 5137 "TARGET_64BIT" 5138 "#" 5139 "&& reload_completed" 5140 [(set (match_dup 0) 5141 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1) 5142 (match_dup 2)) 5143 (match_dup 3)) 5144 (match_dup 4)) 0)))] 5145{ 5146 operands[1] = gen_lowpart (Pmode, operands[1]); 5147 operands[3] = gen_lowpart (Pmode, operands[3]); 5148 operands[4] = gen_lowpart (Pmode, operands[4]); 5149} 5150 [(set_attr "type" "lea") 5151 (set_attr "mode" "SI")]) 5152 5153(define_insn "*adddi_1_rex64" 5154 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r") 5155 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r") 5156 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le"))) 5157 (clobber (reg:CC FLAGS_REG))] 5158 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 5159{ 5160 switch (get_attr_type (insn)) 5161 { 5162 case TYPE_LEA: 5163 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 5164 return "lea{q}\t{%a2, %0|%0, %a2}"; 5165 5166 case TYPE_INCDEC: 5167 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5168 if (operands[2] == const1_rtx) 5169 return "inc{q}\t%0"; 5170 else 5171 { 5172 gcc_assert (operands[2] == constm1_rtx); 5173 return "dec{q}\t%0"; 5174 } 5175 5176 default: 5177 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5178 5179 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5180 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5181 if (GET_CODE (operands[2]) == CONST_INT 5182 /* Avoid overflows. */ 5183 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5184 && (INTVAL (operands[2]) == 128 5185 || (INTVAL (operands[2]) < 0 5186 && INTVAL (operands[2]) != -128))) 5187 { 5188 operands[2] = GEN_INT (-INTVAL (operands[2])); 5189 return "sub{q}\t{%2, %0|%0, %2}"; 5190 } 5191 return "add{q}\t{%2, %0|%0, %2}"; 5192 } 5193} 5194 [(set (attr "type") 5195 (cond [(eq_attr "alternative" "2") 5196 (const_string "lea") 5197 ; Current assemblers are broken and do not allow @GOTOFF in 5198 ; ought but a memory context. 5199 (match_operand:DI 2 "pic_symbolic_operand" "") 5200 (const_string "lea") 5201 (match_operand:DI 2 "incdec_operand" "") 5202 (const_string "incdec") 5203 ] 5204 (const_string "alu"))) 5205 (set_attr "mode" "DI")]) 5206 5207;; Convert lea to the lea pattern to avoid flags dependency. 5208(define_split 5209 [(set (match_operand:DI 0 "register_operand" "") 5210 (plus:DI (match_operand:DI 1 "register_operand" "") 5211 (match_operand:DI 2 "x86_64_nonmemory_operand" ""))) 5212 (clobber (reg:CC FLAGS_REG))] 5213 "TARGET_64BIT && reload_completed 5214 && true_regnum (operands[0]) != true_regnum (operands[1])" 5215 [(set (match_dup 0) 5216 (plus:DI (match_dup 1) 5217 (match_dup 2)))] 5218 "") 5219 5220(define_insn "*adddi_2_rex64" 5221 [(set (reg FLAGS_REG) 5222 (compare 5223 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 5224 (match_operand:DI 2 "x86_64_general_operand" "rme,re")) 5225 (const_int 0))) 5226 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") 5227 (plus:DI (match_dup 1) (match_dup 2)))] 5228 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 5229 && ix86_binary_operator_ok (PLUS, DImode, operands) 5230 /* Current assemblers are broken and do not allow @GOTOFF in 5231 ought but a memory context. */ 5232 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5233{ 5234 switch (get_attr_type (insn)) 5235 { 5236 case TYPE_INCDEC: 5237 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5238 if (operands[2] == const1_rtx) 5239 return "inc{q}\t%0"; 5240 else 5241 { 5242 gcc_assert (operands[2] == constm1_rtx); 5243 return "dec{q}\t%0"; 5244 } 5245 5246 default: 5247 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5248 /* ???? We ought to handle there the 32bit case too 5249 - do we need new constraint? */ 5250 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5251 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5252 if (GET_CODE (operands[2]) == CONST_INT 5253 /* Avoid overflows. */ 5254 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5255 && (INTVAL (operands[2]) == 128 5256 || (INTVAL (operands[2]) < 0 5257 && INTVAL (operands[2]) != -128))) 5258 { 5259 operands[2] = GEN_INT (-INTVAL (operands[2])); 5260 return "sub{q}\t{%2, %0|%0, %2}"; 5261 } 5262 return "add{q}\t{%2, %0|%0, %2}"; 5263 } 5264} 5265 [(set (attr "type") 5266 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5267 (const_string "incdec") 5268 (const_string "alu"))) 5269 (set_attr "mode" "DI")]) 5270 5271(define_insn "*adddi_3_rex64" 5272 [(set (reg FLAGS_REG) 5273 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme")) 5274 (match_operand:DI 1 "x86_64_general_operand" "%0"))) 5275 (clobber (match_scratch:DI 0 "=r"))] 5276 "TARGET_64BIT 5277 && ix86_match_ccmode (insn, CCZmode) 5278 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5279 /* Current assemblers are broken and do not allow @GOTOFF in 5280 ought but a memory context. */ 5281 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5282{ 5283 switch (get_attr_type (insn)) 5284 { 5285 case TYPE_INCDEC: 5286 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5287 if (operands[2] == const1_rtx) 5288 return "inc{q}\t%0"; 5289 else 5290 { 5291 gcc_assert (operands[2] == constm1_rtx); 5292 return "dec{q}\t%0"; 5293 } 5294 5295 default: 5296 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5297 /* ???? We ought to handle there the 32bit case too 5298 - do we need new constraint? */ 5299 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5300 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5301 if (GET_CODE (operands[2]) == CONST_INT 5302 /* Avoid overflows. */ 5303 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5304 && (INTVAL (operands[2]) == 128 5305 || (INTVAL (operands[2]) < 0 5306 && INTVAL (operands[2]) != -128))) 5307 { 5308 operands[2] = GEN_INT (-INTVAL (operands[2])); 5309 return "sub{q}\t{%2, %0|%0, %2}"; 5310 } 5311 return "add{q}\t{%2, %0|%0, %2}"; 5312 } 5313} 5314 [(set (attr "type") 5315 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5316 (const_string "incdec") 5317 (const_string "alu"))) 5318 (set_attr "mode" "DI")]) 5319 5320; For comparisons against 1, -1 and 128, we may generate better code 5321; by converting cmp to add, inc or dec as done by peephole2. This pattern 5322; is matched then. We can't accept general immediate, because for 5323; case of overflows, the result is messed up. 5324; This pattern also don't hold of 0x8000000000000000, since the value overflows 5325; when negated. 5326; Also carry flag is reversed compared to cmp, so this conversion is valid 5327; only for comparisons not depending on it. 5328(define_insn "*adddi_4_rex64" 5329 [(set (reg FLAGS_REG) 5330 (compare (match_operand:DI 1 "nonimmediate_operand" "0") 5331 (match_operand:DI 2 "x86_64_immediate_operand" "e"))) 5332 (clobber (match_scratch:DI 0 "=rm"))] 5333 "TARGET_64BIT 5334 && ix86_match_ccmode (insn, CCGCmode)" 5335{ 5336 switch (get_attr_type (insn)) 5337 { 5338 case TYPE_INCDEC: 5339 if (operands[2] == constm1_rtx) 5340 return "inc{q}\t%0"; 5341 else 5342 { 5343 gcc_assert (operands[2] == const1_rtx); 5344 return "dec{q}\t%0"; 5345 } 5346 5347 default: 5348 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5349 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5350 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5351 if ((INTVAL (operands[2]) == -128 5352 || (INTVAL (operands[2]) > 0 5353 && INTVAL (operands[2]) != 128)) 5354 /* Avoid overflows. */ 5355 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))) 5356 return "sub{q}\t{%2, %0|%0, %2}"; 5357 operands[2] = GEN_INT (-INTVAL (operands[2])); 5358 return "add{q}\t{%2, %0|%0, %2}"; 5359 } 5360} 5361 [(set (attr "type") 5362 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5363 (const_string "incdec") 5364 (const_string "alu"))) 5365 (set_attr "mode" "DI")]) 5366 5367(define_insn "*adddi_5_rex64" 5368 [(set (reg FLAGS_REG) 5369 (compare 5370 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0") 5371 (match_operand:DI 2 "x86_64_general_operand" "rme")) 5372 (const_int 0))) 5373 (clobber (match_scratch:DI 0 "=r"))] 5374 "TARGET_64BIT 5375 && ix86_match_ccmode (insn, CCGOCmode) 5376 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5377 /* Current assemblers are broken and do not allow @GOTOFF in 5378 ought but a memory context. */ 5379 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5380{ 5381 switch (get_attr_type (insn)) 5382 { 5383 case TYPE_INCDEC: 5384 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5385 if (operands[2] == const1_rtx) 5386 return "inc{q}\t%0"; 5387 else 5388 { 5389 gcc_assert (operands[2] == constm1_rtx); 5390 return "dec{q}\t%0"; 5391 } 5392 5393 default: 5394 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5395 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5396 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5397 if (GET_CODE (operands[2]) == CONST_INT 5398 /* Avoid overflows. */ 5399 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5400 && (INTVAL (operands[2]) == 128 5401 || (INTVAL (operands[2]) < 0 5402 && INTVAL (operands[2]) != -128))) 5403 { 5404 operands[2] = GEN_INT (-INTVAL (operands[2])); 5405 return "sub{q}\t{%2, %0|%0, %2}"; 5406 } 5407 return "add{q}\t{%2, %0|%0, %2}"; 5408 } 5409} 5410 [(set (attr "type") 5411 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5412 (const_string "incdec") 5413 (const_string "alu"))) 5414 (set_attr "mode" "DI")]) 5415 5416 5417(define_insn "*addsi_1" 5418 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r") 5419 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r") 5420 (match_operand:SI 2 "general_operand" "rmni,rni,lni"))) 5421 (clobber (reg:CC FLAGS_REG))] 5422 "ix86_binary_operator_ok (PLUS, SImode, operands)" 5423{ 5424 switch (get_attr_type (insn)) 5425 { 5426 case TYPE_LEA: 5427 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 5428 return "lea{l}\t{%a2, %0|%0, %a2}"; 5429 5430 case TYPE_INCDEC: 5431 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5432 if (operands[2] == const1_rtx) 5433 return "inc{l}\t%0"; 5434 else 5435 { 5436 gcc_assert (operands[2] == constm1_rtx); 5437 return "dec{l}\t%0"; 5438 } 5439 5440 default: 5441 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5442 5443 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5444 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5445 if (GET_CODE (operands[2]) == CONST_INT 5446 && (INTVAL (operands[2]) == 128 5447 || (INTVAL (operands[2]) < 0 5448 && INTVAL (operands[2]) != -128))) 5449 { 5450 operands[2] = GEN_INT (-INTVAL (operands[2])); 5451 return "sub{l}\t{%2, %0|%0, %2}"; 5452 } 5453 return "add{l}\t{%2, %0|%0, %2}"; 5454 } 5455} 5456 [(set (attr "type") 5457 (cond [(eq_attr "alternative" "2") 5458 (const_string "lea") 5459 ; Current assemblers are broken and do not allow @GOTOFF in 5460 ; ought but a memory context. 5461 (match_operand:SI 2 "pic_symbolic_operand" "") 5462 (const_string "lea") 5463 (match_operand:SI 2 "incdec_operand" "") 5464 (const_string "incdec") 5465 ] 5466 (const_string "alu"))) 5467 (set_attr "mode" "SI")]) 5468 5469;; Convert lea to the lea pattern to avoid flags dependency. 5470(define_split 5471 [(set (match_operand 0 "register_operand" "") 5472 (plus (match_operand 1 "register_operand" "") 5473 (match_operand 2 "nonmemory_operand" ""))) 5474 (clobber (reg:CC FLAGS_REG))] 5475 "reload_completed 5476 && true_regnum (operands[0]) != true_regnum (operands[1])" 5477 [(const_int 0)] 5478{ 5479 rtx pat; 5480 /* In -fPIC mode the constructs like (const (unspec [symbol_ref])) 5481 may confuse gen_lowpart. */ 5482 if (GET_MODE (operands[0]) != Pmode) 5483 { 5484 operands[1] = gen_lowpart (Pmode, operands[1]); 5485 operands[2] = gen_lowpart (Pmode, operands[2]); 5486 } 5487 operands[0] = gen_lowpart (SImode, operands[0]); 5488 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]); 5489 if (Pmode != SImode) 5490 pat = gen_rtx_SUBREG (SImode, pat, 0); 5491 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5492 DONE; 5493}) 5494 5495;; It may seem that nonimmediate operand is proper one for operand 1. 5496;; The addsi_1 pattern allows nonimmediate operand at that place and 5497;; we take care in ix86_binary_operator_ok to not allow two memory 5498;; operands so proper swapping will be done in reload. This allow 5499;; patterns constructed from addsi_1 to match. 5500(define_insn "addsi_1_zext" 5501 [(set (match_operand:DI 0 "register_operand" "=r,r") 5502 (zero_extend:DI 5503 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") 5504 (match_operand:SI 2 "general_operand" "rmni,lni")))) 5505 (clobber (reg:CC FLAGS_REG))] 5506 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 5507{ 5508 switch (get_attr_type (insn)) 5509 { 5510 case TYPE_LEA: 5511 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 5512 return "lea{l}\t{%a2, %k0|%k0, %a2}"; 5513 5514 case TYPE_INCDEC: 5515 if (operands[2] == const1_rtx) 5516 return "inc{l}\t%k0"; 5517 else 5518 { 5519 gcc_assert (operands[2] == constm1_rtx); 5520 return "dec{l}\t%k0"; 5521 } 5522 5523 default: 5524 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5525 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5526 if (GET_CODE (operands[2]) == CONST_INT 5527 && (INTVAL (operands[2]) == 128 5528 || (INTVAL (operands[2]) < 0 5529 && INTVAL (operands[2]) != -128))) 5530 { 5531 operands[2] = GEN_INT (-INTVAL (operands[2])); 5532 return "sub{l}\t{%2, %k0|%k0, %2}"; 5533 } 5534 return "add{l}\t{%2, %k0|%k0, %2}"; 5535 } 5536} 5537 [(set (attr "type") 5538 (cond [(eq_attr "alternative" "1") 5539 (const_string "lea") 5540 ; Current assemblers are broken and do not allow @GOTOFF in 5541 ; ought but a memory context. 5542 (match_operand:SI 2 "pic_symbolic_operand" "") 5543 (const_string "lea") 5544 (match_operand:SI 2 "incdec_operand" "") 5545 (const_string "incdec") 5546 ] 5547 (const_string "alu"))) 5548 (set_attr "mode" "SI")]) 5549 5550;; Convert lea to the lea pattern to avoid flags dependency. 5551(define_split 5552 [(set (match_operand:DI 0 "register_operand" "") 5553 (zero_extend:DI 5554 (plus:SI (match_operand:SI 1 "register_operand" "") 5555 (match_operand:SI 2 "nonmemory_operand" "")))) 5556 (clobber (reg:CC FLAGS_REG))] 5557 "TARGET_64BIT && reload_completed 5558 && true_regnum (operands[0]) != true_regnum (operands[1])" 5559 [(set (match_dup 0) 5560 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))] 5561{ 5562 operands[1] = gen_lowpart (Pmode, operands[1]); 5563 operands[2] = gen_lowpart (Pmode, operands[2]); 5564}) 5565 5566(define_insn "*addsi_2" 5567 [(set (reg FLAGS_REG) 5568 (compare 5569 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 5570 (match_operand:SI 2 "general_operand" "rmni,rni")) 5571 (const_int 0))) 5572 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 5573 (plus:SI (match_dup 1) (match_dup 2)))] 5574 "ix86_match_ccmode (insn, CCGOCmode) 5575 && ix86_binary_operator_ok (PLUS, SImode, operands) 5576 /* Current assemblers are broken and do not allow @GOTOFF in 5577 ought but a memory context. */ 5578 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5579{ 5580 switch (get_attr_type (insn)) 5581 { 5582 case TYPE_INCDEC: 5583 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5584 if (operands[2] == const1_rtx) 5585 return "inc{l}\t%0"; 5586 else 5587 { 5588 gcc_assert (operands[2] == constm1_rtx); 5589 return "dec{l}\t%0"; 5590 } 5591 5592 default: 5593 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5594 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5595 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5596 if (GET_CODE (operands[2]) == CONST_INT 5597 && (INTVAL (operands[2]) == 128 5598 || (INTVAL (operands[2]) < 0 5599 && INTVAL (operands[2]) != -128))) 5600 { 5601 operands[2] = GEN_INT (-INTVAL (operands[2])); 5602 return "sub{l}\t{%2, %0|%0, %2}"; 5603 } 5604 return "add{l}\t{%2, %0|%0, %2}"; 5605 } 5606} 5607 [(set (attr "type") 5608 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5609 (const_string "incdec") 5610 (const_string "alu"))) 5611 (set_attr "mode" "SI")]) 5612 5613;; See comment for addsi_1_zext why we do use nonimmediate_operand 5614(define_insn "*addsi_2_zext" 5615 [(set (reg FLAGS_REG) 5616 (compare 5617 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 5618 (match_operand:SI 2 "general_operand" "rmni")) 5619 (const_int 0))) 5620 (set (match_operand:DI 0 "register_operand" "=r") 5621 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5622 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 5623 && ix86_binary_operator_ok (PLUS, SImode, operands) 5624 /* Current assemblers are broken and do not allow @GOTOFF in 5625 ought but a memory context. */ 5626 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5627{ 5628 switch (get_attr_type (insn)) 5629 { 5630 case TYPE_INCDEC: 5631 if (operands[2] == const1_rtx) 5632 return "inc{l}\t%k0"; 5633 else 5634 { 5635 gcc_assert (operands[2] == constm1_rtx); 5636 return "dec{l}\t%k0"; 5637 } 5638 5639 default: 5640 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5641 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5642 if (GET_CODE (operands[2]) == CONST_INT 5643 && (INTVAL (operands[2]) == 128 5644 || (INTVAL (operands[2]) < 0 5645 && INTVAL (operands[2]) != -128))) 5646 { 5647 operands[2] = GEN_INT (-INTVAL (operands[2])); 5648 return "sub{l}\t{%2, %k0|%k0, %2}"; 5649 } 5650 return "add{l}\t{%2, %k0|%k0, %2}"; 5651 } 5652} 5653 [(set (attr "type") 5654 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5655 (const_string "incdec") 5656 (const_string "alu"))) 5657 (set_attr "mode" "SI")]) 5658 5659(define_insn "*addsi_3" 5660 [(set (reg FLAGS_REG) 5661 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni")) 5662 (match_operand:SI 1 "nonimmediate_operand" "%0"))) 5663 (clobber (match_scratch:SI 0 "=r"))] 5664 "ix86_match_ccmode (insn, CCZmode) 5665 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5666 /* Current assemblers are broken and do not allow @GOTOFF in 5667 ought but a memory context. */ 5668 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5669{ 5670 switch (get_attr_type (insn)) 5671 { 5672 case TYPE_INCDEC: 5673 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5674 if (operands[2] == const1_rtx) 5675 return "inc{l}\t%0"; 5676 else 5677 { 5678 gcc_assert (operands[2] == constm1_rtx); 5679 return "dec{l}\t%0"; 5680 } 5681 5682 default: 5683 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5684 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5685 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5686 if (GET_CODE (operands[2]) == CONST_INT 5687 && (INTVAL (operands[2]) == 128 5688 || (INTVAL (operands[2]) < 0 5689 && INTVAL (operands[2]) != -128))) 5690 { 5691 operands[2] = GEN_INT (-INTVAL (operands[2])); 5692 return "sub{l}\t{%2, %0|%0, %2}"; 5693 } 5694 return "add{l}\t{%2, %0|%0, %2}"; 5695 } 5696} 5697 [(set (attr "type") 5698 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5699 (const_string "incdec") 5700 (const_string "alu"))) 5701 (set_attr "mode" "SI")]) 5702 5703;; See comment for addsi_1_zext why we do use nonimmediate_operand 5704(define_insn "*addsi_3_zext" 5705 [(set (reg FLAGS_REG) 5706 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni")) 5707 (match_operand:SI 1 "nonimmediate_operand" "%0"))) 5708 (set (match_operand:DI 0 "register_operand" "=r") 5709 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5710 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode) 5711 && ix86_binary_operator_ok (PLUS, SImode, operands) 5712 /* Current assemblers are broken and do not allow @GOTOFF in 5713 ought but a memory context. */ 5714 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5715{ 5716 switch (get_attr_type (insn)) 5717 { 5718 case TYPE_INCDEC: 5719 if (operands[2] == const1_rtx) 5720 return "inc{l}\t%k0"; 5721 else 5722 { 5723 gcc_assert (operands[2] == constm1_rtx); 5724 return "dec{l}\t%k0"; 5725 } 5726 5727 default: 5728 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5729 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5730 if (GET_CODE (operands[2]) == CONST_INT 5731 && (INTVAL (operands[2]) == 128 5732 || (INTVAL (operands[2]) < 0 5733 && INTVAL (operands[2]) != -128))) 5734 { 5735 operands[2] = GEN_INT (-INTVAL (operands[2])); 5736 return "sub{l}\t{%2, %k0|%k0, %2}"; 5737 } 5738 return "add{l}\t{%2, %k0|%k0, %2}"; 5739 } 5740} 5741 [(set (attr "type") 5742 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5743 (const_string "incdec") 5744 (const_string "alu"))) 5745 (set_attr "mode" "SI")]) 5746 5747; For comparisons against 1, -1 and 128, we may generate better code 5748; by converting cmp to add, inc or dec as done by peephole2. This pattern 5749; is matched then. We can't accept general immediate, because for 5750; case of overflows, the result is messed up. 5751; This pattern also don't hold of 0x80000000, since the value overflows 5752; when negated. 5753; Also carry flag is reversed compared to cmp, so this conversion is valid 5754; only for comparisons not depending on it. 5755(define_insn "*addsi_4" 5756 [(set (reg FLAGS_REG) 5757 (compare (match_operand:SI 1 "nonimmediate_operand" "0") 5758 (match_operand:SI 2 "const_int_operand" "n"))) 5759 (clobber (match_scratch:SI 0 "=rm"))] 5760 "ix86_match_ccmode (insn, CCGCmode) 5761 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000" 5762{ 5763 switch (get_attr_type (insn)) 5764 { 5765 case TYPE_INCDEC: 5766 if (operands[2] == constm1_rtx) 5767 return "inc{l}\t%0"; 5768 else 5769 { 5770 gcc_assert (operands[2] == const1_rtx); 5771 return "dec{l}\t%0"; 5772 } 5773 5774 default: 5775 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5776 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5777 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5778 if ((INTVAL (operands[2]) == -128 5779 || (INTVAL (operands[2]) > 0 5780 && INTVAL (operands[2]) != 128))) 5781 return "sub{l}\t{%2, %0|%0, %2}"; 5782 operands[2] = GEN_INT (-INTVAL (operands[2])); 5783 return "add{l}\t{%2, %0|%0, %2}"; 5784 } 5785} 5786 [(set (attr "type") 5787 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5788 (const_string "incdec") 5789 (const_string "alu"))) 5790 (set_attr "mode" "SI")]) 5791 5792(define_insn "*addsi_5" 5793 [(set (reg FLAGS_REG) 5794 (compare 5795 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 5796 (match_operand:SI 2 "general_operand" "rmni")) 5797 (const_int 0))) 5798 (clobber (match_scratch:SI 0 "=r"))] 5799 "ix86_match_ccmode (insn, CCGOCmode) 5800 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5801 /* Current assemblers are broken and do not allow @GOTOFF in 5802 ought but a memory context. */ 5803 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5804{ 5805 switch (get_attr_type (insn)) 5806 { 5807 case TYPE_INCDEC: 5808 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5809 if (operands[2] == const1_rtx) 5810 return "inc{l}\t%0"; 5811 else 5812 { 5813 gcc_assert (operands[2] == constm1_rtx); 5814 return "dec{l}\t%0"; 5815 } 5816 5817 default: 5818 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5819 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5820 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5821 if (GET_CODE (operands[2]) == CONST_INT 5822 && (INTVAL (operands[2]) == 128 5823 || (INTVAL (operands[2]) < 0 5824 && INTVAL (operands[2]) != -128))) 5825 { 5826 operands[2] = GEN_INT (-INTVAL (operands[2])); 5827 return "sub{l}\t{%2, %0|%0, %2}"; 5828 } 5829 return "add{l}\t{%2, %0|%0, %2}"; 5830 } 5831} 5832 [(set (attr "type") 5833 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5834 (const_string "incdec") 5835 (const_string "alu"))) 5836 (set_attr "mode" "SI")]) 5837 5838(define_expand "addhi3" 5839 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 5840 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "") 5841 (match_operand:HI 2 "general_operand" ""))) 5842 (clobber (reg:CC FLAGS_REG))])] 5843 "TARGET_HIMODE_MATH" 5844 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;") 5845 5846;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah 5847;; type optimizations enabled by define-splits. This is not important 5848;; for PII, and in fact harmful because of partial register stalls. 5849 5850(define_insn "*addhi_1_lea" 5851 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") 5852 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r") 5853 (match_operand:HI 2 "general_operand" "ri,rm,lni"))) 5854 (clobber (reg:CC FLAGS_REG))] 5855 "!TARGET_PARTIAL_REG_STALL 5856 && ix86_binary_operator_ok (PLUS, HImode, operands)" 5857{ 5858 switch (get_attr_type (insn)) 5859 { 5860 case TYPE_LEA: 5861 return "#"; 5862 case TYPE_INCDEC: 5863 if (operands[2] == const1_rtx) 5864 return "inc{w}\t%0"; 5865 else 5866 { 5867 gcc_assert (operands[2] == constm1_rtx); 5868 return "dec{w}\t%0"; 5869 } 5870 5871 default: 5872 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5873 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5874 if (GET_CODE (operands[2]) == CONST_INT 5875 && (INTVAL (operands[2]) == 128 5876 || (INTVAL (operands[2]) < 0 5877 && INTVAL (operands[2]) != -128))) 5878 { 5879 operands[2] = GEN_INT (-INTVAL (operands[2])); 5880 return "sub{w}\t{%2, %0|%0, %2}"; 5881 } 5882 return "add{w}\t{%2, %0|%0, %2}"; 5883 } 5884} 5885 [(set (attr "type") 5886 (if_then_else (eq_attr "alternative" "2") 5887 (const_string "lea") 5888 (if_then_else (match_operand:HI 2 "incdec_operand" "") 5889 (const_string "incdec") 5890 (const_string "alu")))) 5891 (set_attr "mode" "HI,HI,SI")]) 5892 5893(define_insn "*addhi_1" 5894 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 5895 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 5896 (match_operand:HI 2 "general_operand" "ri,rm"))) 5897 (clobber (reg:CC FLAGS_REG))] 5898 "TARGET_PARTIAL_REG_STALL 5899 && ix86_binary_operator_ok (PLUS, HImode, operands)" 5900{ 5901 switch (get_attr_type (insn)) 5902 { 5903 case TYPE_INCDEC: 5904 if (operands[2] == const1_rtx) 5905 return "inc{w}\t%0"; 5906 else 5907 { 5908 gcc_assert (operands[2] == constm1_rtx); 5909 return "dec{w}\t%0"; 5910 } 5911 5912 default: 5913 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5914 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5915 if (GET_CODE (operands[2]) == CONST_INT 5916 && (INTVAL (operands[2]) == 128 5917 || (INTVAL (operands[2]) < 0 5918 && INTVAL (operands[2]) != -128))) 5919 { 5920 operands[2] = GEN_INT (-INTVAL (operands[2])); 5921 return "sub{w}\t{%2, %0|%0, %2}"; 5922 } 5923 return "add{w}\t{%2, %0|%0, %2}"; 5924 } 5925} 5926 [(set (attr "type") 5927 (if_then_else (match_operand:HI 2 "incdec_operand" "") 5928 (const_string "incdec") 5929 (const_string "alu"))) 5930 (set_attr "mode" "HI")]) 5931 5932(define_insn "*addhi_2" 5933 [(set (reg FLAGS_REG) 5934 (compare 5935 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 5936 (match_operand:HI 2 "general_operand" "rmni,rni")) 5937 (const_int 0))) 5938 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 5939 (plus:HI (match_dup 1) (match_dup 2)))] 5940 "ix86_match_ccmode (insn, CCGOCmode) 5941 && ix86_binary_operator_ok (PLUS, HImode, operands)" 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(define_insn "*addhi_3" 5975 [(set (reg FLAGS_REG) 5976 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni")) 5977 (match_operand:HI 1 "nonimmediate_operand" "%0"))) 5978 (clobber (match_scratch:HI 0 "=r"))] 5979 "ix86_match_ccmode (insn, CCZmode) 5980 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 5981{ 5982 switch (get_attr_type (insn)) 5983 { 5984 case TYPE_INCDEC: 5985 if (operands[2] == const1_rtx) 5986 return "inc{w}\t%0"; 5987 else 5988 { 5989 gcc_assert (operands[2] == constm1_rtx); 5990 return "dec{w}\t%0"; 5991 } 5992 5993 default: 5994 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5995 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5996 if (GET_CODE (operands[2]) == CONST_INT 5997 && (INTVAL (operands[2]) == 128 5998 || (INTVAL (operands[2]) < 0 5999 && INTVAL (operands[2]) != -128))) 6000 { 6001 operands[2] = GEN_INT (-INTVAL (operands[2])); 6002 return "sub{w}\t{%2, %0|%0, %2}"; 6003 } 6004 return "add{w}\t{%2, %0|%0, %2}"; 6005 } 6006} 6007 [(set (attr "type") 6008 (if_then_else (match_operand:HI 2 "incdec_operand" "") 6009 (const_string "incdec") 6010 (const_string "alu"))) 6011 (set_attr "mode" "HI")]) 6012 6013; See comments above addsi_4 for details. 6014(define_insn "*addhi_4" 6015 [(set (reg FLAGS_REG) 6016 (compare (match_operand:HI 1 "nonimmediate_operand" "0") 6017 (match_operand:HI 2 "const_int_operand" "n"))) 6018 (clobber (match_scratch:HI 0 "=rm"))] 6019 "ix86_match_ccmode (insn, CCGCmode) 6020 && (INTVAL (operands[2]) & 0xffff) != 0x8000" 6021{ 6022 switch (get_attr_type (insn)) 6023 { 6024 case TYPE_INCDEC: 6025 if (operands[2] == constm1_rtx) 6026 return "inc{w}\t%0"; 6027 else 6028 { 6029 gcc_assert (operands[2] == const1_rtx); 6030 return "dec{w}\t%0"; 6031 } 6032 6033 default: 6034 gcc_assert (rtx_equal_p (operands[0], operands[1])); 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 ((INTVAL (operands[2]) == -128 6038 || (INTVAL (operands[2]) > 0 6039 && INTVAL (operands[2]) != 128))) 6040 return "sub{w}\t{%2, %0|%0, %2}"; 6041 operands[2] = GEN_INT (-INTVAL (operands[2])); 6042 return "add{w}\t{%2, %0|%0, %2}"; 6043 } 6044} 6045 [(set (attr "type") 6046 (if_then_else (match_operand:HI 2 "incdec_operand" "") 6047 (const_string "incdec") 6048 (const_string "alu"))) 6049 (set_attr "mode" "SI")]) 6050 6051 6052(define_insn "*addhi_5" 6053 [(set (reg FLAGS_REG) 6054 (compare 6055 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0") 6056 (match_operand:HI 2 "general_operand" "rmni")) 6057 (const_int 0))) 6058 (clobber (match_scratch:HI 0 "=r"))] 6059 "ix86_match_ccmode (insn, CCGOCmode) 6060 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6061{ 6062 switch (get_attr_type (insn)) 6063 { 6064 case TYPE_INCDEC: 6065 if (operands[2] == const1_rtx) 6066 return "inc{w}\t%0"; 6067 else 6068 { 6069 gcc_assert (operands[2] == constm1_rtx); 6070 return "dec{w}\t%0"; 6071 } 6072 6073 default: 6074 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 6075 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 6076 if (GET_CODE (operands[2]) == CONST_INT 6077 && (INTVAL (operands[2]) == 128 6078 || (INTVAL (operands[2]) < 0 6079 && INTVAL (operands[2]) != -128))) 6080 { 6081 operands[2] = GEN_INT (-INTVAL (operands[2])); 6082 return "sub{w}\t{%2, %0|%0, %2}"; 6083 } 6084 return "add{w}\t{%2, %0|%0, %2}"; 6085 } 6086} 6087 [(set (attr "type") 6088 (if_then_else (match_operand:HI 2 "incdec_operand" "") 6089 (const_string "incdec") 6090 (const_string "alu"))) 6091 (set_attr "mode" "HI")]) 6092 6093(define_expand "addqi3" 6094 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") 6095 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "") 6096 (match_operand:QI 2 "general_operand" ""))) 6097 (clobber (reg:CC FLAGS_REG))])] 6098 "TARGET_QIMODE_MATH" 6099 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;") 6100 6101;; %%% Potential partial reg stall on alternative 2. What to do? 6102(define_insn "*addqi_1_lea" 6103 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r") 6104 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r") 6105 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln"))) 6106 (clobber (reg:CC FLAGS_REG))] 6107 "!TARGET_PARTIAL_REG_STALL 6108 && ix86_binary_operator_ok (PLUS, QImode, operands)" 6109{ 6110 int widen = (which_alternative == 2); 6111 switch (get_attr_type (insn)) 6112 { 6113 case TYPE_LEA: 6114 return "#"; 6115 case TYPE_INCDEC: 6116 if (operands[2] == const1_rtx) 6117 return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; 6118 else 6119 { 6120 gcc_assert (operands[2] == constm1_rtx); 6121 return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; 6122 } 6123 6124 default: 6125 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 6126 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 6127 if (GET_CODE (operands[2]) == CONST_INT 6128 && (INTVAL (operands[2]) == 128 6129 || (INTVAL (operands[2]) < 0 6130 && INTVAL (operands[2]) != -128))) 6131 { 6132 operands[2] = GEN_INT (-INTVAL (operands[2])); 6133 if (widen) 6134 return "sub{l}\t{%2, %k0|%k0, %2}"; 6135 else 6136 return "sub{b}\t{%2, %0|%0, %2}"; 6137 } 6138 if (widen) 6139 return "add{l}\t{%k2, %k0|%k0, %k2}"; 6140 else 6141 return "add{b}\t{%2, %0|%0, %2}"; 6142 } 6143} 6144 [(set (attr "type") 6145 (if_then_else (eq_attr "alternative" "3") 6146 (const_string "lea") 6147 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6148 (const_string "incdec") 6149 (const_string "alu")))) 6150 (set_attr "mode" "QI,QI,SI,SI")]) 6151 6152(define_insn "*addqi_1" 6153 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 6154 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 6155 (match_operand:QI 2 "general_operand" "qn,qmn,rn"))) 6156 (clobber (reg:CC FLAGS_REG))] 6157 "TARGET_PARTIAL_REG_STALL 6158 && ix86_binary_operator_ok (PLUS, QImode, operands)" 6159{ 6160 int widen = (which_alternative == 2); 6161 switch (get_attr_type (insn)) 6162 { 6163 case TYPE_INCDEC: 6164 if (operands[2] == const1_rtx) 6165 return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; 6166 else 6167 { 6168 gcc_assert (operands[2] == constm1_rtx); 6169 return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; 6170 } 6171 6172 default: 6173 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 6174 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 6175 if (GET_CODE (operands[2]) == CONST_INT 6176 && (INTVAL (operands[2]) == 128 6177 || (INTVAL (operands[2]) < 0 6178 && INTVAL (operands[2]) != -128))) 6179 { 6180 operands[2] = GEN_INT (-INTVAL (operands[2])); 6181 if (widen) 6182 return "sub{l}\t{%2, %k0|%k0, %2}"; 6183 else 6184 return "sub{b}\t{%2, %0|%0, %2}"; 6185 } 6186 if (widen) 6187 return "add{l}\t{%k2, %k0|%k0, %k2}"; 6188 else 6189 return "add{b}\t{%2, %0|%0, %2}"; 6190 } 6191} 6192 [(set (attr "type") 6193 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6194 (const_string "incdec") 6195 (const_string "alu"))) 6196 (set_attr "mode" "QI,QI,SI")]) 6197 6198(define_insn "*addqi_1_slp" 6199 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 6200 (plus:QI (match_dup 0) 6201 (match_operand:QI 1 "general_operand" "qn,qnm"))) 6202 (clobber (reg:CC FLAGS_REG))] 6203 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 6204 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 6205{ 6206 switch (get_attr_type (insn)) 6207 { 6208 case TYPE_INCDEC: 6209 if (operands[1] == const1_rtx) 6210 return "inc{b}\t%0"; 6211 else 6212 { 6213 gcc_assert (operands[1] == constm1_rtx); 6214 return "dec{b}\t%0"; 6215 } 6216 6217 default: 6218 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */ 6219 if (GET_CODE (operands[1]) == CONST_INT 6220 && INTVAL (operands[1]) < 0) 6221 { 6222 operands[1] = GEN_INT (-INTVAL (operands[1])); 6223 return "sub{b}\t{%1, %0|%0, %1}"; 6224 } 6225 return "add{b}\t{%1, %0|%0, %1}"; 6226 } 6227} 6228 [(set (attr "type") 6229 (if_then_else (match_operand:QI 1 "incdec_operand" "") 6230 (const_string "incdec") 6231 (const_string "alu1"))) 6232 (set (attr "memory") 6233 (if_then_else (match_operand 1 "memory_operand" "") 6234 (const_string "load") 6235 (const_string "none"))) 6236 (set_attr "mode" "QI")]) 6237 6238(define_insn "*addqi_2" 6239 [(set (reg FLAGS_REG) 6240 (compare 6241 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 6242 (match_operand:QI 2 "general_operand" "qmni,qni")) 6243 (const_int 0))) 6244 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 6245 (plus:QI (match_dup 1) (match_dup 2)))] 6246 "ix86_match_ccmode (insn, CCGOCmode) 6247 && ix86_binary_operator_ok (PLUS, QImode, operands)" 6248{ 6249 switch (get_attr_type (insn)) 6250 { 6251 case TYPE_INCDEC: 6252 if (operands[2] == const1_rtx) 6253 return "inc{b}\t%0"; 6254 else 6255 { 6256 gcc_assert (operands[2] == constm1_rtx 6257 || (GET_CODE (operands[2]) == CONST_INT 6258 && INTVAL (operands[2]) == 255)); 6259 return "dec{b}\t%0"; 6260 } 6261 6262 default: 6263 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ 6264 if (GET_CODE (operands[2]) == CONST_INT 6265 && INTVAL (operands[2]) < 0) 6266 { 6267 operands[2] = GEN_INT (-INTVAL (operands[2])); 6268 return "sub{b}\t{%2, %0|%0, %2}"; 6269 } 6270 return "add{b}\t{%2, %0|%0, %2}"; 6271 } 6272} 6273 [(set (attr "type") 6274 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6275 (const_string "incdec") 6276 (const_string "alu"))) 6277 (set_attr "mode" "QI")]) 6278 6279(define_insn "*addqi_3" 6280 [(set (reg FLAGS_REG) 6281 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni")) 6282 (match_operand:QI 1 "nonimmediate_operand" "%0"))) 6283 (clobber (match_scratch:QI 0 "=q"))] 6284 "ix86_match_ccmode (insn, CCZmode) 6285 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6286{ 6287 switch (get_attr_type (insn)) 6288 { 6289 case TYPE_INCDEC: 6290 if (operands[2] == const1_rtx) 6291 return "inc{b}\t%0"; 6292 else 6293 { 6294 gcc_assert (operands[2] == constm1_rtx 6295 || (GET_CODE (operands[2]) == CONST_INT 6296 && INTVAL (operands[2]) == 255)); 6297 return "dec{b}\t%0"; 6298 } 6299 6300 default: 6301 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ 6302 if (GET_CODE (operands[2]) == CONST_INT 6303 && INTVAL (operands[2]) < 0) 6304 { 6305 operands[2] = GEN_INT (-INTVAL (operands[2])); 6306 return "sub{b}\t{%2, %0|%0, %2}"; 6307 } 6308 return "add{b}\t{%2, %0|%0, %2}"; 6309 } 6310} 6311 [(set (attr "type") 6312 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6313 (const_string "incdec") 6314 (const_string "alu"))) 6315 (set_attr "mode" "QI")]) 6316 6317; See comments above addsi_4 for details. 6318(define_insn "*addqi_4" 6319 [(set (reg FLAGS_REG) 6320 (compare (match_operand:QI 1 "nonimmediate_operand" "0") 6321 (match_operand:QI 2 "const_int_operand" "n"))) 6322 (clobber (match_scratch:QI 0 "=qm"))] 6323 "ix86_match_ccmode (insn, CCGCmode) 6324 && (INTVAL (operands[2]) & 0xff) != 0x80" 6325{ 6326 switch (get_attr_type (insn)) 6327 { 6328 case TYPE_INCDEC: 6329 if (operands[2] == constm1_rtx 6330 || (GET_CODE (operands[2]) == CONST_INT 6331 && INTVAL (operands[2]) == 255)) 6332 return "inc{b}\t%0"; 6333 else 6334 { 6335 gcc_assert (operands[2] == const1_rtx); 6336 return "dec{b}\t%0"; 6337 } 6338 6339 default: 6340 gcc_assert (rtx_equal_p (operands[0], operands[1])); 6341 if (INTVAL (operands[2]) < 0) 6342 { 6343 operands[2] = GEN_INT (-INTVAL (operands[2])); 6344 return "add{b}\t{%2, %0|%0, %2}"; 6345 } 6346 return "sub{b}\t{%2, %0|%0, %2}"; 6347 } 6348} 6349 [(set (attr "type") 6350 (if_then_else (match_operand:HI 2 "incdec_operand" "") 6351 (const_string "incdec") 6352 (const_string "alu"))) 6353 (set_attr "mode" "QI")]) 6354 6355 6356(define_insn "*addqi_5" 6357 [(set (reg FLAGS_REG) 6358 (compare 6359 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 6360 (match_operand:QI 2 "general_operand" "qmni")) 6361 (const_int 0))) 6362 (clobber (match_scratch:QI 0 "=q"))] 6363 "ix86_match_ccmode (insn, CCGOCmode) 6364 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6365{ 6366 switch (get_attr_type (insn)) 6367 { 6368 case TYPE_INCDEC: 6369 if (operands[2] == const1_rtx) 6370 return "inc{b}\t%0"; 6371 else 6372 { 6373 gcc_assert (operands[2] == constm1_rtx 6374 || (GET_CODE (operands[2]) == CONST_INT 6375 && INTVAL (operands[2]) == 255)); 6376 return "dec{b}\t%0"; 6377 } 6378 6379 default: 6380 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ 6381 if (GET_CODE (operands[2]) == CONST_INT 6382 && INTVAL (operands[2]) < 0) 6383 { 6384 operands[2] = GEN_INT (-INTVAL (operands[2])); 6385 return "sub{b}\t{%2, %0|%0, %2}"; 6386 } 6387 return "add{b}\t{%2, %0|%0, %2}"; 6388 } 6389} 6390 [(set (attr "type") 6391 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6392 (const_string "incdec") 6393 (const_string "alu"))) 6394 (set_attr "mode" "QI")]) 6395 6396 6397(define_insn "addqi_ext_1" 6398 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6399 (const_int 8) 6400 (const_int 8)) 6401 (plus:SI 6402 (zero_extract:SI 6403 (match_operand 1 "ext_register_operand" "0") 6404 (const_int 8) 6405 (const_int 8)) 6406 (match_operand:QI 2 "general_operand" "Qmn"))) 6407 (clobber (reg:CC FLAGS_REG))] 6408 "!TARGET_64BIT" 6409{ 6410 switch (get_attr_type (insn)) 6411 { 6412 case TYPE_INCDEC: 6413 if (operands[2] == const1_rtx) 6414 return "inc{b}\t%h0"; 6415 else 6416 { 6417 gcc_assert (operands[2] == constm1_rtx 6418 || (GET_CODE (operands[2]) == CONST_INT 6419 && INTVAL (operands[2]) == 255)); 6420 return "dec{b}\t%h0"; 6421 } 6422 6423 default: 6424 return "add{b}\t{%2, %h0|%h0, %2}"; 6425 } 6426} 6427 [(set (attr "type") 6428 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6429 (const_string "incdec") 6430 (const_string "alu"))) 6431 (set_attr "mode" "QI")]) 6432 6433(define_insn "*addqi_ext_1_rex64" 6434 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6435 (const_int 8) 6436 (const_int 8)) 6437 (plus:SI 6438 (zero_extract:SI 6439 (match_operand 1 "ext_register_operand" "0") 6440 (const_int 8) 6441 (const_int 8)) 6442 (match_operand:QI 2 "nonmemory_operand" "Qn"))) 6443 (clobber (reg:CC FLAGS_REG))] 6444 "TARGET_64BIT" 6445{ 6446 switch (get_attr_type (insn)) 6447 { 6448 case TYPE_INCDEC: 6449 if (operands[2] == const1_rtx) 6450 return "inc{b}\t%h0"; 6451 else 6452 { 6453 gcc_assert (operands[2] == constm1_rtx 6454 || (GET_CODE (operands[2]) == CONST_INT 6455 && INTVAL (operands[2]) == 255)); 6456 return "dec{b}\t%h0"; 6457 } 6458 6459 default: 6460 return "add{b}\t{%2, %h0|%h0, %2}"; 6461 } 6462} 6463 [(set (attr "type") 6464 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6465 (const_string "incdec") 6466 (const_string "alu"))) 6467 (set_attr "mode" "QI")]) 6468 6469(define_insn "*addqi_ext_2" 6470 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6471 (const_int 8) 6472 (const_int 8)) 6473 (plus:SI 6474 (zero_extract:SI 6475 (match_operand 1 "ext_register_operand" "%0") 6476 (const_int 8) 6477 (const_int 8)) 6478 (zero_extract:SI 6479 (match_operand 2 "ext_register_operand" "Q") 6480 (const_int 8) 6481 (const_int 8)))) 6482 (clobber (reg:CC FLAGS_REG))] 6483 "" 6484 "add{b}\t{%h2, %h0|%h0, %h2}" 6485 [(set_attr "type" "alu") 6486 (set_attr "mode" "QI")]) 6487 6488;; The patterns that match these are at the end of this file. 6489 6490(define_expand "addxf3" 6491 [(set (match_operand:XF 0 "register_operand" "") 6492 (plus:XF (match_operand:XF 1 "register_operand" "") 6493 (match_operand:XF 2 "register_operand" "")))] 6494 "TARGET_80387" 6495 "") 6496 6497(define_expand "adddf3" 6498 [(set (match_operand:DF 0 "register_operand" "") 6499 (plus:DF (match_operand:DF 1 "register_operand" "") 6500 (match_operand:DF 2 "nonimmediate_operand" "")))] 6501 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 6502 "") 6503 6504(define_expand "addsf3" 6505 [(set (match_operand:SF 0 "register_operand" "") 6506 (plus:SF (match_operand:SF 1 "register_operand" "") 6507 (match_operand:SF 2 "nonimmediate_operand" "")))] 6508 "TARGET_80387 || TARGET_SSE_MATH" 6509 "") 6510 6511;; Subtract instructions 6512 6513;; %%% splits for subditi3 6514 6515(define_expand "subti3" 6516 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "") 6517 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "") 6518 (match_operand:TI 2 "x86_64_general_operand" ""))) 6519 (clobber (reg:CC FLAGS_REG))])] 6520 "TARGET_64BIT" 6521 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;") 6522 6523(define_insn "*subti3_1" 6524 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o") 6525 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0") 6526 (match_operand:TI 2 "x86_64_general_operand" "roe,re"))) 6527 (clobber (reg:CC FLAGS_REG))] 6528 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)" 6529 "#") 6530 6531(define_split 6532 [(set (match_operand:TI 0 "nonimmediate_operand" "") 6533 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "") 6534 (match_operand:TI 2 "x86_64_general_operand" ""))) 6535 (clobber (reg:CC FLAGS_REG))] 6536 "TARGET_64BIT && reload_completed" 6537 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2))) 6538 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))]) 6539 (parallel [(set (match_dup 3) 6540 (minus:DI (match_dup 4) 6541 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) 6542 (match_dup 5)))) 6543 (clobber (reg:CC FLAGS_REG))])] 6544 "split_ti (operands+0, 1, operands+0, operands+3); 6545 split_ti (operands+1, 1, operands+1, operands+4); 6546 split_ti (operands+2, 1, operands+2, operands+5);") 6547 6548;; %%% splits for subsidi3 6549 6550(define_expand "subdi3" 6551 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 6552 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "") 6553 (match_operand:DI 2 "x86_64_general_operand" ""))) 6554 (clobber (reg:CC FLAGS_REG))])] 6555 "" 6556 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;") 6557 6558(define_insn "*subdi3_1" 6559 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") 6560 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6561 (match_operand:DI 2 "general_operand" "roiF,riF"))) 6562 (clobber (reg:CC FLAGS_REG))] 6563 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" 6564 "#") 6565 6566(define_split 6567 [(set (match_operand:DI 0 "nonimmediate_operand" "") 6568 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "") 6569 (match_operand:DI 2 "general_operand" ""))) 6570 (clobber (reg:CC FLAGS_REG))] 6571 "!TARGET_64BIT && reload_completed" 6572 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2))) 6573 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 6574 (parallel [(set (match_dup 3) 6575 (minus:SI (match_dup 4) 6576 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) 6577 (match_dup 5)))) 6578 (clobber (reg:CC FLAGS_REG))])] 6579 "split_di (operands+0, 1, operands+0, operands+3); 6580 split_di (operands+1, 1, operands+1, operands+4); 6581 split_di (operands+2, 1, operands+2, operands+5);") 6582 6583(define_insn "subdi3_carry_rex64" 6584 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6585 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6586 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "") 6587 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))) 6588 (clobber (reg:CC FLAGS_REG))] 6589 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" 6590 "sbb{q}\t{%2, %0|%0, %2}" 6591 [(set_attr "type" "alu") 6592 (set_attr "pent_pair" "pu") 6593 (set_attr "mode" "DI")]) 6594 6595(define_insn "*subdi_1_rex64" 6596 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6597 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6598 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 6599 (clobber (reg:CC FLAGS_REG))] 6600 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" 6601 "sub{q}\t{%2, %0|%0, %2}" 6602 [(set_attr "type" "alu") 6603 (set_attr "mode" "DI")]) 6604 6605(define_insn "*subdi_2_rex64" 6606 [(set (reg FLAGS_REG) 6607 (compare 6608 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6609 (match_operand:DI 2 "x86_64_general_operand" "re,rm")) 6610 (const_int 0))) 6611 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6612 (minus:DI (match_dup 1) (match_dup 2)))] 6613 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 6614 && ix86_binary_operator_ok (MINUS, DImode, operands)" 6615 "sub{q}\t{%2, %0|%0, %2}" 6616 [(set_attr "type" "alu") 6617 (set_attr "mode" "DI")]) 6618 6619(define_insn "*subdi_3_rex63" 6620 [(set (reg FLAGS_REG) 6621 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0") 6622 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 6623 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6624 (minus:DI (match_dup 1) (match_dup 2)))] 6625 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 6626 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6627 "sub{q}\t{%2, %0|%0, %2}" 6628 [(set_attr "type" "alu") 6629 (set_attr "mode" "DI")]) 6630 6631(define_insn "subqi3_carry" 6632 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 6633 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 6634 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "") 6635 (match_operand:QI 2 "general_operand" "qi,qm")))) 6636 (clobber (reg:CC FLAGS_REG))] 6637 "ix86_binary_operator_ok (MINUS, QImode, operands)" 6638 "sbb{b}\t{%2, %0|%0, %2}" 6639 [(set_attr "type" "alu") 6640 (set_attr "pent_pair" "pu") 6641 (set_attr "mode" "QI")]) 6642 6643(define_insn "subhi3_carry" 6644 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6645 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 6646 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "") 6647 (match_operand:HI 2 "general_operand" "ri,rm")))) 6648 (clobber (reg:CC FLAGS_REG))] 6649 "ix86_binary_operator_ok (MINUS, HImode, operands)" 6650 "sbb{w}\t{%2, %0|%0, %2}" 6651 [(set_attr "type" "alu") 6652 (set_attr "pent_pair" "pu") 6653 (set_attr "mode" "HI")]) 6654 6655(define_insn "subsi3_carry" 6656 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6657 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6658 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 6659 (match_operand:SI 2 "general_operand" "ri,rm")))) 6660 (clobber (reg:CC FLAGS_REG))] 6661 "ix86_binary_operator_ok (MINUS, SImode, operands)" 6662 "sbb{l}\t{%2, %0|%0, %2}" 6663 [(set_attr "type" "alu") 6664 (set_attr "pent_pair" "pu") 6665 (set_attr "mode" "SI")]) 6666 6667(define_insn "subsi3_carry_zext" 6668 [(set (match_operand:DI 0 "register_operand" "=rm,r") 6669 (zero_extend:DI 6670 (minus:SI (match_operand:SI 1 "register_operand" "0,0") 6671 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 6672 (match_operand:SI 2 "general_operand" "ri,rm"))))) 6673 (clobber (reg:CC FLAGS_REG))] 6674 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6675 "sbb{l}\t{%2, %k0|%k0, %2}" 6676 [(set_attr "type" "alu") 6677 (set_attr "pent_pair" "pu") 6678 (set_attr "mode" "SI")]) 6679 6680(define_expand "subsi3" 6681 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 6682 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "") 6683 (match_operand:SI 2 "general_operand" ""))) 6684 (clobber (reg:CC FLAGS_REG))])] 6685 "" 6686 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;") 6687 6688(define_insn "*subsi_1" 6689 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6690 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6691 (match_operand:SI 2 "general_operand" "ri,rm"))) 6692 (clobber (reg:CC FLAGS_REG))] 6693 "ix86_binary_operator_ok (MINUS, SImode, operands)" 6694 "sub{l}\t{%2, %0|%0, %2}" 6695 [(set_attr "type" "alu") 6696 (set_attr "mode" "SI")]) 6697 6698(define_insn "*subsi_1_zext" 6699 [(set (match_operand:DI 0 "register_operand" "=r") 6700 (zero_extend:DI 6701 (minus:SI (match_operand:SI 1 "register_operand" "0") 6702 (match_operand:SI 2 "general_operand" "rim")))) 6703 (clobber (reg:CC FLAGS_REG))] 6704 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6705 "sub{l}\t{%2, %k0|%k0, %2}" 6706 [(set_attr "type" "alu") 6707 (set_attr "mode" "SI")]) 6708 6709(define_insn "*subsi_2" 6710 [(set (reg FLAGS_REG) 6711 (compare 6712 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6713 (match_operand:SI 2 "general_operand" "ri,rm")) 6714 (const_int 0))) 6715 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6716 (minus:SI (match_dup 1) (match_dup 2)))] 6717 "ix86_match_ccmode (insn, CCGOCmode) 6718 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6719 "sub{l}\t{%2, %0|%0, %2}" 6720 [(set_attr "type" "alu") 6721 (set_attr "mode" "SI")]) 6722 6723(define_insn "*subsi_2_zext" 6724 [(set (reg FLAGS_REG) 6725 (compare 6726 (minus:SI (match_operand:SI 1 "register_operand" "0") 6727 (match_operand:SI 2 "general_operand" "rim")) 6728 (const_int 0))) 6729 (set (match_operand:DI 0 "register_operand" "=r") 6730 (zero_extend:DI 6731 (minus:SI (match_dup 1) 6732 (match_dup 2))))] 6733 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 6734 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6735 "sub{l}\t{%2, %k0|%k0, %2}" 6736 [(set_attr "type" "alu") 6737 (set_attr "mode" "SI")]) 6738 6739(define_insn "*subsi_3" 6740 [(set (reg FLAGS_REG) 6741 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0") 6742 (match_operand:SI 2 "general_operand" "ri,rm"))) 6743 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6744 (minus:SI (match_dup 1) (match_dup 2)))] 6745 "ix86_match_ccmode (insn, CCmode) 6746 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6747 "sub{l}\t{%2, %0|%0, %2}" 6748 [(set_attr "type" "alu") 6749 (set_attr "mode" "SI")]) 6750 6751(define_insn "*subsi_3_zext" 6752 [(set (reg FLAGS_REG) 6753 (compare (match_operand:SI 1 "register_operand" "0") 6754 (match_operand:SI 2 "general_operand" "rim"))) 6755 (set (match_operand:DI 0 "register_operand" "=r") 6756 (zero_extend:DI 6757 (minus:SI (match_dup 1) 6758 (match_dup 2))))] 6759 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 6760 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6761 "sub{l}\t{%2, %1|%1, %2}" 6762 [(set_attr "type" "alu") 6763 (set_attr "mode" "DI")]) 6764 6765(define_expand "subhi3" 6766 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 6767 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "") 6768 (match_operand:HI 2 "general_operand" ""))) 6769 (clobber (reg:CC FLAGS_REG))])] 6770 "TARGET_HIMODE_MATH" 6771 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;") 6772 6773(define_insn "*subhi_1" 6774 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6775 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 6776 (match_operand:HI 2 "general_operand" "ri,rm"))) 6777 (clobber (reg:CC FLAGS_REG))] 6778 "ix86_binary_operator_ok (MINUS, HImode, operands)" 6779 "sub{w}\t{%2, %0|%0, %2}" 6780 [(set_attr "type" "alu") 6781 (set_attr "mode" "HI")]) 6782 6783(define_insn "*subhi_2" 6784 [(set (reg FLAGS_REG) 6785 (compare 6786 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 6787 (match_operand:HI 2 "general_operand" "ri,rm")) 6788 (const_int 0))) 6789 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6790 (minus:HI (match_dup 1) (match_dup 2)))] 6791 "ix86_match_ccmode (insn, CCGOCmode) 6792 && ix86_binary_operator_ok (MINUS, HImode, operands)" 6793 "sub{w}\t{%2, %0|%0, %2}" 6794 [(set_attr "type" "alu") 6795 (set_attr "mode" "HI")]) 6796 6797(define_insn "*subhi_3" 6798 [(set (reg FLAGS_REG) 6799 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0") 6800 (match_operand:HI 2 "general_operand" "ri,rm"))) 6801 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6802 (minus:HI (match_dup 1) (match_dup 2)))] 6803 "ix86_match_ccmode (insn, CCmode) 6804 && ix86_binary_operator_ok (MINUS, HImode, operands)" 6805 "sub{w}\t{%2, %0|%0, %2}" 6806 [(set_attr "type" "alu") 6807 (set_attr "mode" "HI")]) 6808 6809(define_expand "subqi3" 6810 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") 6811 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "") 6812 (match_operand:QI 2 "general_operand" ""))) 6813 (clobber (reg:CC FLAGS_REG))])] 6814 "TARGET_QIMODE_MATH" 6815 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;") 6816 6817(define_insn "*subqi_1" 6818 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 6819 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 6820 (match_operand:QI 2 "general_operand" "qn,qmn"))) 6821 (clobber (reg:CC FLAGS_REG))] 6822 "ix86_binary_operator_ok (MINUS, QImode, operands)" 6823 "sub{b}\t{%2, %0|%0, %2}" 6824 [(set_attr "type" "alu") 6825 (set_attr "mode" "QI")]) 6826 6827(define_insn "*subqi_1_slp" 6828 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 6829 (minus:QI (match_dup 0) 6830 (match_operand:QI 1 "general_operand" "qn,qmn"))) 6831 (clobber (reg:CC FLAGS_REG))] 6832 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 6833 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 6834 "sub{b}\t{%1, %0|%0, %1}" 6835 [(set_attr "type" "alu1") 6836 (set_attr "mode" "QI")]) 6837 6838(define_insn "*subqi_2" 6839 [(set (reg FLAGS_REG) 6840 (compare 6841 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 6842 (match_operand:QI 2 "general_operand" "qi,qm")) 6843 (const_int 0))) 6844 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q") 6845 (minus:HI (match_dup 1) (match_dup 2)))] 6846 "ix86_match_ccmode (insn, CCGOCmode) 6847 && ix86_binary_operator_ok (MINUS, QImode, operands)" 6848 "sub{b}\t{%2, %0|%0, %2}" 6849 [(set_attr "type" "alu") 6850 (set_attr "mode" "QI")]) 6851 6852(define_insn "*subqi_3" 6853 [(set (reg FLAGS_REG) 6854 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0") 6855 (match_operand:QI 2 "general_operand" "qi,qm"))) 6856 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q") 6857 (minus:HI (match_dup 1) (match_dup 2)))] 6858 "ix86_match_ccmode (insn, CCmode) 6859 && ix86_binary_operator_ok (MINUS, QImode, operands)" 6860 "sub{b}\t{%2, %0|%0, %2}" 6861 [(set_attr "type" "alu") 6862 (set_attr "mode" "QI")]) 6863 6864;; The patterns that match these are at the end of this file. 6865 6866(define_expand "subxf3" 6867 [(set (match_operand:XF 0 "register_operand" "") 6868 (minus:XF (match_operand:XF 1 "register_operand" "") 6869 (match_operand:XF 2 "register_operand" "")))] 6870 "TARGET_80387" 6871 "") 6872 6873(define_expand "subdf3" 6874 [(set (match_operand:DF 0 "register_operand" "") 6875 (minus:DF (match_operand:DF 1 "register_operand" "") 6876 (match_operand:DF 2 "nonimmediate_operand" "")))] 6877 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 6878 "") 6879 6880(define_expand "subsf3" 6881 [(set (match_operand:SF 0 "register_operand" "") 6882 (minus:SF (match_operand:SF 1 "register_operand" "") 6883 (match_operand:SF 2 "nonimmediate_operand" "")))] 6884 "TARGET_80387 || TARGET_SSE_MATH" 6885 "") 6886 6887;; Multiply instructions 6888 6889(define_expand "muldi3" 6890 [(parallel [(set (match_operand:DI 0 "register_operand" "") 6891 (mult:DI (match_operand:DI 1 "register_operand" "") 6892 (match_operand:DI 2 "x86_64_general_operand" ""))) 6893 (clobber (reg:CC FLAGS_REG))])] 6894 "TARGET_64BIT" 6895 "") 6896 6897;; On AMDFAM10 6898;; IMUL reg64, reg64, imm8 Direct 6899;; IMUL reg64, mem64, imm8 VectorPath 6900;; IMUL reg64, reg64, imm32 Direct 6901;; IMUL reg64, mem64, imm32 VectorPath 6902;; IMUL reg64, reg64 Direct 6903;; IMUL reg64, mem64 Direct 6904 6905(define_insn "*muldi3_1_rex64" 6906 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 6907 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0") 6908 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr"))) 6909 (clobber (reg:CC FLAGS_REG))] 6910 "TARGET_64BIT 6911 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6912 "@ 6913 imul{q}\t{%2, %1, %0|%0, %1, %2} 6914 imul{q}\t{%2, %1, %0|%0, %1, %2} 6915 imul{q}\t{%2, %0|%0, %2}" 6916 [(set_attr "type" "imul") 6917 (set_attr "prefix_0f" "0,0,1") 6918 (set (attr "athlon_decode") 6919 (cond [(eq_attr "cpu" "athlon") 6920 (const_string "vector") 6921 (eq_attr "alternative" "1") 6922 (const_string "vector") 6923 (and (eq_attr "alternative" "2") 6924 (match_operand 1 "memory_operand" "")) 6925 (const_string "vector")] 6926 (const_string "direct"))) 6927 (set (attr "amdfam10_decode") 6928 (cond [(and (eq_attr "alternative" "0,1") 6929 (match_operand 1 "memory_operand" "")) 6930 (const_string "vector")] 6931 (const_string "direct"))) 6932 (set_attr "mode" "DI")]) 6933 6934(define_expand "mulsi3" 6935 [(parallel [(set (match_operand:SI 0 "register_operand" "") 6936 (mult:SI (match_operand:SI 1 "register_operand" "") 6937 (match_operand:SI 2 "general_operand" ""))) 6938 (clobber (reg:CC FLAGS_REG))])] 6939 "" 6940 "") 6941 6942;; On AMDFAM10 6943;; IMUL reg32, reg32, imm8 Direct 6944;; IMUL reg32, mem32, imm8 VectorPath 6945;; IMUL reg32, reg32, imm32 Direct 6946;; IMUL reg32, mem32, imm32 VectorPath 6947;; IMUL reg32, reg32 Direct 6948;; IMUL reg32, mem32 Direct 6949 6950(define_insn "*mulsi3_1" 6951 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 6952 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") 6953 (match_operand:SI 2 "general_operand" "K,i,mr"))) 6954 (clobber (reg:CC FLAGS_REG))] 6955 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 6956 "@ 6957 imul{l}\t{%2, %1, %0|%0, %1, %2} 6958 imul{l}\t{%2, %1, %0|%0, %1, %2} 6959 imul{l}\t{%2, %0|%0, %2}" 6960 [(set_attr "type" "imul") 6961 (set_attr "prefix_0f" "0,0,1") 6962 (set (attr "athlon_decode") 6963 (cond [(eq_attr "cpu" "athlon") 6964 (const_string "vector") 6965 (eq_attr "alternative" "1") 6966 (const_string "vector") 6967 (and (eq_attr "alternative" "2") 6968 (match_operand 1 "memory_operand" "")) 6969 (const_string "vector")] 6970 (const_string "direct"))) 6971 (set (attr "amdfam10_decode") 6972 (cond [(and (eq_attr "alternative" "0,1") 6973 (match_operand 1 "memory_operand" "")) 6974 (const_string "vector")] 6975 (const_string "direct"))) 6976 (set_attr "mode" "SI")]) 6977 6978(define_insn "*mulsi3_1_zext" 6979 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 6980 (zero_extend:DI 6981 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") 6982 (match_operand:SI 2 "general_operand" "K,i,mr")))) 6983 (clobber (reg:CC FLAGS_REG))] 6984 "TARGET_64BIT 6985 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6986 "@ 6987 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6988 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6989 imul{l}\t{%2, %k0|%k0, %2}" 6990 [(set_attr "type" "imul") 6991 (set_attr "prefix_0f" "0,0,1") 6992 (set (attr "athlon_decode") 6993 (cond [(eq_attr "cpu" "athlon") 6994 (const_string "vector") 6995 (eq_attr "alternative" "1") 6996 (const_string "vector") 6997 (and (eq_attr "alternative" "2") 6998 (match_operand 1 "memory_operand" "")) 6999 (const_string "vector")] 7000 (const_string "direct"))) 7001 (set (attr "amdfam10_decode") 7002 (cond [(and (eq_attr "alternative" "0,1") 7003 (match_operand 1 "memory_operand" "")) 7004 (const_string "vector")] 7005 (const_string "direct"))) 7006 (set_attr "mode" "SI")]) 7007 7008(define_expand "mulhi3" 7009 [(parallel [(set (match_operand:HI 0 "register_operand" "") 7010 (mult:HI (match_operand:HI 1 "register_operand" "") 7011 (match_operand:HI 2 "general_operand" ""))) 7012 (clobber (reg:CC FLAGS_REG))])] 7013 "TARGET_HIMODE_MATH" 7014 "") 7015 7016;; On AMDFAM10 7017;; IMUL reg16, reg16, imm8 VectorPath 7018;; IMUL reg16, mem16, imm8 VectorPath 7019;; IMUL reg16, reg16, imm16 VectorPath 7020;; IMUL reg16, mem16, imm16 VectorPath 7021;; IMUL reg16, reg16 Direct 7022;; IMUL reg16, mem16 Direct 7023(define_insn "*mulhi3_1" 7024 [(set (match_operand:HI 0 "register_operand" "=r,r,r") 7025 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0") 7026 (match_operand:HI 2 "general_operand" "K,i,mr"))) 7027 (clobber (reg:CC FLAGS_REG))] 7028 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 7029 "@ 7030 imul{w}\t{%2, %1, %0|%0, %1, %2} 7031 imul{w}\t{%2, %1, %0|%0, %1, %2} 7032 imul{w}\t{%2, %0|%0, %2}" 7033 [(set_attr "type" "imul") 7034 (set_attr "prefix_0f" "0,0,1") 7035 (set (attr "athlon_decode") 7036 (cond [(eq_attr "cpu" "athlon") 7037 (const_string "vector") 7038 (eq_attr "alternative" "1,2") 7039 (const_string "vector")] 7040 (const_string "direct"))) 7041 (set (attr "amdfam10_decode") 7042 (cond [(eq_attr "alternative" "0,1") 7043 (const_string "vector")] 7044 (const_string "direct"))) 7045 (set_attr "mode" "HI")]) 7046 7047(define_expand "mulqi3" 7048 [(parallel [(set (match_operand:QI 0 "register_operand" "") 7049 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "") 7050 (match_operand:QI 2 "register_operand" ""))) 7051 (clobber (reg:CC FLAGS_REG))])] 7052 "TARGET_QIMODE_MATH" 7053 "") 7054 7055;;On AMDFAM10 7056;; MUL reg8 Direct 7057;; MUL mem8 Direct 7058 7059(define_insn "*mulqi3_1" 7060 [(set (match_operand:QI 0 "register_operand" "=a") 7061 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 7062 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 7063 (clobber (reg:CC FLAGS_REG))] 7064 "TARGET_QIMODE_MATH 7065 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7066 "mul{b}\t%2" 7067 [(set_attr "type" "imul") 7068 (set_attr "length_immediate" "0") 7069 (set (attr "athlon_decode") 7070 (if_then_else (eq_attr "cpu" "athlon") 7071 (const_string "vector") 7072 (const_string "direct"))) 7073 (set_attr "amdfam10_decode" "direct") 7074 (set_attr "mode" "QI")]) 7075 7076(define_expand "umulqihi3" 7077 [(parallel [(set (match_operand:HI 0 "register_operand" "") 7078 (mult:HI (zero_extend:HI 7079 (match_operand:QI 1 "nonimmediate_operand" "")) 7080 (zero_extend:HI 7081 (match_operand:QI 2 "register_operand" "")))) 7082 (clobber (reg:CC FLAGS_REG))])] 7083 "TARGET_QIMODE_MATH" 7084 "") 7085 7086(define_insn "*umulqihi3_1" 7087 [(set (match_operand:HI 0 "register_operand" "=a") 7088 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0")) 7089 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm")))) 7090 (clobber (reg:CC FLAGS_REG))] 7091 "TARGET_QIMODE_MATH 7092 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7093 "mul{b}\t%2" 7094 [(set_attr "type" "imul") 7095 (set_attr "length_immediate" "0") 7096 (set (attr "athlon_decode") 7097 (if_then_else (eq_attr "cpu" "athlon") 7098 (const_string "vector") 7099 (const_string "direct"))) 7100 (set_attr "amdfam10_decode" "direct") 7101 (set_attr "mode" "QI")]) 7102 7103(define_expand "mulqihi3" 7104 [(parallel [(set (match_operand:HI 0 "register_operand" "") 7105 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")) 7106 (sign_extend:HI (match_operand:QI 2 "register_operand" "")))) 7107 (clobber (reg:CC FLAGS_REG))])] 7108 "TARGET_QIMODE_MATH" 7109 "") 7110 7111(define_insn "*mulqihi3_insn" 7112 [(set (match_operand:HI 0 "register_operand" "=a") 7113 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0")) 7114 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm")))) 7115 (clobber (reg:CC FLAGS_REG))] 7116 "TARGET_QIMODE_MATH 7117 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7118 "imul{b}\t%2" 7119 [(set_attr "type" "imul") 7120 (set_attr "length_immediate" "0") 7121 (set (attr "athlon_decode") 7122 (if_then_else (eq_attr "cpu" "athlon") 7123 (const_string "vector") 7124 (const_string "direct"))) 7125 (set_attr "amdfam10_decode" "direct") 7126 (set_attr "mode" "QI")]) 7127 7128(define_expand "umulditi3" 7129 [(parallel [(set (match_operand:TI 0 "register_operand" "") 7130 (mult:TI (zero_extend:TI 7131 (match_operand:DI 1 "nonimmediate_operand" "")) 7132 (zero_extend:TI 7133 (match_operand:DI 2 "register_operand" "")))) 7134 (clobber (reg:CC FLAGS_REG))])] 7135 "TARGET_64BIT" 7136 "") 7137 7138(define_insn "*umulditi3_insn" 7139 [(set (match_operand:TI 0 "register_operand" "=A") 7140 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0")) 7141 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm")))) 7142 (clobber (reg:CC FLAGS_REG))] 7143 "TARGET_64BIT 7144 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7145 "mul{q}\t%2" 7146 [(set_attr "type" "imul") 7147 (set_attr "length_immediate" "0") 7148 (set (attr "athlon_decode") 7149 (if_then_else (eq_attr "cpu" "athlon") 7150 (const_string "vector") 7151 (const_string "double"))) 7152 (set_attr "amdfam10_decode" "double") 7153 (set_attr "mode" "DI")]) 7154 7155;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers 7156(define_expand "umulsidi3" 7157 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7158 (mult:DI (zero_extend:DI 7159 (match_operand:SI 1 "nonimmediate_operand" "")) 7160 (zero_extend:DI 7161 (match_operand:SI 2 "register_operand" "")))) 7162 (clobber (reg:CC FLAGS_REG))])] 7163 "!TARGET_64BIT" 7164 "") 7165 7166(define_insn "*umulsidi3_insn" 7167 [(set (match_operand:DI 0 "register_operand" "=A") 7168 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0")) 7169 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))) 7170 (clobber (reg:CC FLAGS_REG))] 7171 "!TARGET_64BIT 7172 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7173 "mul{l}\t%2" 7174 [(set_attr "type" "imul") 7175 (set_attr "length_immediate" "0") 7176 (set (attr "athlon_decode") 7177 (if_then_else (eq_attr "cpu" "athlon") 7178 (const_string "vector") 7179 (const_string "double"))) 7180 (set_attr "amdfam10_decode" "double") 7181 (set_attr "mode" "SI")]) 7182 7183(define_expand "mulditi3" 7184 [(parallel [(set (match_operand:TI 0 "register_operand" "") 7185 (mult:TI (sign_extend:TI 7186 (match_operand:DI 1 "nonimmediate_operand" "")) 7187 (sign_extend:TI 7188 (match_operand:DI 2 "register_operand" "")))) 7189 (clobber (reg:CC FLAGS_REG))])] 7190 "TARGET_64BIT" 7191 "") 7192 7193(define_insn "*mulditi3_insn" 7194 [(set (match_operand:TI 0 "register_operand" "=A") 7195 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0")) 7196 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm")))) 7197 (clobber (reg:CC FLAGS_REG))] 7198 "TARGET_64BIT 7199 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7200 "imul{q}\t%2" 7201 [(set_attr "type" "imul") 7202 (set_attr "length_immediate" "0") 7203 (set (attr "athlon_decode") 7204 (if_then_else (eq_attr "cpu" "athlon") 7205 (const_string "vector") 7206 (const_string "double"))) 7207 (set_attr "amdfam10_decode" "double") 7208 (set_attr "mode" "DI")]) 7209 7210(define_expand "mulsidi3" 7211 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7212 (mult:DI (sign_extend:DI 7213 (match_operand:SI 1 "nonimmediate_operand" "")) 7214 (sign_extend:DI 7215 (match_operand:SI 2 "register_operand" "")))) 7216 (clobber (reg:CC FLAGS_REG))])] 7217 "!TARGET_64BIT" 7218 "") 7219 7220(define_insn "*mulsidi3_insn" 7221 [(set (match_operand:DI 0 "register_operand" "=A") 7222 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0")) 7223 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))) 7224 (clobber (reg:CC FLAGS_REG))] 7225 "!TARGET_64BIT 7226 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7227 "imul{l}\t%2" 7228 [(set_attr "type" "imul") 7229 (set_attr "length_immediate" "0") 7230 (set (attr "athlon_decode") 7231 (if_then_else (eq_attr "cpu" "athlon") 7232 (const_string "vector") 7233 (const_string "double"))) 7234 (set_attr "amdfam10_decode" "double") 7235 (set_attr "mode" "SI")]) 7236 7237(define_expand "umuldi3_highpart" 7238 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7239 (truncate:DI 7240 (lshiftrt:TI 7241 (mult:TI (zero_extend:TI 7242 (match_operand:DI 1 "nonimmediate_operand" "")) 7243 (zero_extend:TI 7244 (match_operand:DI 2 "register_operand" ""))) 7245 (const_int 64)))) 7246 (clobber (match_scratch:DI 3 "")) 7247 (clobber (reg:CC FLAGS_REG))])] 7248 "TARGET_64BIT" 7249 "") 7250 7251(define_insn "*umuldi3_highpart_rex64" 7252 [(set (match_operand:DI 0 "register_operand" "=d") 7253 (truncate:DI 7254 (lshiftrt:TI 7255 (mult:TI (zero_extend:TI 7256 (match_operand:DI 1 "nonimmediate_operand" "%a")) 7257 (zero_extend:TI 7258 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7259 (const_int 64)))) 7260 (clobber (match_scratch:DI 3 "=1")) 7261 (clobber (reg:CC FLAGS_REG))] 7262 "TARGET_64BIT 7263 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7264 "mul{q}\t%2" 7265 [(set_attr "type" "imul") 7266 (set_attr "length_immediate" "0") 7267 (set (attr "athlon_decode") 7268 (if_then_else (eq_attr "cpu" "athlon") 7269 (const_string "vector") 7270 (const_string "double"))) 7271 (set_attr "amdfam10_decode" "double") 7272 (set_attr "mode" "DI")]) 7273 7274(define_expand "umulsi3_highpart" 7275 [(parallel [(set (match_operand:SI 0 "register_operand" "") 7276 (truncate:SI 7277 (lshiftrt:DI 7278 (mult:DI (zero_extend:DI 7279 (match_operand:SI 1 "nonimmediate_operand" "")) 7280 (zero_extend:DI 7281 (match_operand:SI 2 "register_operand" ""))) 7282 (const_int 32)))) 7283 (clobber (match_scratch:SI 3 "")) 7284 (clobber (reg:CC FLAGS_REG))])] 7285 "" 7286 "") 7287 7288(define_insn "*umulsi3_highpart_insn" 7289 [(set (match_operand:SI 0 "register_operand" "=d") 7290 (truncate:SI 7291 (lshiftrt:DI 7292 (mult:DI (zero_extend:DI 7293 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7294 (zero_extend:DI 7295 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7296 (const_int 32)))) 7297 (clobber (match_scratch:SI 3 "=1")) 7298 (clobber (reg:CC FLAGS_REG))] 7299 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 7300 "mul{l}\t%2" 7301 [(set_attr "type" "imul") 7302 (set_attr "length_immediate" "0") 7303 (set (attr "athlon_decode") 7304 (if_then_else (eq_attr "cpu" "athlon") 7305 (const_string "vector") 7306 (const_string "double"))) 7307 (set_attr "amdfam10_decode" "double") 7308 (set_attr "mode" "SI")]) 7309 7310(define_insn "*umulsi3_highpart_zext" 7311 [(set (match_operand:DI 0 "register_operand" "=d") 7312 (zero_extend:DI (truncate:SI 7313 (lshiftrt:DI 7314 (mult:DI (zero_extend:DI 7315 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7316 (zero_extend:DI 7317 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7318 (const_int 32))))) 7319 (clobber (match_scratch:SI 3 "=1")) 7320 (clobber (reg:CC FLAGS_REG))] 7321 "TARGET_64BIT 7322 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7323 "mul{l}\t%2" 7324 [(set_attr "type" "imul") 7325 (set_attr "length_immediate" "0") 7326 (set (attr "athlon_decode") 7327 (if_then_else (eq_attr "cpu" "athlon") 7328 (const_string "vector") 7329 (const_string "double"))) 7330 (set_attr "amdfam10_decode" "double") 7331 (set_attr "mode" "SI")]) 7332 7333(define_expand "smuldi3_highpart" 7334 [(parallel [(set (match_operand:DI 0 "register_operand" "=d") 7335 (truncate:DI 7336 (lshiftrt:TI 7337 (mult:TI (sign_extend:TI 7338 (match_operand:DI 1 "nonimmediate_operand" "")) 7339 (sign_extend:TI 7340 (match_operand:DI 2 "register_operand" ""))) 7341 (const_int 64)))) 7342 (clobber (match_scratch:DI 3 "")) 7343 (clobber (reg:CC FLAGS_REG))])] 7344 "TARGET_64BIT" 7345 "") 7346 7347(define_insn "*smuldi3_highpart_rex64" 7348 [(set (match_operand:DI 0 "register_operand" "=d") 7349 (truncate:DI 7350 (lshiftrt:TI 7351 (mult:TI (sign_extend:TI 7352 (match_operand:DI 1 "nonimmediate_operand" "%a")) 7353 (sign_extend:TI 7354 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7355 (const_int 64)))) 7356 (clobber (match_scratch:DI 3 "=1")) 7357 (clobber (reg:CC FLAGS_REG))] 7358 "TARGET_64BIT 7359 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7360 "imul{q}\t%2" 7361 [(set_attr "type" "imul") 7362 (set (attr "athlon_decode") 7363 (if_then_else (eq_attr "cpu" "athlon") 7364 (const_string "vector") 7365 (const_string "double"))) 7366 (set_attr "amdfam10_decode" "double") 7367 (set_attr "mode" "DI")]) 7368 7369(define_expand "smulsi3_highpart" 7370 [(parallel [(set (match_operand:SI 0 "register_operand" "") 7371 (truncate:SI 7372 (lshiftrt:DI 7373 (mult:DI (sign_extend:DI 7374 (match_operand:SI 1 "nonimmediate_operand" "")) 7375 (sign_extend:DI 7376 (match_operand:SI 2 "register_operand" ""))) 7377 (const_int 32)))) 7378 (clobber (match_scratch:SI 3 "")) 7379 (clobber (reg:CC FLAGS_REG))])] 7380 "" 7381 "") 7382 7383(define_insn "*smulsi3_highpart_insn" 7384 [(set (match_operand:SI 0 "register_operand" "=d") 7385 (truncate:SI 7386 (lshiftrt:DI 7387 (mult:DI (sign_extend:DI 7388 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7389 (sign_extend:DI 7390 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7391 (const_int 32)))) 7392 (clobber (match_scratch:SI 3 "=1")) 7393 (clobber (reg:CC FLAGS_REG))] 7394 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 7395 "imul{l}\t%2" 7396 [(set_attr "type" "imul") 7397 (set (attr "athlon_decode") 7398 (if_then_else (eq_attr "cpu" "athlon") 7399 (const_string "vector") 7400 (const_string "double"))) 7401 (set_attr "amdfam10_decode" "double") 7402 (set_attr "mode" "SI")]) 7403 7404(define_insn "*smulsi3_highpart_zext" 7405 [(set (match_operand:DI 0 "register_operand" "=d") 7406 (zero_extend:DI (truncate:SI 7407 (lshiftrt:DI 7408 (mult:DI (sign_extend:DI 7409 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7410 (sign_extend:DI 7411 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7412 (const_int 32))))) 7413 (clobber (match_scratch:SI 3 "=1")) 7414 (clobber (reg:CC FLAGS_REG))] 7415 "TARGET_64BIT 7416 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7417 "imul{l}\t%2" 7418 [(set_attr "type" "imul") 7419 (set (attr "athlon_decode") 7420 (if_then_else (eq_attr "cpu" "athlon") 7421 (const_string "vector") 7422 (const_string "double"))) 7423 (set_attr "amdfam10_decode" "double") 7424 (set_attr "mode" "SI")]) 7425 7426;; The patterns that match these are at the end of this file. 7427 7428(define_expand "mulxf3" 7429 [(set (match_operand:XF 0 "register_operand" "") 7430 (mult:XF (match_operand:XF 1 "register_operand" "") 7431 (match_operand:XF 2 "register_operand" "")))] 7432 "TARGET_80387" 7433 "") 7434 7435(define_expand "muldf3" 7436 [(set (match_operand:DF 0 "register_operand" "") 7437 (mult:DF (match_operand:DF 1 "register_operand" "") 7438 (match_operand:DF 2 "nonimmediate_operand" "")))] 7439 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 7440 "") 7441 7442(define_expand "mulsf3" 7443 [(set (match_operand:SF 0 "register_operand" "") 7444 (mult:SF (match_operand:SF 1 "register_operand" "") 7445 (match_operand:SF 2 "nonimmediate_operand" "")))] 7446 "TARGET_80387 || TARGET_SSE_MATH" 7447 "") 7448 7449;; Divide instructions 7450 7451(define_insn "divqi3" 7452 [(set (match_operand:QI 0 "register_operand" "=a") 7453 (div:QI (match_operand:HI 1 "register_operand" "0") 7454 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 7455 (clobber (reg:CC FLAGS_REG))] 7456 "TARGET_QIMODE_MATH" 7457 "idiv{b}\t%2" 7458 [(set_attr "type" "idiv") 7459 (set_attr "mode" "QI")]) 7460 7461(define_insn "udivqi3" 7462 [(set (match_operand:QI 0 "register_operand" "=a") 7463 (udiv:QI (match_operand:HI 1 "register_operand" "0") 7464 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 7465 (clobber (reg:CC FLAGS_REG))] 7466 "TARGET_QIMODE_MATH" 7467 "div{b}\t%2" 7468 [(set_attr "type" "idiv") 7469 (set_attr "mode" "QI")]) 7470 7471;; The patterns that match these are at the end of this file. 7472 7473(define_expand "divxf3" 7474 [(set (match_operand:XF 0 "register_operand" "") 7475 (div:XF (match_operand:XF 1 "register_operand" "") 7476 (match_operand:XF 2 "register_operand" "")))] 7477 "TARGET_80387" 7478 "") 7479 7480(define_expand "divdf3" 7481 [(set (match_operand:DF 0 "register_operand" "") 7482 (div:DF (match_operand:DF 1 "register_operand" "") 7483 (match_operand:DF 2 "nonimmediate_operand" "")))] 7484 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 7485 "") 7486 7487(define_expand "divsf3" 7488 [(set (match_operand:SF 0 "register_operand" "") 7489 (div:SF (match_operand:SF 1 "register_operand" "") 7490 (match_operand:SF 2 "nonimmediate_operand" "")))] 7491 "TARGET_80387 || TARGET_SSE_MATH" 7492 "") 7493 7494;; Remainder instructions. 7495 7496(define_expand "divmoddi4" 7497 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7498 (div:DI (match_operand:DI 1 "register_operand" "") 7499 (match_operand:DI 2 "nonimmediate_operand" ""))) 7500 (set (match_operand:DI 3 "register_operand" "") 7501 (mod:DI (match_dup 1) (match_dup 2))) 7502 (clobber (reg:CC FLAGS_REG))])] 7503 "TARGET_64BIT" 7504 "") 7505 7506;; Allow to come the parameter in eax or edx to avoid extra moves. 7507;; Penalize eax case slightly because it results in worse scheduling 7508;; of code. 7509(define_insn "*divmoddi4_nocltd_rex64" 7510 [(set (match_operand:DI 0 "register_operand" "=&a,?a") 7511 (div:DI (match_operand:DI 2 "register_operand" "1,0") 7512 (match_operand:DI 3 "nonimmediate_operand" "rm,rm"))) 7513 (set (match_operand:DI 1 "register_operand" "=&d,&d") 7514 (mod:DI (match_dup 2) (match_dup 3))) 7515 (clobber (reg:CC FLAGS_REG))] 7516 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD" 7517 "#" 7518 [(set_attr "type" "multi")]) 7519 7520(define_insn "*divmoddi4_cltd_rex64" 7521 [(set (match_operand:DI 0 "register_operand" "=a") 7522 (div:DI (match_operand:DI 2 "register_operand" "a") 7523 (match_operand:DI 3 "nonimmediate_operand" "rm"))) 7524 (set (match_operand:DI 1 "register_operand" "=&d") 7525 (mod:DI (match_dup 2) (match_dup 3))) 7526 (clobber (reg:CC FLAGS_REG))] 7527 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)" 7528 "#" 7529 [(set_attr "type" "multi")]) 7530 7531(define_insn "*divmoddi_noext_rex64" 7532 [(set (match_operand:DI 0 "register_operand" "=a") 7533 (div:DI (match_operand:DI 1 "register_operand" "0") 7534 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7535 (set (match_operand:DI 3 "register_operand" "=d") 7536 (mod:DI (match_dup 1) (match_dup 2))) 7537 (use (match_operand:DI 4 "register_operand" "3")) 7538 (clobber (reg:CC FLAGS_REG))] 7539 "TARGET_64BIT" 7540 "idiv{q}\t%2" 7541 [(set_attr "type" "idiv") 7542 (set_attr "mode" "DI")]) 7543 7544(define_split 7545 [(set (match_operand:DI 0 "register_operand" "") 7546 (div:DI (match_operand:DI 1 "register_operand" "") 7547 (match_operand:DI 2 "nonimmediate_operand" ""))) 7548 (set (match_operand:DI 3 "register_operand" "") 7549 (mod:DI (match_dup 1) (match_dup 2))) 7550 (clobber (reg:CC FLAGS_REG))] 7551 "TARGET_64BIT && reload_completed" 7552 [(parallel [(set (match_dup 3) 7553 (ashiftrt:DI (match_dup 4) (const_int 63))) 7554 (clobber (reg:CC FLAGS_REG))]) 7555 (parallel [(set (match_dup 0) 7556 (div:DI (reg:DI 0) (match_dup 2))) 7557 (set (match_dup 3) 7558 (mod:DI (reg:DI 0) (match_dup 2))) 7559 (use (match_dup 3)) 7560 (clobber (reg:CC FLAGS_REG))])] 7561{ 7562 /* Avoid use of cltd in favor of a mov+shift. */ 7563 if (!TARGET_USE_CLTD && !optimize_size) 7564 { 7565 if (true_regnum (operands[1])) 7566 emit_move_insn (operands[0], operands[1]); 7567 else 7568 emit_move_insn (operands[3], operands[1]); 7569 operands[4] = operands[3]; 7570 } 7571 else 7572 { 7573 gcc_assert (!true_regnum (operands[1])); 7574 operands[4] = operands[1]; 7575 } 7576}) 7577 7578 7579(define_expand "divmodsi4" 7580 [(parallel [(set (match_operand:SI 0 "register_operand" "") 7581 (div:SI (match_operand:SI 1 "register_operand" "") 7582 (match_operand:SI 2 "nonimmediate_operand" ""))) 7583 (set (match_operand:SI 3 "register_operand" "") 7584 (mod:SI (match_dup 1) (match_dup 2))) 7585 (clobber (reg:CC FLAGS_REG))])] 7586 "" 7587 "") 7588 7589;; Allow to come the parameter in eax or edx to avoid extra moves. 7590;; Penalize eax case slightly because it results in worse scheduling 7591;; of code. 7592(define_insn "*divmodsi4_nocltd" 7593 [(set (match_operand:SI 0 "register_operand" "=&a,?a") 7594 (div:SI (match_operand:SI 2 "register_operand" "1,0") 7595 (match_operand:SI 3 "nonimmediate_operand" "rm,rm"))) 7596 (set (match_operand:SI 1 "register_operand" "=&d,&d") 7597 (mod:SI (match_dup 2) (match_dup 3))) 7598 (clobber (reg:CC FLAGS_REG))] 7599 "!optimize_size && !TARGET_USE_CLTD" 7600 "#" 7601 [(set_attr "type" "multi")]) 7602 7603(define_insn "*divmodsi4_cltd" 7604 [(set (match_operand:SI 0 "register_operand" "=a") 7605 (div:SI (match_operand:SI 2 "register_operand" "a") 7606 (match_operand:SI 3 "nonimmediate_operand" "rm"))) 7607 (set (match_operand:SI 1 "register_operand" "=&d") 7608 (mod:SI (match_dup 2) (match_dup 3))) 7609 (clobber (reg:CC FLAGS_REG))] 7610 "optimize_size || TARGET_USE_CLTD" 7611 "#" 7612 [(set_attr "type" "multi")]) 7613 7614(define_insn "*divmodsi_noext" 7615 [(set (match_operand:SI 0 "register_operand" "=a") 7616 (div:SI (match_operand:SI 1 "register_operand" "0") 7617 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7618 (set (match_operand:SI 3 "register_operand" "=d") 7619 (mod:SI (match_dup 1) (match_dup 2))) 7620 (use (match_operand:SI 4 "register_operand" "3")) 7621 (clobber (reg:CC FLAGS_REG))] 7622 "" 7623 "idiv{l}\t%2" 7624 [(set_attr "type" "idiv") 7625 (set_attr "mode" "SI")]) 7626 7627(define_split 7628 [(set (match_operand:SI 0 "register_operand" "") 7629 (div:SI (match_operand:SI 1 "register_operand" "") 7630 (match_operand:SI 2 "nonimmediate_operand" ""))) 7631 (set (match_operand:SI 3 "register_operand" "") 7632 (mod:SI (match_dup 1) (match_dup 2))) 7633 (clobber (reg:CC FLAGS_REG))] 7634 "reload_completed" 7635 [(parallel [(set (match_dup 3) 7636 (ashiftrt:SI (match_dup 4) (const_int 31))) 7637 (clobber (reg:CC FLAGS_REG))]) 7638 (parallel [(set (match_dup 0) 7639 (div:SI (reg:SI 0) (match_dup 2))) 7640 (set (match_dup 3) 7641 (mod:SI (reg:SI 0) (match_dup 2))) 7642 (use (match_dup 3)) 7643 (clobber (reg:CC FLAGS_REG))])] 7644{ 7645 /* Avoid use of cltd in favor of a mov+shift. */ 7646 if (!TARGET_USE_CLTD && !optimize_size) 7647 { 7648 if (true_regnum (operands[1])) 7649 emit_move_insn (operands[0], operands[1]); 7650 else 7651 emit_move_insn (operands[3], operands[1]); 7652 operands[4] = operands[3]; 7653 } 7654 else 7655 { 7656 gcc_assert (!true_regnum (operands[1])); 7657 operands[4] = operands[1]; 7658 } 7659}) 7660;; %%% Split me. 7661(define_insn "divmodhi4" 7662 [(set (match_operand:HI 0 "register_operand" "=a") 7663 (div:HI (match_operand:HI 1 "register_operand" "0") 7664 (match_operand:HI 2 "nonimmediate_operand" "rm"))) 7665 (set (match_operand:HI 3 "register_operand" "=&d") 7666 (mod:HI (match_dup 1) (match_dup 2))) 7667 (clobber (reg:CC FLAGS_REG))] 7668 "TARGET_HIMODE_MATH" 7669 "cwtd\;idiv{w}\t%2" 7670 [(set_attr "type" "multi") 7671 (set_attr "length_immediate" "0") 7672 (set_attr "mode" "SI")]) 7673 7674(define_insn "udivmoddi4" 7675 [(set (match_operand:DI 0 "register_operand" "=a") 7676 (udiv:DI (match_operand:DI 1 "register_operand" "0") 7677 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7678 (set (match_operand:DI 3 "register_operand" "=&d") 7679 (umod:DI (match_dup 1) (match_dup 2))) 7680 (clobber (reg:CC FLAGS_REG))] 7681 "TARGET_64BIT" 7682 "xor{q}\t%3, %3\;div{q}\t%2" 7683 [(set_attr "type" "multi") 7684 (set_attr "length_immediate" "0") 7685 (set_attr "mode" "DI")]) 7686 7687(define_insn "*udivmoddi4_noext" 7688 [(set (match_operand:DI 0 "register_operand" "=a") 7689 (udiv:DI (match_operand:DI 1 "register_operand" "0") 7690 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7691 (set (match_operand:DI 3 "register_operand" "=d") 7692 (umod:DI (match_dup 1) (match_dup 2))) 7693 (use (match_dup 3)) 7694 (clobber (reg:CC FLAGS_REG))] 7695 "TARGET_64BIT" 7696 "div{q}\t%2" 7697 [(set_attr "type" "idiv") 7698 (set_attr "mode" "DI")]) 7699 7700(define_split 7701 [(set (match_operand:DI 0 "register_operand" "") 7702 (udiv:DI (match_operand:DI 1 "register_operand" "") 7703 (match_operand:DI 2 "nonimmediate_operand" ""))) 7704 (set (match_operand:DI 3 "register_operand" "") 7705 (umod:DI (match_dup 1) (match_dup 2))) 7706 (clobber (reg:CC FLAGS_REG))] 7707 "TARGET_64BIT && reload_completed" 7708 [(set (match_dup 3) (const_int 0)) 7709 (parallel [(set (match_dup 0) 7710 (udiv:DI (match_dup 1) (match_dup 2))) 7711 (set (match_dup 3) 7712 (umod:DI (match_dup 1) (match_dup 2))) 7713 (use (match_dup 3)) 7714 (clobber (reg:CC FLAGS_REG))])] 7715 "") 7716 7717(define_insn "udivmodsi4" 7718 [(set (match_operand:SI 0 "register_operand" "=a") 7719 (udiv:SI (match_operand:SI 1 "register_operand" "0") 7720 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7721 (set (match_operand:SI 3 "register_operand" "=&d") 7722 (umod:SI (match_dup 1) (match_dup 2))) 7723 (clobber (reg:CC FLAGS_REG))] 7724 "" 7725 "xor{l}\t%3, %3\;div{l}\t%2" 7726 [(set_attr "type" "multi") 7727 (set_attr "length_immediate" "0") 7728 (set_attr "mode" "SI")]) 7729 7730(define_insn "*udivmodsi4_noext" 7731 [(set (match_operand:SI 0 "register_operand" "=a") 7732 (udiv:SI (match_operand:SI 1 "register_operand" "0") 7733 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7734 (set (match_operand:SI 3 "register_operand" "=d") 7735 (umod:SI (match_dup 1) (match_dup 2))) 7736 (use (match_dup 3)) 7737 (clobber (reg:CC FLAGS_REG))] 7738 "" 7739 "div{l}\t%2" 7740 [(set_attr "type" "idiv") 7741 (set_attr "mode" "SI")]) 7742 7743(define_split 7744 [(set (match_operand:SI 0 "register_operand" "") 7745 (udiv:SI (match_operand:SI 1 "register_operand" "") 7746 (match_operand:SI 2 "nonimmediate_operand" ""))) 7747 (set (match_operand:SI 3 "register_operand" "") 7748 (umod:SI (match_dup 1) (match_dup 2))) 7749 (clobber (reg:CC FLAGS_REG))] 7750 "reload_completed" 7751 [(set (match_dup 3) (const_int 0)) 7752 (parallel [(set (match_dup 0) 7753 (udiv:SI (match_dup 1) (match_dup 2))) 7754 (set (match_dup 3) 7755 (umod:SI (match_dup 1) (match_dup 2))) 7756 (use (match_dup 3)) 7757 (clobber (reg:CC FLAGS_REG))])] 7758 "") 7759 7760(define_expand "udivmodhi4" 7761 [(set (match_dup 4) (const_int 0)) 7762 (parallel [(set (match_operand:HI 0 "register_operand" "") 7763 (udiv:HI (match_operand:HI 1 "register_operand" "") 7764 (match_operand:HI 2 "nonimmediate_operand" ""))) 7765 (set (match_operand:HI 3 "register_operand" "") 7766 (umod:HI (match_dup 1) (match_dup 2))) 7767 (use (match_dup 4)) 7768 (clobber (reg:CC FLAGS_REG))])] 7769 "TARGET_HIMODE_MATH" 7770 "operands[4] = gen_reg_rtx (HImode);") 7771 7772(define_insn "*udivmodhi_noext" 7773 [(set (match_operand:HI 0 "register_operand" "=a") 7774 (udiv:HI (match_operand:HI 1 "register_operand" "0") 7775 (match_operand:HI 2 "nonimmediate_operand" "rm"))) 7776 (set (match_operand:HI 3 "register_operand" "=d") 7777 (umod:HI (match_dup 1) (match_dup 2))) 7778 (use (match_operand:HI 4 "register_operand" "3")) 7779 (clobber (reg:CC FLAGS_REG))] 7780 "" 7781 "div{w}\t%2" 7782 [(set_attr "type" "idiv") 7783 (set_attr "mode" "HI")]) 7784 7785;; We cannot use div/idiv for double division, because it causes 7786;; "division by zero" on the overflow and that's not what we expect 7787;; from truncate. Because true (non truncating) double division is 7788;; never generated, we can't create this insn anyway. 7789; 7790;(define_insn "" 7791; [(set (match_operand:SI 0 "register_operand" "=a") 7792; (truncate:SI 7793; (udiv:DI (match_operand:DI 1 "register_operand" "A") 7794; (zero_extend:DI 7795; (match_operand:SI 2 "nonimmediate_operand" "rm"))))) 7796; (set (match_operand:SI 3 "register_operand" "=d") 7797; (truncate:SI 7798; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2))))) 7799; (clobber (reg:CC FLAGS_REG))] 7800; "" 7801; "div{l}\t{%2, %0|%0, %2}" 7802; [(set_attr "type" "idiv")]) 7803 7804;;- Logical AND instructions 7805 7806;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al. 7807;; Note that this excludes ah. 7808 7809(define_insn "*testdi_1_rex64" 7810 [(set (reg FLAGS_REG) 7811 (compare 7812 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm") 7813 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re")) 7814 (const_int 0)))] 7815 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7816 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7817 "@ 7818 test{l}\t{%k1, %k0|%k0, %k1} 7819 test{l}\t{%k1, %k0|%k0, %k1} 7820 test{q}\t{%1, %0|%0, %1} 7821 test{q}\t{%1, %0|%0, %1} 7822 test{q}\t{%1, %0|%0, %1}" 7823 [(set_attr "type" "test") 7824 (set_attr "modrm" "0,1,0,1,1") 7825 (set_attr "mode" "SI,SI,DI,DI,DI") 7826 (set_attr "pent_pair" "uv,np,uv,np,uv")]) 7827 7828(define_insn "testsi_1" 7829 [(set (reg FLAGS_REG) 7830 (compare 7831 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm") 7832 (match_operand:SI 1 "general_operand" "in,in,rin")) 7833 (const_int 0)))] 7834 "ix86_match_ccmode (insn, CCNOmode) 7835 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7836 "test{l}\t{%1, %0|%0, %1}" 7837 [(set_attr "type" "test") 7838 (set_attr "modrm" "0,1,1") 7839 (set_attr "mode" "SI") 7840 (set_attr "pent_pair" "uv,np,uv")]) 7841 7842(define_expand "testsi_ccno_1" 7843 [(set (reg:CCNO FLAGS_REG) 7844 (compare:CCNO 7845 (and:SI (match_operand:SI 0 "nonimmediate_operand" "") 7846 (match_operand:SI 1 "nonmemory_operand" "")) 7847 (const_int 0)))] 7848 "" 7849 "") 7850 7851(define_insn "*testhi_1" 7852 [(set (reg FLAGS_REG) 7853 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm") 7854 (match_operand:HI 1 "general_operand" "n,n,rn")) 7855 (const_int 0)))] 7856 "ix86_match_ccmode (insn, CCNOmode) 7857 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7858 "test{w}\t{%1, %0|%0, %1}" 7859 [(set_attr "type" "test") 7860 (set_attr "modrm" "0,1,1") 7861 (set_attr "mode" "HI") 7862 (set_attr "pent_pair" "uv,np,uv")]) 7863 7864(define_expand "testqi_ccz_1" 7865 [(set (reg:CCZ FLAGS_REG) 7866 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "") 7867 (match_operand:QI 1 "nonmemory_operand" "")) 7868 (const_int 0)))] 7869 "" 7870 "") 7871 7872(define_insn "*testqi_1_maybe_si" 7873 [(set (reg FLAGS_REG) 7874 (compare 7875 (and:QI 7876 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r") 7877 (match_operand:QI 1 "general_operand" "n,n,qn,n")) 7878 (const_int 0)))] 7879 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 7880 && ix86_match_ccmode (insn, 7881 GET_CODE (operands[1]) == CONST_INT 7882 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)" 7883{ 7884 if (which_alternative == 3) 7885 { 7886 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0) 7887 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); 7888 return "test{l}\t{%1, %k0|%k0, %1}"; 7889 } 7890 return "test{b}\t{%1, %0|%0, %1}"; 7891} 7892 [(set_attr "type" "test") 7893 (set_attr "modrm" "0,1,1,1") 7894 (set_attr "mode" "QI,QI,QI,SI") 7895 (set_attr "pent_pair" "uv,np,uv,np")]) 7896 7897(define_insn "*testqi_1" 7898 [(set (reg FLAGS_REG) 7899 (compare 7900 (and:QI 7901 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm") 7902 (match_operand:QI 1 "general_operand" "n,n,qn")) 7903 (const_int 0)))] 7904 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 7905 && ix86_match_ccmode (insn, CCNOmode)" 7906 "test{b}\t{%1, %0|%0, %1}" 7907 [(set_attr "type" "test") 7908 (set_attr "modrm" "0,1,1") 7909 (set_attr "mode" "QI") 7910 (set_attr "pent_pair" "uv,np,uv")]) 7911 7912(define_expand "testqi_ext_ccno_0" 7913 [(set (reg:CCNO FLAGS_REG) 7914 (compare:CCNO 7915 (and:SI 7916 (zero_extract:SI 7917 (match_operand 0 "ext_register_operand" "") 7918 (const_int 8) 7919 (const_int 8)) 7920 (match_operand 1 "const_int_operand" "")) 7921 (const_int 0)))] 7922 "" 7923 "") 7924 7925(define_insn "*testqi_ext_0" 7926 [(set (reg FLAGS_REG) 7927 (compare 7928 (and:SI 7929 (zero_extract:SI 7930 (match_operand 0 "ext_register_operand" "Q") 7931 (const_int 8) 7932 (const_int 8)) 7933 (match_operand 1 "const_int_operand" "n")) 7934 (const_int 0)))] 7935 "ix86_match_ccmode (insn, CCNOmode)" 7936 "test{b}\t{%1, %h0|%h0, %1}" 7937 [(set_attr "type" "test") 7938 (set_attr "mode" "QI") 7939 (set_attr "length_immediate" "1") 7940 (set_attr "pent_pair" "np")]) 7941 7942(define_insn "*testqi_ext_1" 7943 [(set (reg FLAGS_REG) 7944 (compare 7945 (and:SI 7946 (zero_extract:SI 7947 (match_operand 0 "ext_register_operand" "Q") 7948 (const_int 8) 7949 (const_int 8)) 7950 (zero_extend:SI 7951 (match_operand:QI 1 "general_operand" "Qm"))) 7952 (const_int 0)))] 7953 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7954 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7955 "test{b}\t{%1, %h0|%h0, %1}" 7956 [(set_attr "type" "test") 7957 (set_attr "mode" "QI")]) 7958 7959(define_insn "*testqi_ext_1_rex64" 7960 [(set (reg FLAGS_REG) 7961 (compare 7962 (and:SI 7963 (zero_extract:SI 7964 (match_operand 0 "ext_register_operand" "Q") 7965 (const_int 8) 7966 (const_int 8)) 7967 (zero_extend:SI 7968 (match_operand:QI 1 "register_operand" "Q"))) 7969 (const_int 0)))] 7970 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 7971 "test{b}\t{%1, %h0|%h0, %1}" 7972 [(set_attr "type" "test") 7973 (set_attr "mode" "QI")]) 7974 7975(define_insn "*testqi_ext_2" 7976 [(set (reg FLAGS_REG) 7977 (compare 7978 (and:SI 7979 (zero_extract:SI 7980 (match_operand 0 "ext_register_operand" "Q") 7981 (const_int 8) 7982 (const_int 8)) 7983 (zero_extract:SI 7984 (match_operand 1 "ext_register_operand" "Q") 7985 (const_int 8) 7986 (const_int 8))) 7987 (const_int 0)))] 7988 "ix86_match_ccmode (insn, CCNOmode)" 7989 "test{b}\t{%h1, %h0|%h0, %h1}" 7990 [(set_attr "type" "test") 7991 (set_attr "mode" "QI")]) 7992 7993;; Combine likes to form bit extractions for some tests. Humor it. 7994(define_insn "*testqi_ext_3" 7995 [(set (reg FLAGS_REG) 7996 (compare (zero_extract:SI 7997 (match_operand 0 "nonimmediate_operand" "rm") 7998 (match_operand:SI 1 "const_int_operand" "") 7999 (match_operand:SI 2 "const_int_operand" "")) 8000 (const_int 0)))] 8001 "ix86_match_ccmode (insn, CCNOmode) 8002 && INTVAL (operands[1]) > 0 8003 && INTVAL (operands[2]) >= 0 8004 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 8005 && (GET_MODE (operands[0]) == SImode 8006 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode) 8007 || GET_MODE (operands[0]) == HImode 8008 || GET_MODE (operands[0]) == QImode)" 8009 "#") 8010 8011(define_insn "*testqi_ext_3_rex64" 8012 [(set (reg FLAGS_REG) 8013 (compare (zero_extract:DI 8014 (match_operand 0 "nonimmediate_operand" "rm") 8015 (match_operand:DI 1 "const_int_operand" "") 8016 (match_operand:DI 2 "const_int_operand" "")) 8017 (const_int 0)))] 8018 "TARGET_64BIT 8019 && ix86_match_ccmode (insn, CCNOmode) 8020 && INTVAL (operands[1]) > 0 8021 && INTVAL (operands[2]) >= 0 8022 /* Ensure that resulting mask is zero or sign extended operand. */ 8023 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 8024 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64 8025 && INTVAL (operands[1]) > 32)) 8026 && (GET_MODE (operands[0]) == SImode 8027 || GET_MODE (operands[0]) == DImode 8028 || GET_MODE (operands[0]) == HImode 8029 || GET_MODE (operands[0]) == QImode)" 8030 "#") 8031 8032(define_split 8033 [(set (match_operand 0 "flags_reg_operand" "") 8034 (match_operator 1 "compare_operator" 8035 [(zero_extract 8036 (match_operand 2 "nonimmediate_operand" "") 8037 (match_operand 3 "const_int_operand" "") 8038 (match_operand 4 "const_int_operand" "")) 8039 (const_int 0)]))] 8040 "ix86_match_ccmode (insn, CCNOmode)" 8041 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))] 8042{ 8043 rtx val = operands[2]; 8044 HOST_WIDE_INT len = INTVAL (operands[3]); 8045 HOST_WIDE_INT pos = INTVAL (operands[4]); 8046 HOST_WIDE_INT mask; 8047 enum machine_mode mode, submode; 8048 8049 mode = GET_MODE (val); 8050 if (GET_CODE (val) == MEM) 8051 { 8052 /* ??? Combine likes to put non-volatile mem extractions in QImode 8053 no matter the size of the test. So find a mode that works. */ 8054 if (! MEM_VOLATILE_P (val)) 8055 { 8056 mode = smallest_mode_for_size (pos + len, MODE_INT); 8057 val = adjust_address (val, mode, 0); 8058 } 8059 } 8060 else if (GET_CODE (val) == SUBREG 8061 && (submode = GET_MODE (SUBREG_REG (val)), 8062 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)) 8063 && pos + len <= GET_MODE_BITSIZE (submode)) 8064 { 8065 /* Narrow a paradoxical subreg to prevent partial register stalls. */ 8066 mode = submode; 8067 val = SUBREG_REG (val); 8068 } 8069 else if (mode == HImode && pos + len <= 8) 8070 { 8071 /* Small HImode tests can be converted to QImode. */ 8072 mode = QImode; 8073 val = gen_lowpart (QImode, val); 8074 } 8075 8076 if (len == HOST_BITS_PER_WIDE_INT) 8077 mask = -1; 8078 else 8079 mask = ((HOST_WIDE_INT)1 << len) - 1; 8080 mask <<= pos; 8081 8082 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode)); 8083}) 8084 8085;; Convert HImode/SImode test instructions with immediate to QImode ones. 8086;; i386 does not allow to encode test with 8bit sign extended immediate, so 8087;; this is relatively important trick. 8088;; Do the conversion only post-reload to avoid limiting of the register class 8089;; to QI regs. 8090(define_split 8091 [(set (match_operand 0 "flags_reg_operand" "") 8092 (match_operator 1 "compare_operator" 8093 [(and (match_operand 2 "register_operand" "") 8094 (match_operand 3 "const_int_operand" "")) 8095 (const_int 0)]))] 8096 "reload_completed 8097 && QI_REG_P (operands[2]) 8098 && GET_MODE (operands[2]) != QImode 8099 && ((ix86_match_ccmode (insn, CCZmode) 8100 && !(INTVAL (operands[3]) & ~(255 << 8))) 8101 || (ix86_match_ccmode (insn, CCNOmode) 8102 && !(INTVAL (operands[3]) & ~(127 << 8))))" 8103 [(set (match_dup 0) 8104 (match_op_dup 1 8105 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8)) 8106 (match_dup 3)) 8107 (const_int 0)]))] 8108 "operands[2] = gen_lowpart (SImode, operands[2]); 8109 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);") 8110 8111(define_split 8112 [(set (match_operand 0 "flags_reg_operand" "") 8113 (match_operator 1 "compare_operator" 8114 [(and (match_operand 2 "nonimmediate_operand" "") 8115 (match_operand 3 "const_int_operand" "")) 8116 (const_int 0)]))] 8117 "reload_completed 8118 && GET_MODE (operands[2]) != QImode 8119 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2])) 8120 && ((ix86_match_ccmode (insn, CCZmode) 8121 && !(INTVAL (operands[3]) & ~255)) 8122 || (ix86_match_ccmode (insn, CCNOmode) 8123 && !(INTVAL (operands[3]) & ~127)))" 8124 [(set (match_dup 0) 8125 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 8126 (const_int 0)]))] 8127 "operands[2] = gen_lowpart (QImode, operands[2]); 8128 operands[3] = gen_lowpart (QImode, operands[3]);") 8129 8130 8131;; %%% This used to optimize known byte-wide and operations to memory, 8132;; and sometimes to QImode registers. If this is considered useful, 8133;; it should be done with splitters. 8134 8135(define_expand "anddi3" 8136 [(set (match_operand:DI 0 "nonimmediate_operand" "") 8137 (and:DI (match_operand:DI 1 "nonimmediate_operand" "") 8138 (match_operand:DI 2 "x86_64_szext_general_operand" ""))) 8139 (clobber (reg:CC FLAGS_REG))] 8140 "TARGET_64BIT" 8141 "ix86_expand_binary_operator (AND, DImode, operands); DONE;") 8142 8143(define_insn "*anddi_1_rex64" 8144 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r") 8145 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm") 8146 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L"))) 8147 (clobber (reg:CC FLAGS_REG))] 8148 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)" 8149{ 8150 switch (get_attr_type (insn)) 8151 { 8152 case TYPE_IMOVX: 8153 { 8154 enum machine_mode mode; 8155 8156 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 8157 if (INTVAL (operands[2]) == 0xff) 8158 mode = QImode; 8159 else 8160 { 8161 gcc_assert (INTVAL (operands[2]) == 0xffff); 8162 mode = HImode; 8163 } 8164 8165 operands[1] = gen_lowpart (mode, operands[1]); 8166 if (mode == QImode) 8167 return "movz{bq|x}\t{%1,%0|%0, %1}"; 8168 else 8169 return "movz{wq|x}\t{%1,%0|%0, %1}"; 8170 } 8171 8172 default: 8173 gcc_assert (rtx_equal_p (operands[0], operands[1])); 8174 if (get_attr_mode (insn) == MODE_SI) 8175 return "and{l}\t{%k2, %k0|%k0, %k2}"; 8176 else 8177 return "and{q}\t{%2, %0|%0, %2}"; 8178 } 8179} 8180 [(set_attr "type" "alu,alu,alu,imovx") 8181 (set_attr "length_immediate" "*,*,*,0") 8182 (set_attr "mode" "SI,DI,DI,DI")]) 8183 8184(define_insn "*anddi_2" 8185 [(set (reg FLAGS_REG) 8186 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") 8187 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re")) 8188 (const_int 0))) 8189 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm") 8190 (and:DI (match_dup 1) (match_dup 2)))] 8191 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8192 && ix86_binary_operator_ok (AND, DImode, operands)" 8193 "@ 8194 and{l}\t{%k2, %k0|%k0, %k2} 8195 and{q}\t{%2, %0|%0, %2} 8196 and{q}\t{%2, %0|%0, %2}" 8197 [(set_attr "type" "alu") 8198 (set_attr "mode" "SI,DI,DI")]) 8199 8200(define_expand "andsi3" 8201 [(set (match_operand:SI 0 "nonimmediate_operand" "") 8202 (and:SI (match_operand:SI 1 "nonimmediate_operand" "") 8203 (match_operand:SI 2 "general_operand" ""))) 8204 (clobber (reg:CC FLAGS_REG))] 8205 "" 8206 "ix86_expand_binary_operator (AND, SImode, operands); DONE;") 8207 8208(define_insn "*andsi_1" 8209 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r") 8210 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm") 8211 (match_operand:SI 2 "general_operand" "ri,rm,L"))) 8212 (clobber (reg:CC FLAGS_REG))] 8213 "ix86_binary_operator_ok (AND, SImode, operands)" 8214{ 8215 switch (get_attr_type (insn)) 8216 { 8217 case TYPE_IMOVX: 8218 { 8219 enum machine_mode mode; 8220 8221 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 8222 if (INTVAL (operands[2]) == 0xff) 8223 mode = QImode; 8224 else 8225 { 8226 gcc_assert (INTVAL (operands[2]) == 0xffff); 8227 mode = HImode; 8228 } 8229 8230 operands[1] = gen_lowpart (mode, operands[1]); 8231 if (mode == QImode) 8232 return "movz{bl|x}\t{%1,%0|%0, %1}"; 8233 else 8234 return "movz{wl|x}\t{%1,%0|%0, %1}"; 8235 } 8236 8237 default: 8238 gcc_assert (rtx_equal_p (operands[0], operands[1])); 8239 return "and{l}\t{%2, %0|%0, %2}"; 8240 } 8241} 8242 [(set_attr "type" "alu,alu,imovx") 8243 (set_attr "length_immediate" "*,*,0") 8244 (set_attr "mode" "SI")]) 8245 8246(define_split 8247 [(set (match_operand 0 "register_operand" "") 8248 (and (match_dup 0) 8249 (const_int -65536))) 8250 (clobber (reg:CC FLAGS_REG))] 8251 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)" 8252 [(set (strict_low_part (match_dup 1)) (const_int 0))] 8253 "operands[1] = gen_lowpart (HImode, operands[0]);") 8254 8255(define_split 8256 [(set (match_operand 0 "ext_register_operand" "") 8257 (and (match_dup 0) 8258 (const_int -256))) 8259 (clobber (reg:CC FLAGS_REG))] 8260 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed" 8261 [(set (strict_low_part (match_dup 1)) (const_int 0))] 8262 "operands[1] = gen_lowpart (QImode, operands[0]);") 8263 8264(define_split 8265 [(set (match_operand 0 "ext_register_operand" "") 8266 (and (match_dup 0) 8267 (const_int -65281))) 8268 (clobber (reg:CC FLAGS_REG))] 8269 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed" 8270 [(parallel [(set (zero_extract:SI (match_dup 0) 8271 (const_int 8) 8272 (const_int 8)) 8273 (xor:SI 8274 (zero_extract:SI (match_dup 0) 8275 (const_int 8) 8276 (const_int 8)) 8277 (zero_extract:SI (match_dup 0) 8278 (const_int 8) 8279 (const_int 8)))) 8280 (clobber (reg:CC FLAGS_REG))])] 8281 "operands[0] = gen_lowpart (SImode, operands[0]);") 8282 8283;; See comment for addsi_1_zext why we do use nonimmediate_operand 8284(define_insn "*andsi_1_zext" 8285 [(set (match_operand:DI 0 "register_operand" "=r") 8286 (zero_extend:DI 8287 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8288 (match_operand:SI 2 "general_operand" "rim")))) 8289 (clobber (reg:CC FLAGS_REG))] 8290 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" 8291 "and{l}\t{%2, %k0|%k0, %2}" 8292 [(set_attr "type" "alu") 8293 (set_attr "mode" "SI")]) 8294 8295(define_insn "*andsi_2" 8296 [(set (reg FLAGS_REG) 8297 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8298 (match_operand:SI 2 "general_operand" "rim,ri")) 8299 (const_int 0))) 8300 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 8301 (and:SI (match_dup 1) (match_dup 2)))] 8302 "ix86_match_ccmode (insn, CCNOmode) 8303 && ix86_binary_operator_ok (AND, SImode, operands)" 8304 "and{l}\t{%2, %0|%0, %2}" 8305 [(set_attr "type" "alu") 8306 (set_attr "mode" "SI")]) 8307 8308;; See comment for addsi_1_zext why we do use nonimmediate_operand 8309(define_insn "*andsi_2_zext" 8310 [(set (reg FLAGS_REG) 8311 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8312 (match_operand:SI 2 "general_operand" "rim")) 8313 (const_int 0))) 8314 (set (match_operand:DI 0 "register_operand" "=r") 8315 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] 8316 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8317 && ix86_binary_operator_ok (AND, SImode, operands)" 8318 "and{l}\t{%2, %k0|%k0, %2}" 8319 [(set_attr "type" "alu") 8320 (set_attr "mode" "SI")]) 8321 8322(define_expand "andhi3" 8323 [(set (match_operand:HI 0 "nonimmediate_operand" "") 8324 (and:HI (match_operand:HI 1 "nonimmediate_operand" "") 8325 (match_operand:HI 2 "general_operand" ""))) 8326 (clobber (reg:CC FLAGS_REG))] 8327 "TARGET_HIMODE_MATH" 8328 "ix86_expand_binary_operator (AND, HImode, operands); DONE;") 8329 8330(define_insn "*andhi_1" 8331 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") 8332 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm") 8333 (match_operand:HI 2 "general_operand" "ri,rm,L"))) 8334 (clobber (reg:CC FLAGS_REG))] 8335 "ix86_binary_operator_ok (AND, HImode, operands)" 8336{ 8337 switch (get_attr_type (insn)) 8338 { 8339 case TYPE_IMOVX: 8340 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 8341 gcc_assert (INTVAL (operands[2]) == 0xff); 8342 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}"; 8343 8344 default: 8345 gcc_assert (rtx_equal_p (operands[0], operands[1])); 8346 8347 return "and{w}\t{%2, %0|%0, %2}"; 8348 } 8349} 8350 [(set_attr "type" "alu,alu,imovx") 8351 (set_attr "length_immediate" "*,*,0") 8352 (set_attr "mode" "HI,HI,SI")]) 8353 8354(define_insn "*andhi_2" 8355 [(set (reg FLAGS_REG) 8356 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 8357 (match_operand:HI 2 "general_operand" "rim,ri")) 8358 (const_int 0))) 8359 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 8360 (and:HI (match_dup 1) (match_dup 2)))] 8361 "ix86_match_ccmode (insn, CCNOmode) 8362 && ix86_binary_operator_ok (AND, HImode, operands)" 8363 "and{w}\t{%2, %0|%0, %2}" 8364 [(set_attr "type" "alu") 8365 (set_attr "mode" "HI")]) 8366 8367(define_expand "andqi3" 8368 [(set (match_operand:QI 0 "nonimmediate_operand" "") 8369 (and:QI (match_operand:QI 1 "nonimmediate_operand" "") 8370 (match_operand:QI 2 "general_operand" ""))) 8371 (clobber (reg:CC FLAGS_REG))] 8372 "TARGET_QIMODE_MATH" 8373 "ix86_expand_binary_operator (AND, QImode, operands); DONE;") 8374 8375;; %%% Potential partial reg stall on alternative 2. What to do? 8376(define_insn "*andqi_1" 8377 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 8378 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8379 (match_operand:QI 2 "general_operand" "qi,qmi,ri"))) 8380 (clobber (reg:CC FLAGS_REG))] 8381 "ix86_binary_operator_ok (AND, QImode, operands)" 8382 "@ 8383 and{b}\t{%2, %0|%0, %2} 8384 and{b}\t{%2, %0|%0, %2} 8385 and{l}\t{%k2, %k0|%k0, %k2}" 8386 [(set_attr "type" "alu") 8387 (set_attr "mode" "QI,QI,SI")]) 8388 8389(define_insn "*andqi_1_slp" 8390 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 8391 (and:QI (match_dup 0) 8392 (match_operand:QI 1 "general_operand" "qi,qmi"))) 8393 (clobber (reg:CC FLAGS_REG))] 8394 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8395 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8396 "and{b}\t{%1, %0|%0, %1}" 8397 [(set_attr "type" "alu1") 8398 (set_attr "mode" "QI")]) 8399 8400(define_insn "*andqi_2_maybe_si" 8401 [(set (reg FLAGS_REG) 8402 (compare (and:QI 8403 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8404 (match_operand:QI 2 "general_operand" "qim,qi,i")) 8405 (const_int 0))) 8406 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r") 8407 (and:QI (match_dup 1) (match_dup 2)))] 8408 "ix86_binary_operator_ok (AND, QImode, operands) 8409 && ix86_match_ccmode (insn, 8410 GET_CODE (operands[2]) == CONST_INT 8411 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)" 8412{ 8413 if (which_alternative == 2) 8414 { 8415 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) 8416 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); 8417 return "and{l}\t{%2, %k0|%k0, %2}"; 8418 } 8419 return "and{b}\t{%2, %0|%0, %2}"; 8420} 8421 [(set_attr "type" "alu") 8422 (set_attr "mode" "QI,QI,SI")]) 8423 8424(define_insn "*andqi_2" 8425 [(set (reg FLAGS_REG) 8426 (compare (and:QI 8427 (match_operand:QI 1 "nonimmediate_operand" "%0,0") 8428 (match_operand:QI 2 "general_operand" "qim,qi")) 8429 (const_int 0))) 8430 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 8431 (and:QI (match_dup 1) (match_dup 2)))] 8432 "ix86_match_ccmode (insn, CCNOmode) 8433 && ix86_binary_operator_ok (AND, QImode, operands)" 8434 "and{b}\t{%2, %0|%0, %2}" 8435 [(set_attr "type" "alu") 8436 (set_attr "mode" "QI")]) 8437 8438(define_insn "*andqi_2_slp" 8439 [(set (reg FLAGS_REG) 8440 (compare (and:QI 8441 (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 8442 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi")) 8443 (const_int 0))) 8444 (set (strict_low_part (match_dup 0)) 8445 (and:QI (match_dup 0) (match_dup 1)))] 8446 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8447 && ix86_match_ccmode (insn, CCNOmode) 8448 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8449 "and{b}\t{%1, %0|%0, %1}" 8450 [(set_attr "type" "alu1") 8451 (set_attr "mode" "QI")]) 8452 8453;; ??? A bug in recog prevents it from recognizing a const_int as an 8454;; operand to zero_extend in andqi_ext_1. It was checking explicitly 8455;; for a QImode operand, which of course failed. 8456 8457(define_insn "andqi_ext_0" 8458 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8459 (const_int 8) 8460 (const_int 8)) 8461 (and:SI 8462 (zero_extract:SI 8463 (match_operand 1 "ext_register_operand" "0") 8464 (const_int 8) 8465 (const_int 8)) 8466 (match_operand 2 "const_int_operand" "n"))) 8467 (clobber (reg:CC FLAGS_REG))] 8468 "" 8469 "and{b}\t{%2, %h0|%h0, %2}" 8470 [(set_attr "type" "alu") 8471 (set_attr "length_immediate" "1") 8472 (set_attr "mode" "QI")]) 8473 8474;; Generated by peephole translating test to and. This shows up 8475;; often in fp comparisons. 8476 8477(define_insn "*andqi_ext_0_cc" 8478 [(set (reg FLAGS_REG) 8479 (compare 8480 (and:SI 8481 (zero_extract:SI 8482 (match_operand 1 "ext_register_operand" "0") 8483 (const_int 8) 8484 (const_int 8)) 8485 (match_operand 2 "const_int_operand" "n")) 8486 (const_int 0))) 8487 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8488 (const_int 8) 8489 (const_int 8)) 8490 (and:SI 8491 (zero_extract:SI 8492 (match_dup 1) 8493 (const_int 8) 8494 (const_int 8)) 8495 (match_dup 2)))] 8496 "ix86_match_ccmode (insn, CCNOmode)" 8497 "and{b}\t{%2, %h0|%h0, %2}" 8498 [(set_attr "type" "alu") 8499 (set_attr "length_immediate" "1") 8500 (set_attr "mode" "QI")]) 8501 8502(define_insn "*andqi_ext_1" 8503 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8504 (const_int 8) 8505 (const_int 8)) 8506 (and:SI 8507 (zero_extract:SI 8508 (match_operand 1 "ext_register_operand" "0") 8509 (const_int 8) 8510 (const_int 8)) 8511 (zero_extend:SI 8512 (match_operand:QI 2 "general_operand" "Qm")))) 8513 (clobber (reg:CC FLAGS_REG))] 8514 "!TARGET_64BIT" 8515 "and{b}\t{%2, %h0|%h0, %2}" 8516 [(set_attr "type" "alu") 8517 (set_attr "length_immediate" "0") 8518 (set_attr "mode" "QI")]) 8519 8520(define_insn "*andqi_ext_1_rex64" 8521 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8522 (const_int 8) 8523 (const_int 8)) 8524 (and:SI 8525 (zero_extract:SI 8526 (match_operand 1 "ext_register_operand" "0") 8527 (const_int 8) 8528 (const_int 8)) 8529 (zero_extend:SI 8530 (match_operand 2 "ext_register_operand" "Q")))) 8531 (clobber (reg:CC FLAGS_REG))] 8532 "TARGET_64BIT" 8533 "and{b}\t{%2, %h0|%h0, %2}" 8534 [(set_attr "type" "alu") 8535 (set_attr "length_immediate" "0") 8536 (set_attr "mode" "QI")]) 8537 8538(define_insn "*andqi_ext_2" 8539 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8540 (const_int 8) 8541 (const_int 8)) 8542 (and:SI 8543 (zero_extract:SI 8544 (match_operand 1 "ext_register_operand" "%0") 8545 (const_int 8) 8546 (const_int 8)) 8547 (zero_extract:SI 8548 (match_operand 2 "ext_register_operand" "Q") 8549 (const_int 8) 8550 (const_int 8)))) 8551 (clobber (reg:CC FLAGS_REG))] 8552 "" 8553 "and{b}\t{%h2, %h0|%h0, %h2}" 8554 [(set_attr "type" "alu") 8555 (set_attr "length_immediate" "0") 8556 (set_attr "mode" "QI")]) 8557 8558;; Convert wide AND instructions with immediate operand to shorter QImode 8559;; equivalents when possible. 8560;; Don't do the splitting with memory operands, since it introduces risk 8561;; of memory mismatch stalls. We may want to do the splitting for optimizing 8562;; for size, but that can (should?) be handled by generic code instead. 8563(define_split 8564 [(set (match_operand 0 "register_operand" "") 8565 (and (match_operand 1 "register_operand" "") 8566 (match_operand 2 "const_int_operand" ""))) 8567 (clobber (reg:CC FLAGS_REG))] 8568 "reload_completed 8569 && QI_REG_P (operands[0]) 8570 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8571 && !(~INTVAL (operands[2]) & ~(255 << 8)) 8572 && GET_MODE (operands[0]) != QImode" 8573 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8574 (and:SI (zero_extract:SI (match_dup 1) 8575 (const_int 8) (const_int 8)) 8576 (match_dup 2))) 8577 (clobber (reg:CC FLAGS_REG))])] 8578 "operands[0] = gen_lowpart (SImode, operands[0]); 8579 operands[1] = gen_lowpart (SImode, operands[1]); 8580 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") 8581 8582;; Since AND can be encoded with sign extended immediate, this is only 8583;; profitable when 7th bit is not set. 8584(define_split 8585 [(set (match_operand 0 "register_operand" "") 8586 (and (match_operand 1 "general_operand" "") 8587 (match_operand 2 "const_int_operand" ""))) 8588 (clobber (reg:CC FLAGS_REG))] 8589 "reload_completed 8590 && ANY_QI_REG_P (operands[0]) 8591 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8592 && !(~INTVAL (operands[2]) & ~255) 8593 && !(INTVAL (operands[2]) & 128) 8594 && GET_MODE (operands[0]) != QImode" 8595 [(parallel [(set (strict_low_part (match_dup 0)) 8596 (and:QI (match_dup 1) 8597 (match_dup 2))) 8598 (clobber (reg:CC FLAGS_REG))])] 8599 "operands[0] = gen_lowpart (QImode, operands[0]); 8600 operands[1] = gen_lowpart (QImode, operands[1]); 8601 operands[2] = gen_lowpart (QImode, operands[2]);") 8602 8603;; Logical inclusive OR instructions 8604 8605;; %%% This used to optimize known byte-wide and operations to memory. 8606;; If this is considered useful, it should be done with splitters. 8607 8608(define_expand "iordi3" 8609 [(set (match_operand:DI 0 "nonimmediate_operand" "") 8610 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "") 8611 (match_operand:DI 2 "x86_64_general_operand" ""))) 8612 (clobber (reg:CC FLAGS_REG))] 8613 "TARGET_64BIT" 8614 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;") 8615 8616(define_insn "*iordi_1_rex64" 8617 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 8618 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8619 (match_operand:DI 2 "x86_64_general_operand" "re,rme"))) 8620 (clobber (reg:CC FLAGS_REG))] 8621 "TARGET_64BIT 8622 && ix86_binary_operator_ok (IOR, DImode, operands)" 8623 "or{q}\t{%2, %0|%0, %2}" 8624 [(set_attr "type" "alu") 8625 (set_attr "mode" "DI")]) 8626 8627(define_insn "*iordi_2_rex64" 8628 [(set (reg FLAGS_REG) 8629 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8630 (match_operand:DI 2 "x86_64_general_operand" "rem,re")) 8631 (const_int 0))) 8632 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") 8633 (ior:DI (match_dup 1) (match_dup 2)))] 8634 "TARGET_64BIT 8635 && ix86_match_ccmode (insn, CCNOmode) 8636 && ix86_binary_operator_ok (IOR, DImode, operands)" 8637 "or{q}\t{%2, %0|%0, %2}" 8638 [(set_attr "type" "alu") 8639 (set_attr "mode" "DI")]) 8640 8641(define_insn "*iordi_3_rex64" 8642 [(set (reg FLAGS_REG) 8643 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0") 8644 (match_operand:DI 2 "x86_64_general_operand" "rem")) 8645 (const_int 0))) 8646 (clobber (match_scratch:DI 0 "=r"))] 8647 "TARGET_64BIT 8648 && ix86_match_ccmode (insn, CCNOmode) 8649 && ix86_binary_operator_ok (IOR, DImode, operands)" 8650 "or{q}\t{%2, %0|%0, %2}" 8651 [(set_attr "type" "alu") 8652 (set_attr "mode" "DI")]) 8653 8654 8655(define_expand "iorsi3" 8656 [(set (match_operand:SI 0 "nonimmediate_operand" "") 8657 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "") 8658 (match_operand:SI 2 "general_operand" ""))) 8659 (clobber (reg:CC FLAGS_REG))] 8660 "" 8661 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;") 8662 8663(define_insn "*iorsi_1" 8664 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 8665 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8666 (match_operand:SI 2 "general_operand" "ri,rmi"))) 8667 (clobber (reg:CC FLAGS_REG))] 8668 "ix86_binary_operator_ok (IOR, SImode, operands)" 8669 "or{l}\t{%2, %0|%0, %2}" 8670 [(set_attr "type" "alu") 8671 (set_attr "mode" "SI")]) 8672 8673;; See comment for addsi_1_zext why we do use nonimmediate_operand 8674(define_insn "*iorsi_1_zext" 8675 [(set (match_operand:DI 0 "register_operand" "=rm") 8676 (zero_extend:DI 8677 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8678 (match_operand:SI 2 "general_operand" "rim")))) 8679 (clobber (reg:CC FLAGS_REG))] 8680 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)" 8681 "or{l}\t{%2, %k0|%k0, %2}" 8682 [(set_attr "type" "alu") 8683 (set_attr "mode" "SI")]) 8684 8685(define_insn "*iorsi_1_zext_imm" 8686 [(set (match_operand:DI 0 "register_operand" "=rm") 8687 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 8688 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 8689 (clobber (reg:CC FLAGS_REG))] 8690 "TARGET_64BIT" 8691 "or{l}\t{%2, %k0|%k0, %2}" 8692 [(set_attr "type" "alu") 8693 (set_attr "mode" "SI")]) 8694 8695(define_insn "*iorsi_2" 8696 [(set (reg FLAGS_REG) 8697 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8698 (match_operand:SI 2 "general_operand" "rim,ri")) 8699 (const_int 0))) 8700 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 8701 (ior:SI (match_dup 1) (match_dup 2)))] 8702 "ix86_match_ccmode (insn, CCNOmode) 8703 && ix86_binary_operator_ok (IOR, SImode, operands)" 8704 "or{l}\t{%2, %0|%0, %2}" 8705 [(set_attr "type" "alu") 8706 (set_attr "mode" "SI")]) 8707 8708;; See comment for addsi_1_zext why we do use nonimmediate_operand 8709;; ??? Special case for immediate operand is missing - it is tricky. 8710(define_insn "*iorsi_2_zext" 8711 [(set (reg FLAGS_REG) 8712 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8713 (match_operand:SI 2 "general_operand" "rim")) 8714 (const_int 0))) 8715 (set (match_operand:DI 0 "register_operand" "=r") 8716 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))] 8717 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8718 && ix86_binary_operator_ok (IOR, SImode, operands)" 8719 "or{l}\t{%2, %k0|%k0, %2}" 8720 [(set_attr "type" "alu") 8721 (set_attr "mode" "SI")]) 8722 8723(define_insn "*iorsi_2_zext_imm" 8724 [(set (reg FLAGS_REG) 8725 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8726 (match_operand 2 "x86_64_zext_immediate_operand" "Z")) 8727 (const_int 0))) 8728 (set (match_operand:DI 0 "register_operand" "=r") 8729 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 8730 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8731 && ix86_binary_operator_ok (IOR, SImode, operands)" 8732 "or{l}\t{%2, %k0|%k0, %2}" 8733 [(set_attr "type" "alu") 8734 (set_attr "mode" "SI")]) 8735 8736(define_insn "*iorsi_3" 8737 [(set (reg FLAGS_REG) 8738 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8739 (match_operand:SI 2 "general_operand" "rim")) 8740 (const_int 0))) 8741 (clobber (match_scratch:SI 0 "=r"))] 8742 "ix86_match_ccmode (insn, CCNOmode) 8743 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 8744 "or{l}\t{%2, %0|%0, %2}" 8745 [(set_attr "type" "alu") 8746 (set_attr "mode" "SI")]) 8747 8748(define_expand "iorhi3" 8749 [(set (match_operand:HI 0 "nonimmediate_operand" "") 8750 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "") 8751 (match_operand:HI 2 "general_operand" ""))) 8752 (clobber (reg:CC FLAGS_REG))] 8753 "TARGET_HIMODE_MATH" 8754 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;") 8755 8756(define_insn "*iorhi_1" 8757 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m") 8758 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 8759 (match_operand:HI 2 "general_operand" "rmi,ri"))) 8760 (clobber (reg:CC FLAGS_REG))] 8761 "ix86_binary_operator_ok (IOR, HImode, operands)" 8762 "or{w}\t{%2, %0|%0, %2}" 8763 [(set_attr "type" "alu") 8764 (set_attr "mode" "HI")]) 8765 8766(define_insn "*iorhi_2" 8767 [(set (reg FLAGS_REG) 8768 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 8769 (match_operand:HI 2 "general_operand" "rim,ri")) 8770 (const_int 0))) 8771 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 8772 (ior:HI (match_dup 1) (match_dup 2)))] 8773 "ix86_match_ccmode (insn, CCNOmode) 8774 && ix86_binary_operator_ok (IOR, HImode, operands)" 8775 "or{w}\t{%2, %0|%0, %2}" 8776 [(set_attr "type" "alu") 8777 (set_attr "mode" "HI")]) 8778 8779(define_insn "*iorhi_3" 8780 [(set (reg FLAGS_REG) 8781 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0") 8782 (match_operand:HI 2 "general_operand" "rim")) 8783 (const_int 0))) 8784 (clobber (match_scratch:HI 0 "=r"))] 8785 "ix86_match_ccmode (insn, CCNOmode) 8786 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 8787 "or{w}\t{%2, %0|%0, %2}" 8788 [(set_attr "type" "alu") 8789 (set_attr "mode" "HI")]) 8790 8791(define_expand "iorqi3" 8792 [(set (match_operand:QI 0 "nonimmediate_operand" "") 8793 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "") 8794 (match_operand:QI 2 "general_operand" ""))) 8795 (clobber (reg:CC FLAGS_REG))] 8796 "TARGET_QIMODE_MATH" 8797 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;") 8798 8799;; %%% Potential partial reg stall on alternative 2. What to do? 8800(define_insn "*iorqi_1" 8801 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") 8802 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8803 (match_operand:QI 2 "general_operand" "qmi,qi,ri"))) 8804 (clobber (reg:CC FLAGS_REG))] 8805 "ix86_binary_operator_ok (IOR, QImode, operands)" 8806 "@ 8807 or{b}\t{%2, %0|%0, %2} 8808 or{b}\t{%2, %0|%0, %2} 8809 or{l}\t{%k2, %k0|%k0, %k2}" 8810 [(set_attr "type" "alu") 8811 (set_attr "mode" "QI,QI,SI")]) 8812 8813(define_insn "*iorqi_1_slp" 8814 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m")) 8815 (ior:QI (match_dup 0) 8816 (match_operand:QI 1 "general_operand" "qmi,qi"))) 8817 (clobber (reg:CC FLAGS_REG))] 8818 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8819 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8820 "or{b}\t{%1, %0|%0, %1}" 8821 [(set_attr "type" "alu1") 8822 (set_attr "mode" "QI")]) 8823 8824(define_insn "*iorqi_2" 8825 [(set (reg FLAGS_REG) 8826 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 8827 (match_operand:QI 2 "general_operand" "qim,qi")) 8828 (const_int 0))) 8829 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 8830 (ior:QI (match_dup 1) (match_dup 2)))] 8831 "ix86_match_ccmode (insn, CCNOmode) 8832 && ix86_binary_operator_ok (IOR, QImode, operands)" 8833 "or{b}\t{%2, %0|%0, %2}" 8834 [(set_attr "type" "alu") 8835 (set_attr "mode" "QI")]) 8836 8837(define_insn "*iorqi_2_slp" 8838 [(set (reg FLAGS_REG) 8839 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 8840 (match_operand:QI 1 "general_operand" "qim,qi")) 8841 (const_int 0))) 8842 (set (strict_low_part (match_dup 0)) 8843 (ior:QI (match_dup 0) (match_dup 1)))] 8844 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8845 && ix86_match_ccmode (insn, CCNOmode) 8846 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8847 "or{b}\t{%1, %0|%0, %1}" 8848 [(set_attr "type" "alu1") 8849 (set_attr "mode" "QI")]) 8850 8851(define_insn "*iorqi_3" 8852 [(set (reg FLAGS_REG) 8853 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 8854 (match_operand:QI 2 "general_operand" "qim")) 8855 (const_int 0))) 8856 (clobber (match_scratch:QI 0 "=q"))] 8857 "ix86_match_ccmode (insn, CCNOmode) 8858 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 8859 "or{b}\t{%2, %0|%0, %2}" 8860 [(set_attr "type" "alu") 8861 (set_attr "mode" "QI")]) 8862 8863(define_insn "iorqi_ext_0" 8864 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8865 (const_int 8) 8866 (const_int 8)) 8867 (ior:SI 8868 (zero_extract:SI 8869 (match_operand 1 "ext_register_operand" "0") 8870 (const_int 8) 8871 (const_int 8)) 8872 (match_operand 2 "const_int_operand" "n"))) 8873 (clobber (reg:CC FLAGS_REG))] 8874 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 8875 "or{b}\t{%2, %h0|%h0, %2}" 8876 [(set_attr "type" "alu") 8877 (set_attr "length_immediate" "1") 8878 (set_attr "mode" "QI")]) 8879 8880(define_insn "*iorqi_ext_1" 8881 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8882 (const_int 8) 8883 (const_int 8)) 8884 (ior:SI 8885 (zero_extract:SI 8886 (match_operand 1 "ext_register_operand" "0") 8887 (const_int 8) 8888 (const_int 8)) 8889 (zero_extend:SI 8890 (match_operand:QI 2 "general_operand" "Qm")))) 8891 (clobber (reg:CC FLAGS_REG))] 8892 "!TARGET_64BIT 8893 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 8894 "or{b}\t{%2, %h0|%h0, %2}" 8895 [(set_attr "type" "alu") 8896 (set_attr "length_immediate" "0") 8897 (set_attr "mode" "QI")]) 8898 8899(define_insn "*iorqi_ext_1_rex64" 8900 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8901 (const_int 8) 8902 (const_int 8)) 8903 (ior:SI 8904 (zero_extract:SI 8905 (match_operand 1 "ext_register_operand" "0") 8906 (const_int 8) 8907 (const_int 8)) 8908 (zero_extend:SI 8909 (match_operand 2 "ext_register_operand" "Q")))) 8910 (clobber (reg:CC FLAGS_REG))] 8911 "TARGET_64BIT 8912 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 8913 "or{b}\t{%2, %h0|%h0, %2}" 8914 [(set_attr "type" "alu") 8915 (set_attr "length_immediate" "0") 8916 (set_attr "mode" "QI")]) 8917 8918(define_insn "*iorqi_ext_2" 8919 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8920 (const_int 8) 8921 (const_int 8)) 8922 (ior:SI 8923 (zero_extract:SI (match_operand 1 "ext_register_operand" "0") 8924 (const_int 8) 8925 (const_int 8)) 8926 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 8927 (const_int 8) 8928 (const_int 8)))) 8929 (clobber (reg:CC FLAGS_REG))] 8930 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 8931 "ior{b}\t{%h2, %h0|%h0, %h2}" 8932 [(set_attr "type" "alu") 8933 (set_attr "length_immediate" "0") 8934 (set_attr "mode" "QI")]) 8935 8936(define_split 8937 [(set (match_operand 0 "register_operand" "") 8938 (ior (match_operand 1 "register_operand" "") 8939 (match_operand 2 "const_int_operand" ""))) 8940 (clobber (reg:CC FLAGS_REG))] 8941 "reload_completed 8942 && QI_REG_P (operands[0]) 8943 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8944 && !(INTVAL (operands[2]) & ~(255 << 8)) 8945 && GET_MODE (operands[0]) != QImode" 8946 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8947 (ior:SI (zero_extract:SI (match_dup 1) 8948 (const_int 8) (const_int 8)) 8949 (match_dup 2))) 8950 (clobber (reg:CC FLAGS_REG))])] 8951 "operands[0] = gen_lowpart (SImode, operands[0]); 8952 operands[1] = gen_lowpart (SImode, operands[1]); 8953 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") 8954 8955;; Since OR can be encoded with sign extended immediate, this is only 8956;; profitable when 7th bit is set. 8957(define_split 8958 [(set (match_operand 0 "register_operand" "") 8959 (ior (match_operand 1 "general_operand" "") 8960 (match_operand 2 "const_int_operand" ""))) 8961 (clobber (reg:CC FLAGS_REG))] 8962 "reload_completed 8963 && ANY_QI_REG_P (operands[0]) 8964 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8965 && !(INTVAL (operands[2]) & ~255) 8966 && (INTVAL (operands[2]) & 128) 8967 && GET_MODE (operands[0]) != QImode" 8968 [(parallel [(set (strict_low_part (match_dup 0)) 8969 (ior:QI (match_dup 1) 8970 (match_dup 2))) 8971 (clobber (reg:CC FLAGS_REG))])] 8972 "operands[0] = gen_lowpart (QImode, operands[0]); 8973 operands[1] = gen_lowpart (QImode, operands[1]); 8974 operands[2] = gen_lowpart (QImode, operands[2]);") 8975 8976;; Logical XOR instructions 8977 8978;; %%% This used to optimize known byte-wide and operations to memory. 8979;; If this is considered useful, it should be done with splitters. 8980 8981(define_expand "xordi3" 8982 [(set (match_operand:DI 0 "nonimmediate_operand" "") 8983 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "") 8984 (match_operand:DI 2 "x86_64_general_operand" ""))) 8985 (clobber (reg:CC FLAGS_REG))] 8986 "TARGET_64BIT" 8987 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;") 8988 8989(define_insn "*xordi_1_rex64" 8990 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 8991 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8992 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 8993 (clobber (reg:CC FLAGS_REG))] 8994 "TARGET_64BIT 8995 && ix86_binary_operator_ok (XOR, DImode, operands)" 8996 "@ 8997 xor{q}\t{%2, %0|%0, %2} 8998 xor{q}\t{%2, %0|%0, %2}" 8999 [(set_attr "type" "alu") 9000 (set_attr "mode" "DI,DI")]) 9001 9002(define_insn "*xordi_2_rex64" 9003 [(set (reg FLAGS_REG) 9004 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 9005 (match_operand:DI 2 "x86_64_general_operand" "rem,re")) 9006 (const_int 0))) 9007 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") 9008 (xor:DI (match_dup 1) (match_dup 2)))] 9009 "TARGET_64BIT 9010 && ix86_match_ccmode (insn, CCNOmode) 9011 && ix86_binary_operator_ok (XOR, DImode, operands)" 9012 "@ 9013 xor{q}\t{%2, %0|%0, %2} 9014 xor{q}\t{%2, %0|%0, %2}" 9015 [(set_attr "type" "alu") 9016 (set_attr "mode" "DI,DI")]) 9017 9018(define_insn "*xordi_3_rex64" 9019 [(set (reg FLAGS_REG) 9020 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0") 9021 (match_operand:DI 2 "x86_64_general_operand" "rem")) 9022 (const_int 0))) 9023 (clobber (match_scratch:DI 0 "=r"))] 9024 "TARGET_64BIT 9025 && ix86_match_ccmode (insn, CCNOmode) 9026 && ix86_binary_operator_ok (XOR, DImode, operands)" 9027 "xor{q}\t{%2, %0|%0, %2}" 9028 [(set_attr "type" "alu") 9029 (set_attr "mode" "DI")]) 9030 9031(define_expand "xorsi3" 9032 [(set (match_operand:SI 0 "nonimmediate_operand" "") 9033 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "") 9034 (match_operand:SI 2 "general_operand" ""))) 9035 (clobber (reg:CC FLAGS_REG))] 9036 "" 9037 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;") 9038 9039(define_insn "*xorsi_1" 9040 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 9041 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 9042 (match_operand:SI 2 "general_operand" "ri,rm"))) 9043 (clobber (reg:CC FLAGS_REG))] 9044 "ix86_binary_operator_ok (XOR, SImode, operands)" 9045 "xor{l}\t{%2, %0|%0, %2}" 9046 [(set_attr "type" "alu") 9047 (set_attr "mode" "SI")]) 9048 9049;; See comment for addsi_1_zext why we do use nonimmediate_operand 9050;; Add speccase for immediates 9051(define_insn "*xorsi_1_zext" 9052 [(set (match_operand:DI 0 "register_operand" "=r") 9053 (zero_extend:DI 9054 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9055 (match_operand:SI 2 "general_operand" "rim")))) 9056 (clobber (reg:CC FLAGS_REG))] 9057 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)" 9058 "xor{l}\t{%2, %k0|%k0, %2}" 9059 [(set_attr "type" "alu") 9060 (set_attr "mode" "SI")]) 9061 9062(define_insn "*xorsi_1_zext_imm" 9063 [(set (match_operand:DI 0 "register_operand" "=r") 9064 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 9065 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 9066 (clobber (reg:CC FLAGS_REG))] 9067 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)" 9068 "xor{l}\t{%2, %k0|%k0, %2}" 9069 [(set_attr "type" "alu") 9070 (set_attr "mode" "SI")]) 9071 9072(define_insn "*xorsi_2" 9073 [(set (reg FLAGS_REG) 9074 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 9075 (match_operand:SI 2 "general_operand" "rim,ri")) 9076 (const_int 0))) 9077 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 9078 (xor:SI (match_dup 1) (match_dup 2)))] 9079 "ix86_match_ccmode (insn, CCNOmode) 9080 && ix86_binary_operator_ok (XOR, SImode, operands)" 9081 "xor{l}\t{%2, %0|%0, %2}" 9082 [(set_attr "type" "alu") 9083 (set_attr "mode" "SI")]) 9084 9085;; See comment for addsi_1_zext why we do use nonimmediate_operand 9086;; ??? Special case for immediate operand is missing - it is tricky. 9087(define_insn "*xorsi_2_zext" 9088 [(set (reg FLAGS_REG) 9089 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9090 (match_operand:SI 2 "general_operand" "rim")) 9091 (const_int 0))) 9092 (set (match_operand:DI 0 "register_operand" "=r") 9093 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))] 9094 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9095 && ix86_binary_operator_ok (XOR, SImode, operands)" 9096 "xor{l}\t{%2, %k0|%k0, %2}" 9097 [(set_attr "type" "alu") 9098 (set_attr "mode" "SI")]) 9099 9100(define_insn "*xorsi_2_zext_imm" 9101 [(set (reg FLAGS_REG) 9102 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9103 (match_operand 2 "x86_64_zext_immediate_operand" "Z")) 9104 (const_int 0))) 9105 (set (match_operand:DI 0 "register_operand" "=r") 9106 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 9107 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9108 && ix86_binary_operator_ok (XOR, SImode, operands)" 9109 "xor{l}\t{%2, %k0|%k0, %2}" 9110 [(set_attr "type" "alu") 9111 (set_attr "mode" "SI")]) 9112 9113(define_insn "*xorsi_3" 9114 [(set (reg FLAGS_REG) 9115 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9116 (match_operand:SI 2 "general_operand" "rim")) 9117 (const_int 0))) 9118 (clobber (match_scratch:SI 0 "=r"))] 9119 "ix86_match_ccmode (insn, CCNOmode) 9120 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 9121 "xor{l}\t{%2, %0|%0, %2}" 9122 [(set_attr "type" "alu") 9123 (set_attr "mode" "SI")]) 9124 9125(define_expand "xorhi3" 9126 [(set (match_operand:HI 0 "nonimmediate_operand" "") 9127 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "") 9128 (match_operand:HI 2 "general_operand" ""))) 9129 (clobber (reg:CC FLAGS_REG))] 9130 "TARGET_HIMODE_MATH" 9131 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;") 9132 9133(define_insn "*xorhi_1" 9134 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m") 9135 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 9136 (match_operand:HI 2 "general_operand" "rmi,ri"))) 9137 (clobber (reg:CC FLAGS_REG))] 9138 "ix86_binary_operator_ok (XOR, HImode, operands)" 9139 "xor{w}\t{%2, %0|%0, %2}" 9140 [(set_attr "type" "alu") 9141 (set_attr "mode" "HI")]) 9142 9143(define_insn "*xorhi_2" 9144 [(set (reg FLAGS_REG) 9145 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 9146 (match_operand:HI 2 "general_operand" "rim,ri")) 9147 (const_int 0))) 9148 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 9149 (xor:HI (match_dup 1) (match_dup 2)))] 9150 "ix86_match_ccmode (insn, CCNOmode) 9151 && ix86_binary_operator_ok (XOR, HImode, operands)" 9152 "xor{w}\t{%2, %0|%0, %2}" 9153 [(set_attr "type" "alu") 9154 (set_attr "mode" "HI")]) 9155 9156(define_insn "*xorhi_3" 9157 [(set (reg FLAGS_REG) 9158 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0") 9159 (match_operand:HI 2 "general_operand" "rim")) 9160 (const_int 0))) 9161 (clobber (match_scratch:HI 0 "=r"))] 9162 "ix86_match_ccmode (insn, CCNOmode) 9163 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 9164 "xor{w}\t{%2, %0|%0, %2}" 9165 [(set_attr "type" "alu") 9166 (set_attr "mode" "HI")]) 9167 9168(define_expand "xorqi3" 9169 [(set (match_operand:QI 0 "nonimmediate_operand" "") 9170 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "") 9171 (match_operand:QI 2 "general_operand" ""))) 9172 (clobber (reg:CC FLAGS_REG))] 9173 "TARGET_QIMODE_MATH" 9174 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;") 9175 9176;; %%% Potential partial reg stall on alternative 2. What to do? 9177(define_insn "*xorqi_1" 9178 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") 9179 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 9180 (match_operand:QI 2 "general_operand" "qmi,qi,ri"))) 9181 (clobber (reg:CC FLAGS_REG))] 9182 "ix86_binary_operator_ok (XOR, QImode, operands)" 9183 "@ 9184 xor{b}\t{%2, %0|%0, %2} 9185 xor{b}\t{%2, %0|%0, %2} 9186 xor{l}\t{%k2, %k0|%k0, %k2}" 9187 [(set_attr "type" "alu") 9188 (set_attr "mode" "QI,QI,SI")]) 9189 9190(define_insn "*xorqi_1_slp" 9191 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 9192 (xor:QI (match_dup 0) 9193 (match_operand:QI 1 "general_operand" "qi,qmi"))) 9194 (clobber (reg:CC FLAGS_REG))] 9195 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 9196 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 9197 "xor{b}\t{%1, %0|%0, %1}" 9198 [(set_attr "type" "alu1") 9199 (set_attr "mode" "QI")]) 9200 9201(define_insn "xorqi_ext_0" 9202 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9203 (const_int 8) 9204 (const_int 8)) 9205 (xor:SI 9206 (zero_extract:SI 9207 (match_operand 1 "ext_register_operand" "0") 9208 (const_int 8) 9209 (const_int 8)) 9210 (match_operand 2 "const_int_operand" "n"))) 9211 (clobber (reg:CC FLAGS_REG))] 9212 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 9213 "xor{b}\t{%2, %h0|%h0, %2}" 9214 [(set_attr "type" "alu") 9215 (set_attr "length_immediate" "1") 9216 (set_attr "mode" "QI")]) 9217 9218(define_insn "*xorqi_ext_1" 9219 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9220 (const_int 8) 9221 (const_int 8)) 9222 (xor:SI 9223 (zero_extract:SI 9224 (match_operand 1 "ext_register_operand" "0") 9225 (const_int 8) 9226 (const_int 8)) 9227 (zero_extend:SI 9228 (match_operand:QI 2 "general_operand" "Qm")))) 9229 (clobber (reg:CC FLAGS_REG))] 9230 "!TARGET_64BIT 9231 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 9232 "xor{b}\t{%2, %h0|%h0, %2}" 9233 [(set_attr "type" "alu") 9234 (set_attr "length_immediate" "0") 9235 (set_attr "mode" "QI")]) 9236 9237(define_insn "*xorqi_ext_1_rex64" 9238 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9239 (const_int 8) 9240 (const_int 8)) 9241 (xor:SI 9242 (zero_extract:SI 9243 (match_operand 1 "ext_register_operand" "0") 9244 (const_int 8) 9245 (const_int 8)) 9246 (zero_extend:SI 9247 (match_operand 2 "ext_register_operand" "Q")))) 9248 (clobber (reg:CC FLAGS_REG))] 9249 "TARGET_64BIT 9250 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 9251 "xor{b}\t{%2, %h0|%h0, %2}" 9252 [(set_attr "type" "alu") 9253 (set_attr "length_immediate" "0") 9254 (set_attr "mode" "QI")]) 9255 9256(define_insn "*xorqi_ext_2" 9257 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9258 (const_int 8) 9259 (const_int 8)) 9260 (xor:SI 9261 (zero_extract:SI (match_operand 1 "ext_register_operand" "0") 9262 (const_int 8) 9263 (const_int 8)) 9264 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 9265 (const_int 8) 9266 (const_int 8)))) 9267 (clobber (reg:CC FLAGS_REG))] 9268 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 9269 "xor{b}\t{%h2, %h0|%h0, %h2}" 9270 [(set_attr "type" "alu") 9271 (set_attr "length_immediate" "0") 9272 (set_attr "mode" "QI")]) 9273 9274(define_insn "*xorqi_cc_1" 9275 [(set (reg FLAGS_REG) 9276 (compare 9277 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 9278 (match_operand:QI 2 "general_operand" "qim,qi")) 9279 (const_int 0))) 9280 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 9281 (xor:QI (match_dup 1) (match_dup 2)))] 9282 "ix86_match_ccmode (insn, CCNOmode) 9283 && ix86_binary_operator_ok (XOR, QImode, operands)" 9284 "xor{b}\t{%2, %0|%0, %2}" 9285 [(set_attr "type" "alu") 9286 (set_attr "mode" "QI")]) 9287 9288(define_insn "*xorqi_2_slp" 9289 [(set (reg FLAGS_REG) 9290 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 9291 (match_operand:QI 1 "general_operand" "qim,qi")) 9292 (const_int 0))) 9293 (set (strict_low_part (match_dup 0)) 9294 (xor:QI (match_dup 0) (match_dup 1)))] 9295 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 9296 && ix86_match_ccmode (insn, CCNOmode) 9297 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 9298 "xor{b}\t{%1, %0|%0, %1}" 9299 [(set_attr "type" "alu1") 9300 (set_attr "mode" "QI")]) 9301 9302(define_insn "*xorqi_cc_2" 9303 [(set (reg FLAGS_REG) 9304 (compare 9305 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 9306 (match_operand:QI 2 "general_operand" "qim")) 9307 (const_int 0))) 9308 (clobber (match_scratch:QI 0 "=q"))] 9309 "ix86_match_ccmode (insn, CCNOmode) 9310 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 9311 "xor{b}\t{%2, %0|%0, %2}" 9312 [(set_attr "type" "alu") 9313 (set_attr "mode" "QI")]) 9314 9315(define_insn "*xorqi_cc_ext_1" 9316 [(set (reg FLAGS_REG) 9317 (compare 9318 (xor:SI 9319 (zero_extract:SI 9320 (match_operand 1 "ext_register_operand" "0") 9321 (const_int 8) 9322 (const_int 8)) 9323 (match_operand:QI 2 "general_operand" "qmn")) 9324 (const_int 0))) 9325 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q") 9326 (const_int 8) 9327 (const_int 8)) 9328 (xor:SI 9329 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) 9330 (match_dup 2)))] 9331 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 9332 "xor{b}\t{%2, %h0|%h0, %2}" 9333 [(set_attr "type" "alu") 9334 (set_attr "mode" "QI")]) 9335 9336(define_insn "*xorqi_cc_ext_1_rex64" 9337 [(set (reg FLAGS_REG) 9338 (compare 9339 (xor:SI 9340 (zero_extract:SI 9341 (match_operand 1 "ext_register_operand" "0") 9342 (const_int 8) 9343 (const_int 8)) 9344 (match_operand:QI 2 "nonmemory_operand" "Qn")) 9345 (const_int 0))) 9346 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9347 (const_int 8) 9348 (const_int 8)) 9349 (xor:SI 9350 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) 9351 (match_dup 2)))] 9352 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 9353 "xor{b}\t{%2, %h0|%h0, %2}" 9354 [(set_attr "type" "alu") 9355 (set_attr "mode" "QI")]) 9356 9357(define_expand "xorqi_cc_ext_1" 9358 [(parallel [ 9359 (set (reg:CCNO FLAGS_REG) 9360 (compare:CCNO 9361 (xor:SI 9362 (zero_extract:SI 9363 (match_operand 1 "ext_register_operand" "") 9364 (const_int 8) 9365 (const_int 8)) 9366 (match_operand:QI 2 "general_operand" "")) 9367 (const_int 0))) 9368 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "") 9369 (const_int 8) 9370 (const_int 8)) 9371 (xor:SI 9372 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) 9373 (match_dup 2)))])] 9374 "" 9375 "") 9376 9377(define_split 9378 [(set (match_operand 0 "register_operand" "") 9379 (xor (match_operand 1 "register_operand" "") 9380 (match_operand 2 "const_int_operand" ""))) 9381 (clobber (reg:CC FLAGS_REG))] 9382 "reload_completed 9383 && QI_REG_P (operands[0]) 9384 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 9385 && !(INTVAL (operands[2]) & ~(255 << 8)) 9386 && GET_MODE (operands[0]) != QImode" 9387 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 9388 (xor:SI (zero_extract:SI (match_dup 1) 9389 (const_int 8) (const_int 8)) 9390 (match_dup 2))) 9391 (clobber (reg:CC FLAGS_REG))])] 9392 "operands[0] = gen_lowpart (SImode, operands[0]); 9393 operands[1] = gen_lowpart (SImode, operands[1]); 9394 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") 9395 9396;; Since XOR can be encoded with sign extended immediate, this is only 9397;; profitable when 7th bit is set. 9398(define_split 9399 [(set (match_operand 0 "register_operand" "") 9400 (xor (match_operand 1 "general_operand" "") 9401 (match_operand 2 "const_int_operand" ""))) 9402 (clobber (reg:CC FLAGS_REG))] 9403 "reload_completed 9404 && ANY_QI_REG_P (operands[0]) 9405 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 9406 && !(INTVAL (operands[2]) & ~255) 9407 && (INTVAL (operands[2]) & 128) 9408 && GET_MODE (operands[0]) != QImode" 9409 [(parallel [(set (strict_low_part (match_dup 0)) 9410 (xor:QI (match_dup 1) 9411 (match_dup 2))) 9412 (clobber (reg:CC FLAGS_REG))])] 9413 "operands[0] = gen_lowpart (QImode, operands[0]); 9414 operands[1] = gen_lowpart (QImode, operands[1]); 9415 operands[2] = gen_lowpart (QImode, operands[2]);") 9416 9417;; Negation instructions 9418 9419(define_expand "negti2" 9420 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "") 9421 (neg:TI (match_operand:TI 1 "nonimmediate_operand" ""))) 9422 (clobber (reg:CC FLAGS_REG))])] 9423 "TARGET_64BIT" 9424 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;") 9425 9426(define_insn "*negti2_1" 9427 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro") 9428 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0"))) 9429 (clobber (reg:CC FLAGS_REG))] 9430 "TARGET_64BIT 9431 && ix86_unary_operator_ok (NEG, TImode, operands)" 9432 "#") 9433 9434(define_split 9435 [(set (match_operand:TI 0 "nonimmediate_operand" "") 9436 (neg:TI (match_operand:TI 1 "nonimmediate_operand" ""))) 9437 (clobber (reg:CC FLAGS_REG))] 9438 "TARGET_64BIT && reload_completed" 9439 [(parallel 9440 [(set (reg:CCZ FLAGS_REG) 9441 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0))) 9442 (set (match_dup 0) (neg:DI (match_dup 2)))]) 9443 (parallel 9444 [(set (match_dup 1) 9445 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) 9446 (match_dup 3)) 9447 (const_int 0))) 9448 (clobber (reg:CC FLAGS_REG))]) 9449 (parallel 9450 [(set (match_dup 1) 9451 (neg:DI (match_dup 1))) 9452 (clobber (reg:CC FLAGS_REG))])] 9453 "split_ti (operands+1, 1, operands+2, operands+3); 9454 split_ti (operands+0, 1, operands+0, operands+1);") 9455 9456(define_expand "negdi2" 9457 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 9458 (neg:DI (match_operand:DI 1 "nonimmediate_operand" ""))) 9459 (clobber (reg:CC FLAGS_REG))])] 9460 "" 9461 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;") 9462 9463(define_insn "*negdi2_1" 9464 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro") 9465 (neg:DI (match_operand:DI 1 "general_operand" "0"))) 9466 (clobber (reg:CC FLAGS_REG))] 9467 "!TARGET_64BIT 9468 && ix86_unary_operator_ok (NEG, DImode, operands)" 9469 "#") 9470 9471(define_split 9472 [(set (match_operand:DI 0 "nonimmediate_operand" "") 9473 (neg:DI (match_operand:DI 1 "general_operand" ""))) 9474 (clobber (reg:CC FLAGS_REG))] 9475 "!TARGET_64BIT && reload_completed" 9476 [(parallel 9477 [(set (reg:CCZ FLAGS_REG) 9478 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0))) 9479 (set (match_dup 0) (neg:SI (match_dup 2)))]) 9480 (parallel 9481 [(set (match_dup 1) 9482 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) 9483 (match_dup 3)) 9484 (const_int 0))) 9485 (clobber (reg:CC FLAGS_REG))]) 9486 (parallel 9487 [(set (match_dup 1) 9488 (neg:SI (match_dup 1))) 9489 (clobber (reg:CC FLAGS_REG))])] 9490 "split_di (operands+1, 1, operands+2, operands+3); 9491 split_di (operands+0, 1, operands+0, operands+1);") 9492 9493(define_insn "*negdi2_1_rex64" 9494 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9495 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))) 9496 (clobber (reg:CC FLAGS_REG))] 9497 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)" 9498 "neg{q}\t%0" 9499 [(set_attr "type" "negnot") 9500 (set_attr "mode" "DI")]) 9501 9502;; The problem with neg is that it does not perform (compare x 0), 9503;; it really performs (compare 0 x), which leaves us with the zero 9504;; flag being the only useful item. 9505 9506(define_insn "*negdi2_cmpz_rex64" 9507 [(set (reg:CCZ FLAGS_REG) 9508 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")) 9509 (const_int 0))) 9510 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9511 (neg:DI (match_dup 1)))] 9512 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)" 9513 "neg{q}\t%0" 9514 [(set_attr "type" "negnot") 9515 (set_attr "mode" "DI")]) 9516 9517 9518(define_expand "negsi2" 9519 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 9520 (neg:SI (match_operand:SI 1 "nonimmediate_operand" ""))) 9521 (clobber (reg:CC FLAGS_REG))])] 9522 "" 9523 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;") 9524 9525(define_insn "*negsi2_1" 9526 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 9527 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))) 9528 (clobber (reg:CC FLAGS_REG))] 9529 "ix86_unary_operator_ok (NEG, SImode, operands)" 9530 "neg{l}\t%0" 9531 [(set_attr "type" "negnot") 9532 (set_attr "mode" "SI")]) 9533 9534;; Combine is quite creative about this pattern. 9535(define_insn "*negsi2_1_zext" 9536 [(set (match_operand:DI 0 "register_operand" "=r") 9537 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0") 9538 (const_int 32))) 9539 (const_int 32))) 9540 (clobber (reg:CC FLAGS_REG))] 9541 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9542 "neg{l}\t%k0" 9543 [(set_attr "type" "negnot") 9544 (set_attr "mode" "SI")]) 9545 9546;; The problem with neg is that it does not perform (compare x 0), 9547;; it really performs (compare 0 x), which leaves us with the zero 9548;; flag being the only useful item. 9549 9550(define_insn "*negsi2_cmpz" 9551 [(set (reg:CCZ FLAGS_REG) 9552 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")) 9553 (const_int 0))) 9554 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 9555 (neg:SI (match_dup 1)))] 9556 "ix86_unary_operator_ok (NEG, SImode, operands)" 9557 "neg{l}\t%0" 9558 [(set_attr "type" "negnot") 9559 (set_attr "mode" "SI")]) 9560 9561(define_insn "*negsi2_cmpz_zext" 9562 [(set (reg:CCZ FLAGS_REG) 9563 (compare:CCZ (lshiftrt:DI 9564 (neg:DI (ashift:DI 9565 (match_operand:DI 1 "register_operand" "0") 9566 (const_int 32))) 9567 (const_int 32)) 9568 (const_int 0))) 9569 (set (match_operand:DI 0 "register_operand" "=r") 9570 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1) 9571 (const_int 32))) 9572 (const_int 32)))] 9573 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9574 "neg{l}\t%k0" 9575 [(set_attr "type" "negnot") 9576 (set_attr "mode" "SI")]) 9577 9578(define_expand "neghi2" 9579 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 9580 (neg:HI (match_operand:HI 1 "nonimmediate_operand" ""))) 9581 (clobber (reg:CC FLAGS_REG))])] 9582 "TARGET_HIMODE_MATH" 9583 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;") 9584 9585(define_insn "*neghi2_1" 9586 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 9587 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))) 9588 (clobber (reg:CC FLAGS_REG))] 9589 "ix86_unary_operator_ok (NEG, HImode, operands)" 9590 "neg{w}\t%0" 9591 [(set_attr "type" "negnot") 9592 (set_attr "mode" "HI")]) 9593 9594(define_insn "*neghi2_cmpz" 9595 [(set (reg:CCZ FLAGS_REG) 9596 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")) 9597 (const_int 0))) 9598 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 9599 (neg:HI (match_dup 1)))] 9600 "ix86_unary_operator_ok (NEG, HImode, operands)" 9601 "neg{w}\t%0" 9602 [(set_attr "type" "negnot") 9603 (set_attr "mode" "HI")]) 9604 9605(define_expand "negqi2" 9606 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") 9607 (neg:QI (match_operand:QI 1 "nonimmediate_operand" ""))) 9608 (clobber (reg:CC FLAGS_REG))])] 9609 "TARGET_QIMODE_MATH" 9610 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;") 9611 9612(define_insn "*negqi2_1" 9613 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 9614 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))) 9615 (clobber (reg:CC FLAGS_REG))] 9616 "ix86_unary_operator_ok (NEG, QImode, operands)" 9617 "neg{b}\t%0" 9618 [(set_attr "type" "negnot") 9619 (set_attr "mode" "QI")]) 9620 9621(define_insn "*negqi2_cmpz" 9622 [(set (reg:CCZ FLAGS_REG) 9623 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")) 9624 (const_int 0))) 9625 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 9626 (neg:QI (match_dup 1)))] 9627 "ix86_unary_operator_ok (NEG, QImode, operands)" 9628 "neg{b}\t%0" 9629 [(set_attr "type" "negnot") 9630 (set_attr "mode" "QI")]) 9631 9632;; Changing of sign for FP values is doable using integer unit too. 9633 9634(define_expand "negsf2" 9635 [(set (match_operand:SF 0 "nonimmediate_operand" "") 9636 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))] 9637 "TARGET_80387 || TARGET_SSE_MATH" 9638 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;") 9639 9640(define_expand "abssf2" 9641 [(set (match_operand:SF 0 "nonimmediate_operand" "") 9642 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))] 9643 "TARGET_80387 || TARGET_SSE_MATH" 9644 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;") 9645 9646(define_insn "*absnegsf2_mixed" 9647 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm") 9648 (match_operator:SF 3 "absneg_operator" 9649 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")])) 9650 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X ")) 9651 (clobber (reg:CC FLAGS_REG))] 9652 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387 9653 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)" 9654 "#") 9655 9656(define_insn "*absnegsf2_sse" 9657 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm") 9658 (match_operator:SF 3 "absneg_operator" 9659 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")])) 9660 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X")) 9661 (clobber (reg:CC FLAGS_REG))] 9662 "TARGET_SSE_MATH 9663 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)" 9664 "#") 9665 9666(define_insn "*absnegsf2_i387" 9667 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm") 9668 (match_operator:SF 3 "absneg_operator" 9669 [(match_operand:SF 1 "nonimmediate_operand" "0,0")])) 9670 (use (match_operand 2 "" "")) 9671 (clobber (reg:CC FLAGS_REG))] 9672 "TARGET_80387 && !TARGET_SSE_MATH 9673 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)" 9674 "#") 9675 9676(define_expand "copysignsf3" 9677 [(match_operand:SF 0 "register_operand" "") 9678 (match_operand:SF 1 "nonmemory_operand" "") 9679 (match_operand:SF 2 "register_operand" "")] 9680 "TARGET_SSE_MATH" 9681{ 9682 ix86_expand_copysign (operands); 9683 DONE; 9684}) 9685 9686(define_insn_and_split "copysignsf3_const" 9687 [(set (match_operand:SF 0 "register_operand" "=x") 9688 (unspec:SF 9689 [(match_operand:V4SF 1 "vector_move_operand" "xmC") 9690 (match_operand:SF 2 "register_operand" "0") 9691 (match_operand:V4SF 3 "nonimmediate_operand" "xm")] 9692 UNSPEC_COPYSIGN))] 9693 "TARGET_SSE_MATH" 9694 "#" 9695 "&& reload_completed" 9696 [(const_int 0)] 9697{ 9698 ix86_split_copysign_const (operands); 9699 DONE; 9700}) 9701 9702(define_insn "copysignsf3_var" 9703 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x") 9704 (unspec:SF 9705 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x") 9706 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x") 9707 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0") 9708 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")] 9709 UNSPEC_COPYSIGN)) 9710 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))] 9711 "TARGET_SSE_MATH" 9712 "#") 9713 9714(define_split 9715 [(set (match_operand:SF 0 "register_operand" "") 9716 (unspec:SF 9717 [(match_operand:SF 2 "register_operand" "") 9718 (match_operand:SF 3 "register_operand" "") 9719 (match_operand:V4SF 4 "" "") 9720 (match_operand:V4SF 5 "" "")] 9721 UNSPEC_COPYSIGN)) 9722 (clobber (match_scratch:V4SF 1 ""))] 9723 "TARGET_SSE_MATH && reload_completed" 9724 [(const_int 0)] 9725{ 9726 ix86_split_copysign_var (operands); 9727 DONE; 9728}) 9729 9730(define_expand "negdf2" 9731 [(set (match_operand:DF 0 "nonimmediate_operand" "") 9732 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))] 9733 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 9734 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;") 9735 9736(define_expand "absdf2" 9737 [(set (match_operand:DF 0 "nonimmediate_operand" "") 9738 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))] 9739 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 9740 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;") 9741 9742(define_insn "*absnegdf2_mixed" 9743 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm") 9744 (match_operator:DF 3 "absneg_operator" 9745 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")])) 9746 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X")) 9747 (clobber (reg:CC FLAGS_REG))] 9748 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387 9749 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)" 9750 "#") 9751 9752(define_insn "*absnegdf2_sse" 9753 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm") 9754 (match_operator:DF 3 "absneg_operator" 9755 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")])) 9756 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X ")) 9757 (clobber (reg:CC FLAGS_REG))] 9758 "TARGET_SSE2 && TARGET_SSE_MATH 9759 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)" 9760 "#") 9761 9762(define_insn "*absnegdf2_i387" 9763 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm") 9764 (match_operator:DF 3 "absneg_operator" 9765 [(match_operand:DF 1 "nonimmediate_operand" "0,0")])) 9766 (use (match_operand 2 "" "")) 9767 (clobber (reg:CC FLAGS_REG))] 9768 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH) 9769 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)" 9770 "#") 9771 9772(define_expand "copysigndf3" 9773 [(match_operand:DF 0 "register_operand" "") 9774 (match_operand:DF 1 "nonmemory_operand" "") 9775 (match_operand:DF 2 "register_operand" "")] 9776 "TARGET_SSE2 && TARGET_SSE_MATH" 9777{ 9778 ix86_expand_copysign (operands); 9779 DONE; 9780}) 9781 9782(define_insn_and_split "copysigndf3_const" 9783 [(set (match_operand:DF 0 "register_operand" "=x") 9784 (unspec:DF 9785 [(match_operand:V2DF 1 "vector_move_operand" "xmC") 9786 (match_operand:DF 2 "register_operand" "0") 9787 (match_operand:V2DF 3 "nonimmediate_operand" "xm")] 9788 UNSPEC_COPYSIGN))] 9789 "TARGET_SSE2 && TARGET_SSE_MATH" 9790 "#" 9791 "&& reload_completed" 9792 [(const_int 0)] 9793{ 9794 ix86_split_copysign_const (operands); 9795 DONE; 9796}) 9797 9798(define_insn "copysigndf3_var" 9799 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x") 9800 (unspec:DF 9801 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x") 9802 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x") 9803 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0") 9804 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")] 9805 UNSPEC_COPYSIGN)) 9806 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))] 9807 "TARGET_SSE2 && TARGET_SSE_MATH" 9808 "#") 9809 9810(define_split 9811 [(set (match_operand:DF 0 "register_operand" "") 9812 (unspec:DF 9813 [(match_operand:DF 2 "register_operand" "") 9814 (match_operand:DF 3 "register_operand" "") 9815 (match_operand:V2DF 4 "" "") 9816 (match_operand:V2DF 5 "" "")] 9817 UNSPEC_COPYSIGN)) 9818 (clobber (match_scratch:V2DF 1 ""))] 9819 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed" 9820 [(const_int 0)] 9821{ 9822 ix86_split_copysign_var (operands); 9823 DONE; 9824}) 9825 9826(define_expand "negxf2" 9827 [(set (match_operand:XF 0 "nonimmediate_operand" "") 9828 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))] 9829 "TARGET_80387" 9830 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;") 9831 9832(define_expand "absxf2" 9833 [(set (match_operand:XF 0 "nonimmediate_operand" "") 9834 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))] 9835 "TARGET_80387" 9836 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;") 9837 9838(define_insn "*absnegxf2_i387" 9839 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm") 9840 (match_operator:XF 3 "absneg_operator" 9841 [(match_operand:XF 1 "nonimmediate_operand" "0,0")])) 9842 (use (match_operand 2 "" "")) 9843 (clobber (reg:CC FLAGS_REG))] 9844 "TARGET_80387 9845 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)" 9846 "#") 9847 9848;; Splitters for fp abs and neg. 9849 9850(define_split 9851 [(set (match_operand 0 "fp_register_operand" "") 9852 (match_operator 1 "absneg_operator" [(match_dup 0)])) 9853 (use (match_operand 2 "" "")) 9854 (clobber (reg:CC FLAGS_REG))] 9855 "reload_completed" 9856 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))]) 9857 9858(define_split 9859 [(set (match_operand 0 "register_operand" "") 9860 (match_operator 3 "absneg_operator" 9861 [(match_operand 1 "register_operand" "")])) 9862 (use (match_operand 2 "nonimmediate_operand" "")) 9863 (clobber (reg:CC FLAGS_REG))] 9864 "reload_completed && SSE_REG_P (operands[0])" 9865 [(set (match_dup 0) (match_dup 3))] 9866{ 9867 enum machine_mode mode = GET_MODE (operands[0]); 9868 enum machine_mode vmode = GET_MODE (operands[2]); 9869 rtx tmp; 9870 9871 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0); 9872 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0); 9873 if (operands_match_p (operands[0], operands[2])) 9874 { 9875 tmp = operands[1]; 9876 operands[1] = operands[2]; 9877 operands[2] = tmp; 9878 } 9879 if (GET_CODE (operands[3]) == ABS) 9880 tmp = gen_rtx_AND (vmode, operands[1], operands[2]); 9881 else 9882 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]); 9883 operands[3] = tmp; 9884}) 9885 9886(define_split 9887 [(set (match_operand:SF 0 "register_operand" "") 9888 (match_operator:SF 1 "absneg_operator" [(match_dup 0)])) 9889 (use (match_operand:V4SF 2 "" "")) 9890 (clobber (reg:CC FLAGS_REG))] 9891 "reload_completed" 9892 [(parallel [(set (match_dup 0) (match_dup 1)) 9893 (clobber (reg:CC FLAGS_REG))])] 9894{ 9895 rtx tmp; 9896 operands[0] = gen_lowpart (SImode, operands[0]); 9897 if (GET_CODE (operands[1]) == ABS) 9898 { 9899 tmp = gen_int_mode (0x7fffffff, SImode); 9900 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9901 } 9902 else 9903 { 9904 tmp = gen_int_mode (0x80000000, SImode); 9905 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 9906 } 9907 operands[1] = tmp; 9908}) 9909 9910(define_split 9911 [(set (match_operand:DF 0 "register_operand" "") 9912 (match_operator:DF 1 "absneg_operator" [(match_dup 0)])) 9913 (use (match_operand 2 "" "")) 9914 (clobber (reg:CC FLAGS_REG))] 9915 "reload_completed" 9916 [(parallel [(set (match_dup 0) (match_dup 1)) 9917 (clobber (reg:CC FLAGS_REG))])] 9918{ 9919 rtx tmp; 9920 if (TARGET_64BIT) 9921 { 9922 tmp = gen_lowpart (DImode, operands[0]); 9923 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63)); 9924 operands[0] = tmp; 9925 9926 if (GET_CODE (operands[1]) == ABS) 9927 tmp = const0_rtx; 9928 else 9929 tmp = gen_rtx_NOT (DImode, tmp); 9930 } 9931 else 9932 { 9933 operands[0] = gen_highpart (SImode, operands[0]); 9934 if (GET_CODE (operands[1]) == ABS) 9935 { 9936 tmp = gen_int_mode (0x7fffffff, SImode); 9937 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9938 } 9939 else 9940 { 9941 tmp = gen_int_mode (0x80000000, SImode); 9942 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 9943 } 9944 } 9945 operands[1] = tmp; 9946}) 9947 9948(define_split 9949 [(set (match_operand:XF 0 "register_operand" "") 9950 (match_operator:XF 1 "absneg_operator" [(match_dup 0)])) 9951 (use (match_operand 2 "" "")) 9952 (clobber (reg:CC FLAGS_REG))] 9953 "reload_completed" 9954 [(parallel [(set (match_dup 0) (match_dup 1)) 9955 (clobber (reg:CC FLAGS_REG))])] 9956{ 9957 rtx tmp; 9958 operands[0] = gen_rtx_REG (SImode, 9959 true_regnum (operands[0]) 9960 + (TARGET_64BIT ? 1 : 2)); 9961 if (GET_CODE (operands[1]) == ABS) 9962 { 9963 tmp = GEN_INT (0x7fff); 9964 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9965 } 9966 else 9967 { 9968 tmp = GEN_INT (0x8000); 9969 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 9970 } 9971 operands[1] = tmp; 9972}) 9973 9974(define_split 9975 [(set (match_operand 0 "memory_operand" "") 9976 (match_operator 1 "absneg_operator" [(match_dup 0)])) 9977 (use (match_operand 2 "" "")) 9978 (clobber (reg:CC FLAGS_REG))] 9979 "reload_completed" 9980 [(parallel [(set (match_dup 0) (match_dup 1)) 9981 (clobber (reg:CC FLAGS_REG))])] 9982{ 9983 enum machine_mode mode = GET_MODE (operands[0]); 9984 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode); 9985 rtx tmp; 9986 9987 operands[0] = adjust_address (operands[0], QImode, size - 1); 9988 if (GET_CODE (operands[1]) == ABS) 9989 { 9990 tmp = gen_int_mode (0x7f, QImode); 9991 tmp = gen_rtx_AND (QImode, operands[0], tmp); 9992 } 9993 else 9994 { 9995 tmp = gen_int_mode (0x80, QImode); 9996 tmp = gen_rtx_XOR (QImode, operands[0], tmp); 9997 } 9998 operands[1] = tmp; 9999}) 10000 10001;; Conditionalize these after reload. If they match before reload, we 10002;; lose the clobber and ability to use integer instructions. 10003 10004(define_insn "*negsf2_1" 10005 [(set (match_operand:SF 0 "register_operand" "=f") 10006 (neg:SF (match_operand:SF 1 "register_operand" "0")))] 10007 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)" 10008 "fchs" 10009 [(set_attr "type" "fsgn") 10010 (set_attr "mode" "SF")]) 10011 10012(define_insn "*negdf2_1" 10013 [(set (match_operand:DF 0 "register_operand" "=f") 10014 (neg:DF (match_operand:DF 1 "register_operand" "0")))] 10015 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))" 10016 "fchs" 10017 [(set_attr "type" "fsgn") 10018 (set_attr "mode" "DF")]) 10019 10020(define_insn "*negxf2_1" 10021 [(set (match_operand:XF 0 "register_operand" "=f") 10022 (neg:XF (match_operand:XF 1 "register_operand" "0")))] 10023 "TARGET_80387" 10024 "fchs" 10025 [(set_attr "type" "fsgn") 10026 (set_attr "mode" "XF")]) 10027 10028(define_insn "*abssf2_1" 10029 [(set (match_operand:SF 0 "register_operand" "=f") 10030 (abs:SF (match_operand:SF 1 "register_operand" "0")))] 10031 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)" 10032 "fabs" 10033 [(set_attr "type" "fsgn") 10034 (set_attr "mode" "SF")]) 10035 10036(define_insn "*absdf2_1" 10037 [(set (match_operand:DF 0 "register_operand" "=f") 10038 (abs:DF (match_operand:DF 1 "register_operand" "0")))] 10039 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))" 10040 "fabs" 10041 [(set_attr "type" "fsgn") 10042 (set_attr "mode" "DF")]) 10043 10044(define_insn "*absxf2_1" 10045 [(set (match_operand:XF 0 "register_operand" "=f") 10046 (abs:XF (match_operand:XF 1 "register_operand" "0")))] 10047 "TARGET_80387" 10048 "fabs" 10049 [(set_attr "type" "fsgn") 10050 (set_attr "mode" "DF")]) 10051 10052(define_insn "*negextendsfdf2" 10053 [(set (match_operand:DF 0 "register_operand" "=f") 10054 (neg:DF (float_extend:DF 10055 (match_operand:SF 1 "register_operand" "0"))))] 10056 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 10057 "fchs" 10058 [(set_attr "type" "fsgn") 10059 (set_attr "mode" "DF")]) 10060 10061(define_insn "*negextenddfxf2" 10062 [(set (match_operand:XF 0 "register_operand" "=f") 10063 (neg:XF (float_extend:XF 10064 (match_operand:DF 1 "register_operand" "0"))))] 10065 "TARGET_80387" 10066 "fchs" 10067 [(set_attr "type" "fsgn") 10068 (set_attr "mode" "XF")]) 10069 10070(define_insn "*negextendsfxf2" 10071 [(set (match_operand:XF 0 "register_operand" "=f") 10072 (neg:XF (float_extend:XF 10073 (match_operand:SF 1 "register_operand" "0"))))] 10074 "TARGET_80387" 10075 "fchs" 10076 [(set_attr "type" "fsgn") 10077 (set_attr "mode" "XF")]) 10078 10079(define_insn "*absextendsfdf2" 10080 [(set (match_operand:DF 0 "register_operand" "=f") 10081 (abs:DF (float_extend:DF 10082 (match_operand:SF 1 "register_operand" "0"))))] 10083 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 10084 "fabs" 10085 [(set_attr "type" "fsgn") 10086 (set_attr "mode" "DF")]) 10087 10088(define_insn "*absextenddfxf2" 10089 [(set (match_operand:XF 0 "register_operand" "=f") 10090 (abs:XF (float_extend:XF 10091 (match_operand:DF 1 "register_operand" "0"))))] 10092 "TARGET_80387" 10093 "fabs" 10094 [(set_attr "type" "fsgn") 10095 (set_attr "mode" "XF")]) 10096 10097(define_insn "*absextendsfxf2" 10098 [(set (match_operand:XF 0 "register_operand" "=f") 10099 (abs:XF (float_extend:XF 10100 (match_operand:SF 1 "register_operand" "0"))))] 10101 "TARGET_80387" 10102 "fabs" 10103 [(set_attr "type" "fsgn") 10104 (set_attr "mode" "XF")]) 10105 10106;; One complement instructions 10107 10108(define_expand "one_cmpldi2" 10109 [(set (match_operand:DI 0 "nonimmediate_operand" "") 10110 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))] 10111 "TARGET_64BIT" 10112 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;") 10113 10114(define_insn "*one_cmpldi2_1_rex64" 10115 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 10116 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))] 10117 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)" 10118 "not{q}\t%0" 10119 [(set_attr "type" "negnot") 10120 (set_attr "mode" "DI")]) 10121 10122(define_insn "*one_cmpldi2_2_rex64" 10123 [(set (reg FLAGS_REG) 10124 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")) 10125 (const_int 0))) 10126 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 10127 (not:DI (match_dup 1)))] 10128 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 10129 && ix86_unary_operator_ok (NOT, DImode, operands)" 10130 "#" 10131 [(set_attr "type" "alu1") 10132 (set_attr "mode" "DI")]) 10133 10134(define_split 10135 [(set (match_operand 0 "flags_reg_operand" "") 10136 (match_operator 2 "compare_operator" 10137 [(not:DI (match_operand:DI 3 "nonimmediate_operand" "")) 10138 (const_int 0)])) 10139 (set (match_operand:DI 1 "nonimmediate_operand" "") 10140 (not:DI (match_dup 3)))] 10141 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 10142 [(parallel [(set (match_dup 0) 10143 (match_op_dup 2 10144 [(xor:DI (match_dup 3) (const_int -1)) 10145 (const_int 0)])) 10146 (set (match_dup 1) 10147 (xor:DI (match_dup 3) (const_int -1)))])] 10148 "") 10149 10150(define_expand "one_cmplsi2" 10151 [(set (match_operand:SI 0 "nonimmediate_operand" "") 10152 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))] 10153 "" 10154 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;") 10155 10156(define_insn "*one_cmplsi2_1" 10157 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 10158 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))] 10159 "ix86_unary_operator_ok (NOT, SImode, operands)" 10160 "not{l}\t%0" 10161 [(set_attr "type" "negnot") 10162 (set_attr "mode" "SI")]) 10163 10164;; ??? Currently never generated - xor is used instead. 10165(define_insn "*one_cmplsi2_1_zext" 10166 [(set (match_operand:DI 0 "register_operand" "=r") 10167 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))] 10168 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)" 10169 "not{l}\t%k0" 10170 [(set_attr "type" "negnot") 10171 (set_attr "mode" "SI")]) 10172 10173(define_insn "*one_cmplsi2_2" 10174 [(set (reg FLAGS_REG) 10175 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")) 10176 (const_int 0))) 10177 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 10178 (not:SI (match_dup 1)))] 10179 "ix86_match_ccmode (insn, CCNOmode) 10180 && ix86_unary_operator_ok (NOT, SImode, operands)" 10181 "#" 10182 [(set_attr "type" "alu1") 10183 (set_attr "mode" "SI")]) 10184 10185(define_split 10186 [(set (match_operand 0 "flags_reg_operand" "") 10187 (match_operator 2 "compare_operator" 10188 [(not:SI (match_operand:SI 3 "nonimmediate_operand" "")) 10189 (const_int 0)])) 10190 (set (match_operand:SI 1 "nonimmediate_operand" "") 10191 (not:SI (match_dup 3)))] 10192 "ix86_match_ccmode (insn, CCNOmode)" 10193 [(parallel [(set (match_dup 0) 10194 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 10195 (const_int 0)])) 10196 (set (match_dup 1) 10197 (xor:SI (match_dup 3) (const_int -1)))])] 10198 "") 10199 10200;; ??? Currently never generated - xor is used instead. 10201(define_insn "*one_cmplsi2_2_zext" 10202 [(set (reg FLAGS_REG) 10203 (compare (not:SI (match_operand:SI 1 "register_operand" "0")) 10204 (const_int 0))) 10205 (set (match_operand:DI 0 "register_operand" "=r") 10206 (zero_extend:DI (not:SI (match_dup 1))))] 10207 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 10208 && ix86_unary_operator_ok (NOT, SImode, operands)" 10209 "#" 10210 [(set_attr "type" "alu1") 10211 (set_attr "mode" "SI")]) 10212 10213(define_split 10214 [(set (match_operand 0 "flags_reg_operand" "") 10215 (match_operator 2 "compare_operator" 10216 [(not:SI (match_operand:SI 3 "register_operand" "")) 10217 (const_int 0)])) 10218 (set (match_operand:DI 1 "register_operand" "") 10219 (zero_extend:DI (not:SI (match_dup 3))))] 10220 "ix86_match_ccmode (insn, CCNOmode)" 10221 [(parallel [(set (match_dup 0) 10222 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 10223 (const_int 0)])) 10224 (set (match_dup 1) 10225 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])] 10226 "") 10227 10228(define_expand "one_cmplhi2" 10229 [(set (match_operand:HI 0 "nonimmediate_operand" "") 10230 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))] 10231 "TARGET_HIMODE_MATH" 10232 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;") 10233 10234(define_insn "*one_cmplhi2_1" 10235 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10236 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] 10237 "ix86_unary_operator_ok (NOT, HImode, operands)" 10238 "not{w}\t%0" 10239 [(set_attr "type" "negnot") 10240 (set_attr "mode" "HI")]) 10241 10242(define_insn "*one_cmplhi2_2" 10243 [(set (reg FLAGS_REG) 10244 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")) 10245 (const_int 0))) 10246 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10247 (not:HI (match_dup 1)))] 10248 "ix86_match_ccmode (insn, CCNOmode) 10249 && ix86_unary_operator_ok (NEG, HImode, operands)" 10250 "#" 10251 [(set_attr "type" "alu1") 10252 (set_attr "mode" "HI")]) 10253 10254(define_split 10255 [(set (match_operand 0 "flags_reg_operand" "") 10256 (match_operator 2 "compare_operator" 10257 [(not:HI (match_operand:HI 3 "nonimmediate_operand" "")) 10258 (const_int 0)])) 10259 (set (match_operand:HI 1 "nonimmediate_operand" "") 10260 (not:HI (match_dup 3)))] 10261 "ix86_match_ccmode (insn, CCNOmode)" 10262 [(parallel [(set (match_dup 0) 10263 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1)) 10264 (const_int 0)])) 10265 (set (match_dup 1) 10266 (xor:HI (match_dup 3) (const_int -1)))])] 10267 "") 10268 10269;; %%% Potential partial reg stall on alternative 1. What to do? 10270(define_expand "one_cmplqi2" 10271 [(set (match_operand:QI 0 "nonimmediate_operand" "") 10272 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))] 10273 "TARGET_QIMODE_MATH" 10274 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;") 10275 10276(define_insn "*one_cmplqi2_1" 10277 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") 10278 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] 10279 "ix86_unary_operator_ok (NOT, QImode, operands)" 10280 "@ 10281 not{b}\t%0 10282 not{l}\t%k0" 10283 [(set_attr "type" "negnot") 10284 (set_attr "mode" "QI,SI")]) 10285 10286(define_insn "*one_cmplqi2_2" 10287 [(set (reg FLAGS_REG) 10288 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")) 10289 (const_int 0))) 10290 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 10291 (not:QI (match_dup 1)))] 10292 "ix86_match_ccmode (insn, CCNOmode) 10293 && ix86_unary_operator_ok (NOT, QImode, operands)" 10294 "#" 10295 [(set_attr "type" "alu1") 10296 (set_attr "mode" "QI")]) 10297 10298(define_split 10299 [(set (match_operand 0 "flags_reg_operand" "") 10300 (match_operator 2 "compare_operator" 10301 [(not:QI (match_operand:QI 3 "nonimmediate_operand" "")) 10302 (const_int 0)])) 10303 (set (match_operand:QI 1 "nonimmediate_operand" "") 10304 (not:QI (match_dup 3)))] 10305 "ix86_match_ccmode (insn, CCNOmode)" 10306 [(parallel [(set (match_dup 0) 10307 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1)) 10308 (const_int 0)])) 10309 (set (match_dup 1) 10310 (xor:QI (match_dup 3) (const_int -1)))])] 10311 "") 10312 10313;; Arithmetic shift instructions 10314 10315;; DImode shifts are implemented using the i386 "shift double" opcode, 10316;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count 10317;; is variable, then the count is in %cl and the "imm" operand is dropped 10318;; from the assembler input. 10319;; 10320;; This instruction shifts the target reg/mem as usual, but instead of 10321;; shifting in zeros, bits are shifted in from reg operand. If the insn 10322;; is a left shift double, bits are taken from the high order bits of 10323;; reg, else if the insn is a shift right double, bits are taken from the 10324;; low order bits of reg. So if %eax is "1234" and %edx is "5678", 10325;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". 10326;; 10327;; Since sh[lr]d does not change the `reg' operand, that is done 10328;; separately, making all shifts emit pairs of shift double and normal 10329;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to 10330;; support a 63 bit shift, each shift where the count is in a reg expands 10331;; to a pair of shifts, a branch, a shift by 32 and a label. 10332;; 10333;; If the shift count is a constant, we need never emit more than one 10334;; shift pair, instead using moves and sign extension for counts greater 10335;; than 31. 10336 10337(define_expand "ashlti3" 10338 [(parallel [(set (match_operand:TI 0 "register_operand" "") 10339 (ashift:TI (match_operand:TI 1 "register_operand" "") 10340 (match_operand:QI 2 "nonmemory_operand" ""))) 10341 (clobber (reg:CC FLAGS_REG))])] 10342 "TARGET_64BIT" 10343{ 10344 if (! immediate_operand (operands[2], QImode)) 10345 { 10346 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2])); 10347 DONE; 10348 } 10349 ix86_expand_binary_operator (ASHIFT, TImode, operands); 10350 DONE; 10351}) 10352 10353(define_insn "ashlti3_1" 10354 [(set (match_operand:TI 0 "register_operand" "=r") 10355 (ashift:TI (match_operand:TI 1 "register_operand" "0") 10356 (match_operand:QI 2 "register_operand" "c"))) 10357 (clobber (match_scratch:DI 3 "=&r")) 10358 (clobber (reg:CC FLAGS_REG))] 10359 "TARGET_64BIT" 10360 "#" 10361 [(set_attr "type" "multi")]) 10362 10363(define_insn "*ashlti3_2" 10364 [(set (match_operand:TI 0 "register_operand" "=r") 10365 (ashift:TI (match_operand:TI 1 "register_operand" "0") 10366 (match_operand:QI 2 "immediate_operand" "O"))) 10367 (clobber (reg:CC FLAGS_REG))] 10368 "TARGET_64BIT" 10369 "#" 10370 [(set_attr "type" "multi")]) 10371 10372(define_split 10373 [(set (match_operand:TI 0 "register_operand" "") 10374 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "") 10375 (match_operand:QI 2 "register_operand" ""))) 10376 (clobber (match_scratch:DI 3 "")) 10377 (clobber (reg:CC FLAGS_REG))] 10378 "TARGET_64BIT && reload_completed" 10379 [(const_int 0)] 10380 "ix86_split_ashl (operands, operands[3], TImode); DONE;") 10381 10382(define_split 10383 [(set (match_operand:TI 0 "register_operand" "") 10384 (ashift:TI (match_operand:TI 1 "register_operand" "") 10385 (match_operand:QI 2 "immediate_operand" ""))) 10386 (clobber (reg:CC FLAGS_REG))] 10387 "TARGET_64BIT && reload_completed" 10388 [(const_int 0)] 10389 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;") 10390 10391(define_insn "x86_64_shld" 10392 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m") 10393 (ior:DI (ashift:DI (match_dup 0) 10394 (match_operand:QI 2 "nonmemory_operand" "J,c")) 10395 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r") 10396 (minus:QI (const_int 64) (match_dup 2))))) 10397 (clobber (reg:CC FLAGS_REG))] 10398 "TARGET_64BIT" 10399 "@ 10400 shld{q}\t{%2, %1, %0|%0, %1, %2} 10401 shld{q}\t{%s2%1, %0|%0, %1, %2}" 10402 [(set_attr "type" "ishift") 10403 (set_attr "prefix_0f" "1") 10404 (set_attr "mode" "DI") 10405 (set_attr "athlon_decode" "vector") 10406 (set_attr "amdfam10_decode" "vector")]) 10407 10408(define_expand "x86_64_shift_adj" 10409 [(set (reg:CCZ FLAGS_REG) 10410 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "") 10411 (const_int 64)) 10412 (const_int 0))) 10413 (set (match_operand:DI 0 "register_operand" "") 10414 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10415 (match_operand:DI 1 "register_operand" "") 10416 (match_dup 0))) 10417 (set (match_dup 1) 10418 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10419 (match_operand:DI 3 "register_operand" "r") 10420 (match_dup 1)))] 10421 "TARGET_64BIT" 10422 "") 10423 10424(define_expand "ashldi3" 10425 [(set (match_operand:DI 0 "shiftdi_operand" "") 10426 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "") 10427 (match_operand:QI 2 "nonmemory_operand" "")))] 10428 "" 10429 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;") 10430 10431(define_insn "*ashldi3_1_rex64" 10432 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 10433 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l") 10434 (match_operand:QI 2 "nonmemory_operand" "cJ,M"))) 10435 (clobber (reg:CC FLAGS_REG))] 10436 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)" 10437{ 10438 switch (get_attr_type (insn)) 10439 { 10440 case TYPE_ALU: 10441 gcc_assert (operands[2] == const1_rtx); 10442 gcc_assert (rtx_equal_p (operands[0], operands[1])); 10443 return "add{q}\t{%0, %0|%0, %0}"; 10444 10445 case TYPE_LEA: 10446 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 10447 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3); 10448 operands[1] = gen_rtx_MULT (DImode, operands[1], 10449 GEN_INT (1 << INTVAL (operands[2]))); 10450 return "lea{q}\t{%a1, %0|%0, %a1}"; 10451 10452 default: 10453 if (REG_P (operands[2])) 10454 return "sal{q}\t{%b2, %0|%0, %b2}"; 10455 else if (operands[2] == const1_rtx 10456 && (TARGET_SHIFT1 || optimize_size)) 10457 return "sal{q}\t%0"; 10458 else 10459 return "sal{q}\t{%2, %0|%0, %2}"; 10460 } 10461} 10462 [(set (attr "type") 10463 (cond [(eq_attr "alternative" "1") 10464 (const_string "lea") 10465 (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;; Convert lea to the lea pattern to avoid flags dependency. 10475(define_split 10476 [(set (match_operand:DI 0 "register_operand" "") 10477 (ashift:DI (match_operand:DI 1 "index_register_operand" "") 10478 (match_operand:QI 2 "immediate_operand" ""))) 10479 (clobber (reg:CC FLAGS_REG))] 10480 "TARGET_64BIT && reload_completed 10481 && true_regnum (operands[0]) != true_regnum (operands[1])" 10482 [(set (match_dup 0) 10483 (mult:DI (match_dup 1) 10484 (match_dup 2)))] 10485 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);") 10486 10487;; This pattern can't accept a variable shift count, since shifts by 10488;; zero don't affect the flags. We assume that shifts by constant 10489;; zero are optimized away. 10490(define_insn "*ashldi3_cmp_rex64" 10491 [(set (reg FLAGS_REG) 10492 (compare 10493 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0") 10494 (match_operand:QI 2 "immediate_operand" "e")) 10495 (const_int 0))) 10496 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 10497 (ashift:DI (match_dup 1) (match_dup 2)))] 10498 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 10499 && ix86_binary_operator_ok (ASHIFT, DImode, operands) 10500 && (optimize_size 10501 || !TARGET_PARTIAL_FLAG_REG_STALL 10502 || (operands[2] == const1_rtx 10503 && (TARGET_SHIFT1 10504 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 10505{ 10506 switch (get_attr_type (insn)) 10507 { 10508 case TYPE_ALU: 10509 gcc_assert (operands[2] == const1_rtx); 10510 return "add{q}\t{%0, %0|%0, %0}"; 10511 10512 default: 10513 if (REG_P (operands[2])) 10514 return "sal{q}\t{%b2, %0|%0, %b2}"; 10515 else if (operands[2] == const1_rtx 10516 && (TARGET_SHIFT1 || optimize_size)) 10517 return "sal{q}\t%0"; 10518 else 10519 return "sal{q}\t{%2, %0|%0, %2}"; 10520 } 10521} 10522 [(set (attr "type") 10523 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10524 (const_int 0)) 10525 (match_operand 0 "register_operand" "")) 10526 (match_operand 2 "const1_operand" "")) 10527 (const_string "alu") 10528 ] 10529 (const_string "ishift"))) 10530 (set_attr "mode" "DI")]) 10531 10532(define_insn "*ashldi3_cconly_rex64" 10533 [(set (reg FLAGS_REG) 10534 (compare 10535 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0") 10536 (match_operand:QI 2 "immediate_operand" "e")) 10537 (const_int 0))) 10538 (clobber (match_scratch:DI 0 "=r"))] 10539 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 10540 && ix86_binary_operator_ok (ASHIFT, DImode, operands) 10541 && (optimize_size 10542 || !TARGET_PARTIAL_FLAG_REG_STALL 10543 || (operands[2] == const1_rtx 10544 && (TARGET_SHIFT1 10545 || TARGET_DOUBLE_WITH_ADD)))" 10546{ 10547 switch (get_attr_type (insn)) 10548 { 10549 case TYPE_ALU: 10550 gcc_assert (operands[2] == const1_rtx); 10551 return "add{q}\t{%0, %0|%0, %0}"; 10552 10553 default: 10554 if (REG_P (operands[2])) 10555 return "sal{q}\t{%b2, %0|%0, %b2}"; 10556 else if (operands[2] == const1_rtx 10557 && (TARGET_SHIFT1 || optimize_size)) 10558 return "sal{q}\t%0"; 10559 else 10560 return "sal{q}\t{%2, %0|%0, %2}"; 10561 } 10562} 10563 [(set (attr "type") 10564 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10565 (const_int 0)) 10566 (match_operand 0 "register_operand" "")) 10567 (match_operand 2 "const1_operand" "")) 10568 (const_string "alu") 10569 ] 10570 (const_string "ishift"))) 10571 (set_attr "mode" "DI")]) 10572 10573(define_insn "*ashldi3_1" 10574 [(set (match_operand:DI 0 "register_operand" "=&r,r") 10575 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0") 10576 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc"))) 10577 (clobber (reg:CC FLAGS_REG))] 10578 "!TARGET_64BIT" 10579 "#" 10580 [(set_attr "type" "multi")]) 10581 10582;; By default we don't ask for a scratch register, because when DImode 10583;; values are manipulated, registers are already at a premium. But if 10584;; we have one handy, we won't turn it away. 10585(define_peephole2 10586 [(match_scratch:SI 3 "r") 10587 (parallel [(set (match_operand:DI 0 "register_operand" "") 10588 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "") 10589 (match_operand:QI 2 "nonmemory_operand" ""))) 10590 (clobber (reg:CC FLAGS_REG))]) 10591 (match_dup 3)] 10592 "!TARGET_64BIT && TARGET_CMOVE" 10593 [(const_int 0)] 10594 "ix86_split_ashl (operands, operands[3], DImode); DONE;") 10595 10596(define_split 10597 [(set (match_operand:DI 0 "register_operand" "") 10598 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "") 10599 (match_operand:QI 2 "nonmemory_operand" ""))) 10600 (clobber (reg:CC FLAGS_REG))] 10601 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) 10602 ? flow2_completed : reload_completed)" 10603 [(const_int 0)] 10604 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;") 10605 10606(define_insn "x86_shld_1" 10607 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m") 10608 (ior:SI (ashift:SI (match_dup 0) 10609 (match_operand:QI 2 "nonmemory_operand" "I,c")) 10610 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") 10611 (minus:QI (const_int 32) (match_dup 2))))) 10612 (clobber (reg:CC FLAGS_REG))] 10613 "" 10614 "@ 10615 shld{l}\t{%2, %1, %0|%0, %1, %2} 10616 shld{l}\t{%s2%1, %0|%0, %1, %2}" 10617 [(set_attr "type" "ishift") 10618 (set_attr "prefix_0f" "1") 10619 (set_attr "mode" "SI") 10620 (set_attr "pent_pair" "np") 10621 (set_attr "athlon_decode" "vector") 10622 (set_attr "amdfam10_decode" "vector")]) 10623 10624(define_expand "x86_shift_adj_1" 10625 [(set (reg:CCZ FLAGS_REG) 10626 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "") 10627 (const_int 32)) 10628 (const_int 0))) 10629 (set (match_operand:SI 0 "register_operand" "") 10630 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10631 (match_operand:SI 1 "register_operand" "") 10632 (match_dup 0))) 10633 (set (match_dup 1) 10634 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10635 (match_operand:SI 3 "register_operand" "r") 10636 (match_dup 1)))] 10637 "TARGET_CMOVE" 10638 "") 10639 10640(define_expand "x86_shift_adj_2" 10641 [(use (match_operand:SI 0 "register_operand" "")) 10642 (use (match_operand:SI 1 "register_operand" "")) 10643 (use (match_operand:QI 2 "register_operand" ""))] 10644 "" 10645{ 10646 rtx label = gen_label_rtx (); 10647 rtx tmp; 10648 10649 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32))); 10650 10651 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 10652 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 10653 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 10654 gen_rtx_LABEL_REF (VOIDmode, label), 10655 pc_rtx); 10656 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 10657 JUMP_LABEL (tmp) = label; 10658 10659 emit_move_insn (operands[0], operands[1]); 10660 ix86_expand_clear (operands[1]); 10661 10662 emit_label (label); 10663 LABEL_NUSES (label) = 1; 10664 10665 DONE; 10666}) 10667 10668(define_expand "ashlsi3" 10669 [(set (match_operand:SI 0 "nonimmediate_operand" "") 10670 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "") 10671 (match_operand:QI 2 "nonmemory_operand" ""))) 10672 (clobber (reg:CC FLAGS_REG))] 10673 "" 10674 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;") 10675 10676(define_insn "*ashlsi3_1" 10677 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 10678 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l") 10679 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 10680 (clobber (reg:CC FLAGS_REG))] 10681 "ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10682{ 10683 switch (get_attr_type (insn)) 10684 { 10685 case TYPE_ALU: 10686 gcc_assert (operands[2] == const1_rtx); 10687 gcc_assert (rtx_equal_p (operands[0], operands[1])); 10688 return "add{l}\t{%0, %0|%0, %0}"; 10689 10690 case TYPE_LEA: 10691 return "#"; 10692 10693 default: 10694 if (REG_P (operands[2])) 10695 return "sal{l}\t{%b2, %0|%0, %b2}"; 10696 else if (operands[2] == const1_rtx 10697 && (TARGET_SHIFT1 || optimize_size)) 10698 return "sal{l}\t%0"; 10699 else 10700 return "sal{l}\t{%2, %0|%0, %2}"; 10701 } 10702} 10703 [(set (attr "type") 10704 (cond [(eq_attr "alternative" "1") 10705 (const_string "lea") 10706 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10707 (const_int 0)) 10708 (match_operand 0 "register_operand" "")) 10709 (match_operand 2 "const1_operand" "")) 10710 (const_string "alu") 10711 ] 10712 (const_string "ishift"))) 10713 (set_attr "mode" "SI")]) 10714 10715;; Convert lea to the lea pattern to avoid flags dependency. 10716(define_split 10717 [(set (match_operand 0 "register_operand" "") 10718 (ashift (match_operand 1 "index_register_operand" "") 10719 (match_operand:QI 2 "const_int_operand" ""))) 10720 (clobber (reg:CC FLAGS_REG))] 10721 "reload_completed 10722 && true_regnum (operands[0]) != true_regnum (operands[1]) 10723 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4" 10724 [(const_int 0)] 10725{ 10726 rtx pat; 10727 enum machine_mode mode = GET_MODE (operands[0]); 10728 10729 if (GET_MODE_SIZE (mode) < 4) 10730 operands[0] = gen_lowpart (SImode, operands[0]); 10731 if (mode != Pmode) 10732 operands[1] = gen_lowpart (Pmode, operands[1]); 10733 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode); 10734 10735 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]); 10736 if (Pmode != SImode) 10737 pat = gen_rtx_SUBREG (SImode, pat, 0); 10738 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 10739 DONE; 10740}) 10741 10742;; Rare case of shifting RSP is handled by generating move and shift 10743(define_split 10744 [(set (match_operand 0 "register_operand" "") 10745 (ashift (match_operand 1 "register_operand" "") 10746 (match_operand:QI 2 "const_int_operand" ""))) 10747 (clobber (reg:CC FLAGS_REG))] 10748 "reload_completed 10749 && true_regnum (operands[0]) != true_regnum (operands[1])" 10750 [(const_int 0)] 10751{ 10752 rtx pat, clob; 10753 emit_move_insn (operands[0], operands[1]); 10754 pat = gen_rtx_SET (VOIDmode, operands[0], 10755 gen_rtx_ASHIFT (GET_MODE (operands[0]), 10756 operands[0], operands[2])); 10757 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); 10758 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob))); 10759 DONE; 10760}) 10761 10762(define_insn "*ashlsi3_1_zext" 10763 [(set (match_operand:DI 0 "register_operand" "=r,r") 10764 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l") 10765 (match_operand:QI 2 "nonmemory_operand" "cI,M")))) 10766 (clobber (reg:CC FLAGS_REG))] 10767 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10768{ 10769 switch (get_attr_type (insn)) 10770 { 10771 case TYPE_ALU: 10772 gcc_assert (operands[2] == const1_rtx); 10773 return "add{l}\t{%k0, %k0|%k0, %k0}"; 10774 10775 case TYPE_LEA: 10776 return "#"; 10777 10778 default: 10779 if (REG_P (operands[2])) 10780 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 10781 else if (operands[2] == const1_rtx 10782 && (TARGET_SHIFT1 || optimize_size)) 10783 return "sal{l}\t%k0"; 10784 else 10785 return "sal{l}\t{%2, %k0|%k0, %2}"; 10786 } 10787} 10788 [(set (attr "type") 10789 (cond [(eq_attr "alternative" "1") 10790 (const_string "lea") 10791 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10792 (const_int 0)) 10793 (match_operand 2 "const1_operand" "")) 10794 (const_string "alu") 10795 ] 10796 (const_string "ishift"))) 10797 (set_attr "mode" "SI")]) 10798 10799;; Convert lea to the lea pattern to avoid flags dependency. 10800(define_split 10801 [(set (match_operand:DI 0 "register_operand" "") 10802 (zero_extend:DI (ashift (match_operand 1 "register_operand" "") 10803 (match_operand:QI 2 "const_int_operand" "")))) 10804 (clobber (reg:CC FLAGS_REG))] 10805 "TARGET_64BIT && reload_completed 10806 && true_regnum (operands[0]) != true_regnum (operands[1])" 10807 [(set (match_dup 0) (zero_extend:DI 10808 (subreg:SI (mult:SI (match_dup 1) 10809 (match_dup 2)) 0)))] 10810{ 10811 operands[1] = gen_lowpart (Pmode, operands[1]); 10812 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode); 10813}) 10814 10815;; This pattern can't accept a variable shift count, since shifts by 10816;; zero don't affect the flags. We assume that shifts by constant 10817;; zero are optimized away. 10818(define_insn "*ashlsi3_cmp" 10819 [(set (reg FLAGS_REG) 10820 (compare 10821 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0") 10822 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10823 (const_int 0))) 10824 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 10825 (ashift:SI (match_dup 1) (match_dup 2)))] 10826 "ix86_match_ccmode (insn, CCGOCmode) 10827 && ix86_binary_operator_ok (ASHIFT, SImode, operands) 10828 && (optimize_size 10829 || !TARGET_PARTIAL_FLAG_REG_STALL 10830 || (operands[2] == const1_rtx 10831 && (TARGET_SHIFT1 10832 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 10833{ 10834 switch (get_attr_type (insn)) 10835 { 10836 case TYPE_ALU: 10837 gcc_assert (operands[2] == const1_rtx); 10838 return "add{l}\t{%0, %0|%0, %0}"; 10839 10840 default: 10841 if (REG_P (operands[2])) 10842 return "sal{l}\t{%b2, %0|%0, %b2}"; 10843 else if (operands[2] == const1_rtx 10844 && (TARGET_SHIFT1 || optimize_size)) 10845 return "sal{l}\t%0"; 10846 else 10847 return "sal{l}\t{%2, %0|%0, %2}"; 10848 } 10849} 10850 [(set (attr "type") 10851 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10852 (const_int 0)) 10853 (match_operand 0 "register_operand" "")) 10854 (match_operand 2 "const1_operand" "")) 10855 (const_string "alu") 10856 ] 10857 (const_string "ishift"))) 10858 (set_attr "mode" "SI")]) 10859 10860(define_insn "*ashlsi3_cconly" 10861 [(set (reg FLAGS_REG) 10862 (compare 10863 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0") 10864 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10865 (const_int 0))) 10866 (clobber (match_scratch:SI 0 "=r"))] 10867 "ix86_match_ccmode (insn, CCGOCmode) 10868 && ix86_binary_operator_ok (ASHIFT, SImode, operands) 10869 && (optimize_size 10870 || !TARGET_PARTIAL_FLAG_REG_STALL 10871 || (operands[2] == const1_rtx 10872 && (TARGET_SHIFT1 10873 || TARGET_DOUBLE_WITH_ADD)))" 10874{ 10875 switch (get_attr_type (insn)) 10876 { 10877 case TYPE_ALU: 10878 gcc_assert (operands[2] == const1_rtx); 10879 return "add{l}\t{%0, %0|%0, %0}"; 10880 10881 default: 10882 if (REG_P (operands[2])) 10883 return "sal{l}\t{%b2, %0|%0, %b2}"; 10884 else if (operands[2] == const1_rtx 10885 && (TARGET_SHIFT1 || optimize_size)) 10886 return "sal{l}\t%0"; 10887 else 10888 return "sal{l}\t{%2, %0|%0, %2}"; 10889 } 10890} 10891 [(set (attr "type") 10892 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10893 (const_int 0)) 10894 (match_operand 0 "register_operand" "")) 10895 (match_operand 2 "const1_operand" "")) 10896 (const_string "alu") 10897 ] 10898 (const_string "ishift"))) 10899 (set_attr "mode" "SI")]) 10900 10901(define_insn "*ashlsi3_cmp_zext" 10902 [(set (reg FLAGS_REG) 10903 (compare 10904 (ashift:SI (match_operand:SI 1 "register_operand" "0") 10905 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10906 (const_int 0))) 10907 (set (match_operand:DI 0 "register_operand" "=r") 10908 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 10909 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 10910 && ix86_binary_operator_ok (ASHIFT, SImode, operands) 10911 && (optimize_size 10912 || !TARGET_PARTIAL_FLAG_REG_STALL 10913 || (operands[2] == const1_rtx 10914 && (TARGET_SHIFT1 10915 || TARGET_DOUBLE_WITH_ADD)))" 10916{ 10917 switch (get_attr_type (insn)) 10918 { 10919 case TYPE_ALU: 10920 gcc_assert (operands[2] == const1_rtx); 10921 return "add{l}\t{%k0, %k0|%k0, %k0}"; 10922 10923 default: 10924 if (REG_P (operands[2])) 10925 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 10926 else if (operands[2] == const1_rtx 10927 && (TARGET_SHIFT1 || optimize_size)) 10928 return "sal{l}\t%k0"; 10929 else 10930 return "sal{l}\t{%2, %k0|%k0, %2}"; 10931 } 10932} 10933 [(set (attr "type") 10934 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10935 (const_int 0)) 10936 (match_operand 2 "const1_operand" "")) 10937 (const_string "alu") 10938 ] 10939 (const_string "ishift"))) 10940 (set_attr "mode" "SI")]) 10941 10942(define_expand "ashlhi3" 10943 [(set (match_operand:HI 0 "nonimmediate_operand" "") 10944 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "") 10945 (match_operand:QI 2 "nonmemory_operand" ""))) 10946 (clobber (reg:CC FLAGS_REG))] 10947 "TARGET_HIMODE_MATH" 10948 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;") 10949 10950(define_insn "*ashlhi3_1_lea" 10951 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 10952 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l") 10953 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 10954 (clobber (reg:CC FLAGS_REG))] 10955 "!TARGET_PARTIAL_REG_STALL 10956 && ix86_binary_operator_ok (ASHIFT, HImode, operands)" 10957{ 10958 switch (get_attr_type (insn)) 10959 { 10960 case TYPE_LEA: 10961 return "#"; 10962 case TYPE_ALU: 10963 gcc_assert (operands[2] == const1_rtx); 10964 return "add{w}\t{%0, %0|%0, %0}"; 10965 10966 default: 10967 if (REG_P (operands[2])) 10968 return "sal{w}\t{%b2, %0|%0, %b2}"; 10969 else if (operands[2] == const1_rtx 10970 && (TARGET_SHIFT1 || optimize_size)) 10971 return "sal{w}\t%0"; 10972 else 10973 return "sal{w}\t{%2, %0|%0, %2}"; 10974 } 10975} 10976 [(set (attr "type") 10977 (cond [(eq_attr "alternative" "1") 10978 (const_string "lea") 10979 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10980 (const_int 0)) 10981 (match_operand 0 "register_operand" "")) 10982 (match_operand 2 "const1_operand" "")) 10983 (const_string "alu") 10984 ] 10985 (const_string "ishift"))) 10986 (set_attr "mode" "HI,SI")]) 10987 10988(define_insn "*ashlhi3_1" 10989 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10990 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") 10991 (match_operand:QI 2 "nonmemory_operand" "cI"))) 10992 (clobber (reg:CC FLAGS_REG))] 10993 "TARGET_PARTIAL_REG_STALL 10994 && ix86_binary_operator_ok (ASHIFT, HImode, operands)" 10995{ 10996 switch (get_attr_type (insn)) 10997 { 10998 case TYPE_ALU: 10999 gcc_assert (operands[2] == const1_rtx); 11000 return "add{w}\t{%0, %0|%0, %0}"; 11001 11002 default: 11003 if (REG_P (operands[2])) 11004 return "sal{w}\t{%b2, %0|%0, %b2}"; 11005 else if (operands[2] == const1_rtx 11006 && (TARGET_SHIFT1 || optimize_size)) 11007 return "sal{w}\t%0"; 11008 else 11009 return "sal{w}\t{%2, %0|%0, %2}"; 11010 } 11011} 11012 [(set (attr "type") 11013 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11014 (const_int 0)) 11015 (match_operand 0 "register_operand" "")) 11016 (match_operand 2 "const1_operand" "")) 11017 (const_string "alu") 11018 ] 11019 (const_string "ishift"))) 11020 (set_attr "mode" "HI")]) 11021 11022;; This pattern can't accept a variable shift count, since shifts by 11023;; zero don't affect the flags. We assume that shifts by constant 11024;; zero are optimized away. 11025(define_insn "*ashlhi3_cmp" 11026 [(set (reg FLAGS_REG) 11027 (compare 11028 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11029 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11030 (const_int 0))) 11031 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 11032 (ashift:HI (match_dup 1) (match_dup 2)))] 11033 "ix86_match_ccmode (insn, CCGOCmode) 11034 && ix86_binary_operator_ok (ASHIFT, HImode, operands) 11035 && (optimize_size 11036 || !TARGET_PARTIAL_FLAG_REG_STALL 11037 || (operands[2] == const1_rtx 11038 && (TARGET_SHIFT1 11039 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 11040{ 11041 switch (get_attr_type (insn)) 11042 { 11043 case TYPE_ALU: 11044 gcc_assert (operands[2] == const1_rtx); 11045 return "add{w}\t{%0, %0|%0, %0}"; 11046 11047 default: 11048 if (REG_P (operands[2])) 11049 return "sal{w}\t{%b2, %0|%0, %b2}"; 11050 else if (operands[2] == const1_rtx 11051 && (TARGET_SHIFT1 || optimize_size)) 11052 return "sal{w}\t%0"; 11053 else 11054 return "sal{w}\t{%2, %0|%0, %2}"; 11055 } 11056} 11057 [(set (attr "type") 11058 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11059 (const_int 0)) 11060 (match_operand 0 "register_operand" "")) 11061 (match_operand 2 "const1_operand" "")) 11062 (const_string "alu") 11063 ] 11064 (const_string "ishift"))) 11065 (set_attr "mode" "HI")]) 11066 11067(define_insn "*ashlhi3_cconly" 11068 [(set (reg FLAGS_REG) 11069 (compare 11070 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11071 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11072 (const_int 0))) 11073 (clobber (match_scratch:HI 0 "=r"))] 11074 "ix86_match_ccmode (insn, CCGOCmode) 11075 && ix86_binary_operator_ok (ASHIFT, HImode, operands) 11076 && (optimize_size 11077 || !TARGET_PARTIAL_FLAG_REG_STALL 11078 || (operands[2] == const1_rtx 11079 && (TARGET_SHIFT1 11080 || TARGET_DOUBLE_WITH_ADD)))" 11081{ 11082 switch (get_attr_type (insn)) 11083 { 11084 case TYPE_ALU: 11085 gcc_assert (operands[2] == const1_rtx); 11086 return "add{w}\t{%0, %0|%0, %0}"; 11087 11088 default: 11089 if (REG_P (operands[2])) 11090 return "sal{w}\t{%b2, %0|%0, %b2}"; 11091 else if (operands[2] == const1_rtx 11092 && (TARGET_SHIFT1 || optimize_size)) 11093 return "sal{w}\t%0"; 11094 else 11095 return "sal{w}\t{%2, %0|%0, %2}"; 11096 } 11097} 11098 [(set (attr "type") 11099 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11100 (const_int 0)) 11101 (match_operand 0 "register_operand" "")) 11102 (match_operand 2 "const1_operand" "")) 11103 (const_string "alu") 11104 ] 11105 (const_string "ishift"))) 11106 (set_attr "mode" "HI")]) 11107 11108(define_expand "ashlqi3" 11109 [(set (match_operand:QI 0 "nonimmediate_operand" "") 11110 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "") 11111 (match_operand:QI 2 "nonmemory_operand" ""))) 11112 (clobber (reg:CC FLAGS_REG))] 11113 "TARGET_QIMODE_MATH" 11114 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;") 11115 11116;; %%% Potential partial reg stall on alternative 2. What to do? 11117 11118(define_insn "*ashlqi3_1_lea" 11119 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r") 11120 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l") 11121 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M"))) 11122 (clobber (reg:CC FLAGS_REG))] 11123 "!TARGET_PARTIAL_REG_STALL 11124 && ix86_binary_operator_ok (ASHIFT, QImode, operands)" 11125{ 11126 switch (get_attr_type (insn)) 11127 { 11128 case TYPE_LEA: 11129 return "#"; 11130 case TYPE_ALU: 11131 gcc_assert (operands[2] == const1_rtx); 11132 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) 11133 return "add{l}\t{%k0, %k0|%k0, %k0}"; 11134 else 11135 return "add{b}\t{%0, %0|%0, %0}"; 11136 11137 default: 11138 if (REG_P (operands[2])) 11139 { 11140 if (get_attr_mode (insn) == MODE_SI) 11141 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 11142 else 11143 return "sal{b}\t{%b2, %0|%0, %b2}"; 11144 } 11145 else if (operands[2] == const1_rtx 11146 && (TARGET_SHIFT1 || optimize_size)) 11147 { 11148 if (get_attr_mode (insn) == MODE_SI) 11149 return "sal{l}\t%0"; 11150 else 11151 return "sal{b}\t%0"; 11152 } 11153 else 11154 { 11155 if (get_attr_mode (insn) == MODE_SI) 11156 return "sal{l}\t{%2, %k0|%k0, %2}"; 11157 else 11158 return "sal{b}\t{%2, %0|%0, %2}"; 11159 } 11160 } 11161} 11162 [(set (attr "type") 11163 (cond [(eq_attr "alternative" "2") 11164 (const_string "lea") 11165 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11166 (const_int 0)) 11167 (match_operand 0 "register_operand" "")) 11168 (match_operand 2 "const1_operand" "")) 11169 (const_string "alu") 11170 ] 11171 (const_string "ishift"))) 11172 (set_attr "mode" "QI,SI,SI")]) 11173 11174(define_insn "*ashlqi3_1" 11175 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") 11176 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 11177 (match_operand:QI 2 "nonmemory_operand" "cI,cI"))) 11178 (clobber (reg:CC FLAGS_REG))] 11179 "TARGET_PARTIAL_REG_STALL 11180 && ix86_binary_operator_ok (ASHIFT, QImode, operands)" 11181{ 11182 switch (get_attr_type (insn)) 11183 { 11184 case TYPE_ALU: 11185 gcc_assert (operands[2] == const1_rtx); 11186 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) 11187 return "add{l}\t{%k0, %k0|%k0, %k0}"; 11188 else 11189 return "add{b}\t{%0, %0|%0, %0}"; 11190 11191 default: 11192 if (REG_P (operands[2])) 11193 { 11194 if (get_attr_mode (insn) == MODE_SI) 11195 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 11196 else 11197 return "sal{b}\t{%b2, %0|%0, %b2}"; 11198 } 11199 else if (operands[2] == const1_rtx 11200 && (TARGET_SHIFT1 || optimize_size)) 11201 { 11202 if (get_attr_mode (insn) == MODE_SI) 11203 return "sal{l}\t%0"; 11204 else 11205 return "sal{b}\t%0"; 11206 } 11207 else 11208 { 11209 if (get_attr_mode (insn) == MODE_SI) 11210 return "sal{l}\t{%2, %k0|%k0, %2}"; 11211 else 11212 return "sal{b}\t{%2, %0|%0, %2}"; 11213 } 11214 } 11215} 11216 [(set (attr "type") 11217 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11218 (const_int 0)) 11219 (match_operand 0 "register_operand" "")) 11220 (match_operand 2 "const1_operand" "")) 11221 (const_string "alu") 11222 ] 11223 (const_string "ishift"))) 11224 (set_attr "mode" "QI,SI")]) 11225 11226;; This pattern can't accept a variable shift count, since shifts by 11227;; zero don't affect the flags. We assume that shifts by constant 11228;; zero are optimized away. 11229(define_insn "*ashlqi3_cmp" 11230 [(set (reg FLAGS_REG) 11231 (compare 11232 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11233 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11234 (const_int 0))) 11235 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11236 (ashift:QI (match_dup 1) (match_dup 2)))] 11237 "ix86_match_ccmode (insn, CCGOCmode) 11238 && ix86_binary_operator_ok (ASHIFT, QImode, operands) 11239 && (optimize_size 11240 || !TARGET_PARTIAL_FLAG_REG_STALL 11241 || (operands[2] == const1_rtx 11242 && (TARGET_SHIFT1 11243 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 11244{ 11245 switch (get_attr_type (insn)) 11246 { 11247 case TYPE_ALU: 11248 gcc_assert (operands[2] == const1_rtx); 11249 return "add{b}\t{%0, %0|%0, %0}"; 11250 11251 default: 11252 if (REG_P (operands[2])) 11253 return "sal{b}\t{%b2, %0|%0, %b2}"; 11254 else if (operands[2] == const1_rtx 11255 && (TARGET_SHIFT1 || optimize_size)) 11256 return "sal{b}\t%0"; 11257 else 11258 return "sal{b}\t{%2, %0|%0, %2}"; 11259 } 11260} 11261 [(set (attr "type") 11262 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11263 (const_int 0)) 11264 (match_operand 0 "register_operand" "")) 11265 (match_operand 2 "const1_operand" "")) 11266 (const_string "alu") 11267 ] 11268 (const_string "ishift"))) 11269 (set_attr "mode" "QI")]) 11270 11271(define_insn "*ashlqi3_cconly" 11272 [(set (reg FLAGS_REG) 11273 (compare 11274 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11275 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11276 (const_int 0))) 11277 (clobber (match_scratch:QI 0 "=q"))] 11278 "ix86_match_ccmode (insn, CCGOCmode) 11279 && ix86_binary_operator_ok (ASHIFT, QImode, operands) 11280 && (optimize_size 11281 || !TARGET_PARTIAL_FLAG_REG_STALL 11282 || (operands[2] == const1_rtx 11283 && (TARGET_SHIFT1 11284 || TARGET_DOUBLE_WITH_ADD)))" 11285{ 11286 switch (get_attr_type (insn)) 11287 { 11288 case TYPE_ALU: 11289 gcc_assert (operands[2] == const1_rtx); 11290 return "add{b}\t{%0, %0|%0, %0}"; 11291 11292 default: 11293 if (REG_P (operands[2])) 11294 return "sal{b}\t{%b2, %0|%0, %b2}"; 11295 else if (operands[2] == const1_rtx 11296 && (TARGET_SHIFT1 || optimize_size)) 11297 return "sal{b}\t%0"; 11298 else 11299 return "sal{b}\t{%2, %0|%0, %2}"; 11300 } 11301} 11302 [(set (attr "type") 11303 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11304 (const_int 0)) 11305 (match_operand 0 "register_operand" "")) 11306 (match_operand 2 "const1_operand" "")) 11307 (const_string "alu") 11308 ] 11309 (const_string "ishift"))) 11310 (set_attr "mode" "QI")]) 11311 11312;; See comment above `ashldi3' about how this works. 11313 11314(define_expand "ashrti3" 11315 [(parallel [(set (match_operand:TI 0 "register_operand" "") 11316 (ashiftrt:TI (match_operand:TI 1 "register_operand" "") 11317 (match_operand:QI 2 "nonmemory_operand" ""))) 11318 (clobber (reg:CC FLAGS_REG))])] 11319 "TARGET_64BIT" 11320{ 11321 if (! immediate_operand (operands[2], QImode)) 11322 { 11323 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2])); 11324 DONE; 11325 } 11326 ix86_expand_binary_operator (ASHIFTRT, TImode, operands); 11327 DONE; 11328}) 11329 11330(define_insn "ashrti3_1" 11331 [(set (match_operand:TI 0 "register_operand" "=r") 11332 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0") 11333 (match_operand:QI 2 "register_operand" "c"))) 11334 (clobber (match_scratch:DI 3 "=&r")) 11335 (clobber (reg:CC FLAGS_REG))] 11336 "TARGET_64BIT" 11337 "#" 11338 [(set_attr "type" "multi")]) 11339 11340(define_insn "*ashrti3_2" 11341 [(set (match_operand:TI 0 "register_operand" "=r") 11342 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0") 11343 (match_operand:QI 2 "immediate_operand" "O"))) 11344 (clobber (reg:CC FLAGS_REG))] 11345 "TARGET_64BIT" 11346 "#" 11347 [(set_attr "type" "multi")]) 11348 11349(define_split 11350 [(set (match_operand:TI 0 "register_operand" "") 11351 (ashiftrt:TI (match_operand:TI 1 "register_operand" "") 11352 (match_operand:QI 2 "register_operand" ""))) 11353 (clobber (match_scratch:DI 3 "")) 11354 (clobber (reg:CC FLAGS_REG))] 11355 "TARGET_64BIT && reload_completed" 11356 [(const_int 0)] 11357 "ix86_split_ashr (operands, operands[3], TImode); DONE;") 11358 11359(define_split 11360 [(set (match_operand:TI 0 "register_operand" "") 11361 (ashiftrt:TI (match_operand:TI 1 "register_operand" "") 11362 (match_operand:QI 2 "immediate_operand" ""))) 11363 (clobber (reg:CC FLAGS_REG))] 11364 "TARGET_64BIT && reload_completed" 11365 [(const_int 0)] 11366 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;") 11367 11368(define_insn "x86_64_shrd" 11369 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m") 11370 (ior:DI (ashiftrt:DI (match_dup 0) 11371 (match_operand:QI 2 "nonmemory_operand" "J,c")) 11372 (ashift:DI (match_operand:DI 1 "register_operand" "r,r") 11373 (minus:QI (const_int 64) (match_dup 2))))) 11374 (clobber (reg:CC FLAGS_REG))] 11375 "TARGET_64BIT" 11376 "@ 11377 shrd{q}\t{%2, %1, %0|%0, %1, %2} 11378 shrd{q}\t{%s2%1, %0|%0, %1, %2}" 11379 [(set_attr "type" "ishift") 11380 (set_attr "prefix_0f" "1") 11381 (set_attr "mode" "DI") 11382 (set_attr "athlon_decode" "vector") 11383 (set_attr "amdfam10_decode" "vector")]) 11384 11385(define_expand "ashrdi3" 11386 [(set (match_operand:DI 0 "shiftdi_operand" "") 11387 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") 11388 (match_operand:QI 2 "nonmemory_operand" "")))] 11389 "" 11390 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;") 11391 11392(define_insn "*ashrdi3_63_rex64" 11393 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm") 11394 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0") 11395 (match_operand:DI 2 "const_int_operand" "i,i"))) 11396 (clobber (reg:CC FLAGS_REG))] 11397 "TARGET_64BIT && INTVAL (operands[2]) == 63 11398 && (TARGET_USE_CLTD || optimize_size) 11399 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11400 "@ 11401 {cqto|cqo} 11402 sar{q}\t{%2, %0|%0, %2}" 11403 [(set_attr "type" "imovx,ishift") 11404 (set_attr "prefix_0f" "0,*") 11405 (set_attr "length_immediate" "0,*") 11406 (set_attr "modrm" "0,1") 11407 (set_attr "mode" "DI")]) 11408 11409(define_insn "*ashrdi3_1_one_bit_rex64" 11410 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11411 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11412 (match_operand:QI 2 "const1_operand" ""))) 11413 (clobber (reg:CC FLAGS_REG))] 11414 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands) 11415 && (TARGET_SHIFT1 || optimize_size)" 11416 "sar{q}\t%0" 11417 [(set_attr "type" "ishift") 11418 (set (attr "length") 11419 (if_then_else (match_operand:DI 0 "register_operand" "") 11420 (const_string "2") 11421 (const_string "*")))]) 11422 11423(define_insn "*ashrdi3_1_rex64" 11424 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 11425 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 11426 (match_operand:QI 2 "nonmemory_operand" "J,c"))) 11427 (clobber (reg:CC FLAGS_REG))] 11428 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11429 "@ 11430 sar{q}\t{%2, %0|%0, %2} 11431 sar{q}\t{%b2, %0|%0, %b2}" 11432 [(set_attr "type" "ishift") 11433 (set_attr "mode" "DI")]) 11434 11435;; This pattern can't accept a variable shift count, since shifts by 11436;; zero don't affect the flags. We assume that shifts by constant 11437;; zero are optimized away. 11438(define_insn "*ashrdi3_one_bit_cmp_rex64" 11439 [(set (reg FLAGS_REG) 11440 (compare 11441 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11442 (match_operand:QI 2 "const1_operand" "")) 11443 (const_int 0))) 11444 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11445 (ashiftrt:DI (match_dup 1) (match_dup 2)))] 11446 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11447 && (TARGET_SHIFT1 || optimize_size) 11448 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11449 "sar{q}\t%0" 11450 [(set_attr "type" "ishift") 11451 (set (attr "length") 11452 (if_then_else (match_operand:DI 0 "register_operand" "") 11453 (const_string "2") 11454 (const_string "*")))]) 11455 11456(define_insn "*ashrdi3_one_bit_cconly_rex64" 11457 [(set (reg FLAGS_REG) 11458 (compare 11459 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11460 (match_operand:QI 2 "const1_operand" "")) 11461 (const_int 0))) 11462 (clobber (match_scratch:DI 0 "=r"))] 11463 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11464 && (TARGET_SHIFT1 || optimize_size) 11465 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11466 "sar{q}\t%0" 11467 [(set_attr "type" "ishift") 11468 (set_attr "length" "2")]) 11469 11470;; This pattern can't accept a variable shift count, since shifts by 11471;; zero don't affect the flags. We assume that shifts by constant 11472;; zero are optimized away. 11473(define_insn "*ashrdi3_cmp_rex64" 11474 [(set (reg FLAGS_REG) 11475 (compare 11476 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11477 (match_operand:QI 2 "const_int_operand" "n")) 11478 (const_int 0))) 11479 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11480 (ashiftrt:DI (match_dup 1) (match_dup 2)))] 11481 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11482 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands) 11483 && (optimize_size 11484 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11485 "sar{q}\t{%2, %0|%0, %2}" 11486 [(set_attr "type" "ishift") 11487 (set_attr "mode" "DI")]) 11488 11489(define_insn "*ashrdi3_cconly_rex64" 11490 [(set (reg FLAGS_REG) 11491 (compare 11492 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11493 (match_operand:QI 2 "const_int_operand" "n")) 11494 (const_int 0))) 11495 (clobber (match_scratch:DI 0 "=r"))] 11496 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11497 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands) 11498 && (optimize_size 11499 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11500 "sar{q}\t{%2, %0|%0, %2}" 11501 [(set_attr "type" "ishift") 11502 (set_attr "mode" "DI")]) 11503 11504(define_insn "*ashrdi3_1" 11505 [(set (match_operand:DI 0 "register_operand" "=r") 11506 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") 11507 (match_operand:QI 2 "nonmemory_operand" "Jc"))) 11508 (clobber (reg:CC FLAGS_REG))] 11509 "!TARGET_64BIT" 11510 "#" 11511 [(set_attr "type" "multi")]) 11512 11513;; By default we don't ask for a scratch register, because when DImode 11514;; values are manipulated, registers are already at a premium. But if 11515;; we have one handy, we won't turn it away. 11516(define_peephole2 11517 [(match_scratch:SI 3 "r") 11518 (parallel [(set (match_operand:DI 0 "register_operand" "") 11519 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 11520 (match_operand:QI 2 "nonmemory_operand" ""))) 11521 (clobber (reg:CC FLAGS_REG))]) 11522 (match_dup 3)] 11523 "!TARGET_64BIT && TARGET_CMOVE" 11524 [(const_int 0)] 11525 "ix86_split_ashr (operands, operands[3], DImode); DONE;") 11526 11527(define_split 11528 [(set (match_operand:DI 0 "register_operand" "") 11529 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 11530 (match_operand:QI 2 "nonmemory_operand" ""))) 11531 (clobber (reg:CC FLAGS_REG))] 11532 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) 11533 ? flow2_completed : reload_completed)" 11534 [(const_int 0)] 11535 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;") 11536 11537(define_insn "x86_shrd_1" 11538 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m") 11539 (ior:SI (ashiftrt:SI (match_dup 0) 11540 (match_operand:QI 2 "nonmemory_operand" "I,c")) 11541 (ashift:SI (match_operand:SI 1 "register_operand" "r,r") 11542 (minus:QI (const_int 32) (match_dup 2))))) 11543 (clobber (reg:CC FLAGS_REG))] 11544 "" 11545 "@ 11546 shrd{l}\t{%2, %1, %0|%0, %1, %2} 11547 shrd{l}\t{%s2%1, %0|%0, %1, %2}" 11548 [(set_attr "type" "ishift") 11549 (set_attr "prefix_0f" "1") 11550 (set_attr "pent_pair" "np") 11551 (set_attr "mode" "SI")]) 11552 11553(define_expand "x86_shift_adj_3" 11554 [(use (match_operand:SI 0 "register_operand" "")) 11555 (use (match_operand:SI 1 "register_operand" "")) 11556 (use (match_operand:QI 2 "register_operand" ""))] 11557 "" 11558{ 11559 rtx label = gen_label_rtx (); 11560 rtx tmp; 11561 11562 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32))); 11563 11564 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 11565 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 11566 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 11567 gen_rtx_LABEL_REF (VOIDmode, label), 11568 pc_rtx); 11569 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 11570 JUMP_LABEL (tmp) = label; 11571 11572 emit_move_insn (operands[0], operands[1]); 11573 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31))); 11574 11575 emit_label (label); 11576 LABEL_NUSES (label) = 1; 11577 11578 DONE; 11579}) 11580 11581(define_insn "ashrsi3_31" 11582 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm") 11583 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0") 11584 (match_operand:SI 2 "const_int_operand" "i,i"))) 11585 (clobber (reg:CC FLAGS_REG))] 11586 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size) 11587 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11588 "@ 11589 {cltd|cdq} 11590 sar{l}\t{%2, %0|%0, %2}" 11591 [(set_attr "type" "imovx,ishift") 11592 (set_attr "prefix_0f" "0,*") 11593 (set_attr "length_immediate" "0,*") 11594 (set_attr "modrm" "0,1") 11595 (set_attr "mode" "SI")]) 11596 11597(define_insn "*ashrsi3_31_zext" 11598 [(set (match_operand:DI 0 "register_operand" "=*d,r") 11599 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0") 11600 (match_operand:SI 2 "const_int_operand" "i,i")))) 11601 (clobber (reg:CC FLAGS_REG))] 11602 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size) 11603 && INTVAL (operands[2]) == 31 11604 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11605 "@ 11606 {cltd|cdq} 11607 sar{l}\t{%2, %k0|%k0, %2}" 11608 [(set_attr "type" "imovx,ishift") 11609 (set_attr "prefix_0f" "0,*") 11610 (set_attr "length_immediate" "0,*") 11611 (set_attr "modrm" "0,1") 11612 (set_attr "mode" "SI")]) 11613 11614(define_expand "ashrsi3" 11615 [(set (match_operand:SI 0 "nonimmediate_operand" "") 11616 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") 11617 (match_operand:QI 2 "nonmemory_operand" ""))) 11618 (clobber (reg:CC FLAGS_REG))] 11619 "" 11620 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;") 11621 11622(define_insn "*ashrsi3_1_one_bit" 11623 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 11624 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11625 (match_operand:QI 2 "const1_operand" ""))) 11626 (clobber (reg:CC FLAGS_REG))] 11627 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11628 && (TARGET_SHIFT1 || optimize_size)" 11629 "sar{l}\t%0" 11630 [(set_attr "type" "ishift") 11631 (set (attr "length") 11632 (if_then_else (match_operand:SI 0 "register_operand" "") 11633 (const_string "2") 11634 (const_string "*")))]) 11635 11636(define_insn "*ashrsi3_1_one_bit_zext" 11637 [(set (match_operand:DI 0 "register_operand" "=r") 11638 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 11639 (match_operand:QI 2 "const1_operand" "")))) 11640 (clobber (reg:CC FLAGS_REG))] 11641 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11642 && (TARGET_SHIFT1 || optimize_size)" 11643 "sar{l}\t%k0" 11644 [(set_attr "type" "ishift") 11645 (set_attr "length" "2")]) 11646 11647(define_insn "*ashrsi3_1" 11648 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 11649 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 11650 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 11651 (clobber (reg:CC FLAGS_REG))] 11652 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11653 "@ 11654 sar{l}\t{%2, %0|%0, %2} 11655 sar{l}\t{%b2, %0|%0, %b2}" 11656 [(set_attr "type" "ishift") 11657 (set_attr "mode" "SI")]) 11658 11659(define_insn "*ashrsi3_1_zext" 11660 [(set (match_operand:DI 0 "register_operand" "=r,r") 11661 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0") 11662 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 11663 (clobber (reg:CC FLAGS_REG))] 11664 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11665 "@ 11666 sar{l}\t{%2, %k0|%k0, %2} 11667 sar{l}\t{%b2, %k0|%k0, %b2}" 11668 [(set_attr "type" "ishift") 11669 (set_attr "mode" "SI")]) 11670 11671;; This pattern can't accept a variable shift count, since shifts by 11672;; zero don't affect the flags. We assume that shifts by constant 11673;; zero are optimized away. 11674(define_insn "*ashrsi3_one_bit_cmp" 11675 [(set (reg FLAGS_REG) 11676 (compare 11677 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11678 (match_operand:QI 2 "const1_operand" "")) 11679 (const_int 0))) 11680 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 11681 (ashiftrt:SI (match_dup 1) (match_dup 2)))] 11682 "ix86_match_ccmode (insn, CCGOCmode) 11683 && (TARGET_SHIFT1 || optimize_size) 11684 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11685 "sar{l}\t%0" 11686 [(set_attr "type" "ishift") 11687 (set (attr "length") 11688 (if_then_else (match_operand:SI 0 "register_operand" "") 11689 (const_string "2") 11690 (const_string "*")))]) 11691 11692(define_insn "*ashrsi3_one_bit_cconly" 11693 [(set (reg FLAGS_REG) 11694 (compare 11695 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11696 (match_operand:QI 2 "const1_operand" "")) 11697 (const_int 0))) 11698 (clobber (match_scratch:SI 0 "=r"))] 11699 "ix86_match_ccmode (insn, CCGOCmode) 11700 && (TARGET_SHIFT1 || optimize_size) 11701 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11702 "sar{l}\t%0" 11703 [(set_attr "type" "ishift") 11704 (set_attr "length" "2")]) 11705 11706(define_insn "*ashrsi3_one_bit_cmp_zext" 11707 [(set (reg FLAGS_REG) 11708 (compare 11709 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 11710 (match_operand:QI 2 "const1_operand" "")) 11711 (const_int 0))) 11712 (set (match_operand:DI 0 "register_operand" "=r") 11713 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))] 11714 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 11715 && (TARGET_SHIFT1 || optimize_size) 11716 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11717 "sar{l}\t%k0" 11718 [(set_attr "type" "ishift") 11719 (set_attr "length" "2")]) 11720 11721;; This pattern can't accept a variable shift count, since shifts by 11722;; zero don't affect the flags. We assume that shifts by constant 11723;; zero are optimized away. 11724(define_insn "*ashrsi3_cmp" 11725 [(set (reg FLAGS_REG) 11726 (compare 11727 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11728 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11729 (const_int 0))) 11730 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 11731 (ashiftrt:SI (match_dup 1) (match_dup 2)))] 11732 "ix86_match_ccmode (insn, CCGOCmode) 11733 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11734 && (optimize_size 11735 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11736 "sar{l}\t{%2, %0|%0, %2}" 11737 [(set_attr "type" "ishift") 11738 (set_attr "mode" "SI")]) 11739 11740(define_insn "*ashrsi3_cconly" 11741 [(set (reg FLAGS_REG) 11742 (compare 11743 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11744 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11745 (const_int 0))) 11746 (clobber (match_scratch:SI 0 "=r"))] 11747 "ix86_match_ccmode (insn, CCGOCmode) 11748 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11749 && (optimize_size 11750 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11751 "sar{l}\t{%2, %0|%0, %2}" 11752 [(set_attr "type" "ishift") 11753 (set_attr "mode" "SI")]) 11754 11755(define_insn "*ashrsi3_cmp_zext" 11756 [(set (reg FLAGS_REG) 11757 (compare 11758 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 11759 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11760 (const_int 0))) 11761 (set (match_operand:DI 0 "register_operand" "=r") 11762 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))] 11763 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11764 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11765 && (optimize_size 11766 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11767 "sar{l}\t{%2, %k0|%k0, %2}" 11768 [(set_attr "type" "ishift") 11769 (set_attr "mode" "SI")]) 11770 11771(define_expand "ashrhi3" 11772 [(set (match_operand:HI 0 "nonimmediate_operand" "") 11773 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") 11774 (match_operand:QI 2 "nonmemory_operand" ""))) 11775 (clobber (reg:CC FLAGS_REG))] 11776 "TARGET_HIMODE_MATH" 11777 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;") 11778 11779(define_insn "*ashrhi3_1_one_bit" 11780 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 11781 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11782 (match_operand:QI 2 "const1_operand" ""))) 11783 (clobber (reg:CC FLAGS_REG))] 11784 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands) 11785 && (TARGET_SHIFT1 || optimize_size)" 11786 "sar{w}\t%0" 11787 [(set_attr "type" "ishift") 11788 (set (attr "length") 11789 (if_then_else (match_operand 0 "register_operand" "") 11790 (const_string "2") 11791 (const_string "*")))]) 11792 11793(define_insn "*ashrhi3_1" 11794 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 11795 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 11796 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 11797 (clobber (reg:CC FLAGS_REG))] 11798 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" 11799 "@ 11800 sar{w}\t{%2, %0|%0, %2} 11801 sar{w}\t{%b2, %0|%0, %b2}" 11802 [(set_attr "type" "ishift") 11803 (set_attr "mode" "HI")]) 11804 11805;; This pattern can't accept a variable shift count, since shifts by 11806;; zero don't affect the flags. We assume that shifts by constant 11807;; zero are optimized away. 11808(define_insn "*ashrhi3_one_bit_cmp" 11809 [(set (reg FLAGS_REG) 11810 (compare 11811 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11812 (match_operand:QI 2 "const1_operand" "")) 11813 (const_int 0))) 11814 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 11815 (ashiftrt:HI (match_dup 1) (match_dup 2)))] 11816 "ix86_match_ccmode (insn, CCGOCmode) 11817 && (TARGET_SHIFT1 || optimize_size) 11818 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" 11819 "sar{w}\t%0" 11820 [(set_attr "type" "ishift") 11821 (set (attr "length") 11822 (if_then_else (match_operand 0 "register_operand" "") 11823 (const_string "2") 11824 (const_string "*")))]) 11825 11826(define_insn "*ashrhi3_one_bit_cconly" 11827 [(set (reg FLAGS_REG) 11828 (compare 11829 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11830 (match_operand:QI 2 "const1_operand" "")) 11831 (const_int 0))) 11832 (clobber (match_scratch:HI 0 "=r"))] 11833 "ix86_match_ccmode (insn, CCGOCmode) 11834 && (TARGET_SHIFT1 || optimize_size) 11835 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" 11836 "sar{w}\t%0" 11837 [(set_attr "type" "ishift") 11838 (set_attr "length" "2")]) 11839 11840;; This pattern can't accept a variable shift count, since shifts by 11841;; zero don't affect the flags. We assume that shifts by constant 11842;; zero are optimized away. 11843(define_insn "*ashrhi3_cmp" 11844 [(set (reg FLAGS_REG) 11845 (compare 11846 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11847 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11848 (const_int 0))) 11849 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 11850 (ashiftrt:HI (match_dup 1) (match_dup 2)))] 11851 "ix86_match_ccmode (insn, CCGOCmode) 11852 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands) 11853 && (optimize_size 11854 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11855 "sar{w}\t{%2, %0|%0, %2}" 11856 [(set_attr "type" "ishift") 11857 (set_attr "mode" "HI")]) 11858 11859(define_insn "*ashrhi3_cconly" 11860 [(set (reg FLAGS_REG) 11861 (compare 11862 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11863 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11864 (const_int 0))) 11865 (clobber (match_scratch:HI 0 "=r"))] 11866 "ix86_match_ccmode (insn, CCGOCmode) 11867 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands) 11868 && (optimize_size 11869 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11870 "sar{w}\t{%2, %0|%0, %2}" 11871 [(set_attr "type" "ishift") 11872 (set_attr "mode" "HI")]) 11873 11874(define_expand "ashrqi3" 11875 [(set (match_operand:QI 0 "nonimmediate_operand" "") 11876 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "") 11877 (match_operand:QI 2 "nonmemory_operand" ""))) 11878 (clobber (reg:CC FLAGS_REG))] 11879 "TARGET_QIMODE_MATH" 11880 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;") 11881 11882(define_insn "*ashrqi3_1_one_bit" 11883 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11884 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11885 (match_operand:QI 2 "const1_operand" ""))) 11886 (clobber (reg:CC FLAGS_REG))] 11887 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 11888 && (TARGET_SHIFT1 || optimize_size)" 11889 "sar{b}\t%0" 11890 [(set_attr "type" "ishift") 11891 (set (attr "length") 11892 (if_then_else (match_operand 0 "register_operand" "") 11893 (const_string "2") 11894 (const_string "*")))]) 11895 11896(define_insn "*ashrqi3_1_one_bit_slp" 11897 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 11898 (ashiftrt:QI (match_dup 0) 11899 (match_operand:QI 1 "const1_operand" ""))) 11900 (clobber (reg:CC FLAGS_REG))] 11901 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 11902 && (! TARGET_PARTIAL_REG_STALL || optimize_size) 11903 && (TARGET_SHIFT1 || optimize_size)" 11904 "sar{b}\t%0" 11905 [(set_attr "type" "ishift1") 11906 (set (attr "length") 11907 (if_then_else (match_operand 0 "register_operand" "") 11908 (const_string "2") 11909 (const_string "*")))]) 11910 11911(define_insn "*ashrqi3_1" 11912 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 11913 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 11914 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 11915 (clobber (reg:CC FLAGS_REG))] 11916 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" 11917 "@ 11918 sar{b}\t{%2, %0|%0, %2} 11919 sar{b}\t{%b2, %0|%0, %b2}" 11920 [(set_attr "type" "ishift") 11921 (set_attr "mode" "QI")]) 11922 11923(define_insn "*ashrqi3_1_slp" 11924 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 11925 (ashiftrt:QI (match_dup 0) 11926 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 11927 (clobber (reg:CC FLAGS_REG))] 11928 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 11929 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 11930 "@ 11931 sar{b}\t{%1, %0|%0, %1} 11932 sar{b}\t{%b1, %0|%0, %b1}" 11933 [(set_attr "type" "ishift1") 11934 (set_attr "mode" "QI")]) 11935 11936;; This pattern can't accept a variable shift count, since shifts by 11937;; zero don't affect the flags. We assume that shifts by constant 11938;; zero are optimized away. 11939(define_insn "*ashrqi3_one_bit_cmp" 11940 [(set (reg FLAGS_REG) 11941 (compare 11942 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11943 (match_operand:QI 2 "const1_operand" "I")) 11944 (const_int 0))) 11945 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11946 (ashiftrt:QI (match_dup 1) (match_dup 2)))] 11947 "ix86_match_ccmode (insn, CCGOCmode) 11948 && (TARGET_SHIFT1 || optimize_size) 11949 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" 11950 "sar{b}\t%0" 11951 [(set_attr "type" "ishift") 11952 (set (attr "length") 11953 (if_then_else (match_operand 0 "register_operand" "") 11954 (const_string "2") 11955 (const_string "*")))]) 11956 11957(define_insn "*ashrqi3_one_bit_cconly" 11958 [(set (reg FLAGS_REG) 11959 (compare 11960 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11961 (match_operand:QI 2 "const1_operand" "I")) 11962 (const_int 0))) 11963 (clobber (match_scratch:QI 0 "=q"))] 11964 "ix86_match_ccmode (insn, CCGOCmode) 11965 && (TARGET_SHIFT1 || optimize_size) 11966 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" 11967 "sar{b}\t%0" 11968 [(set_attr "type" "ishift") 11969 (set_attr "length" "2")]) 11970 11971;; This pattern can't accept a variable shift count, since shifts by 11972;; zero don't affect the flags. We assume that shifts by constant 11973;; zero are optimized away. 11974(define_insn "*ashrqi3_cmp" 11975 [(set (reg FLAGS_REG) 11976 (compare 11977 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11978 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11979 (const_int 0))) 11980 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11981 (ashiftrt:QI (match_dup 1) (match_dup 2)))] 11982 "ix86_match_ccmode (insn, CCGOCmode) 11983 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 11984 && (optimize_size 11985 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11986 "sar{b}\t{%2, %0|%0, %2}" 11987 [(set_attr "type" "ishift") 11988 (set_attr "mode" "QI")]) 11989 11990(define_insn "*ashrqi3_cconly" 11991 [(set (reg FLAGS_REG) 11992 (compare 11993 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11994 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11995 (const_int 0))) 11996 (clobber (match_scratch:QI 0 "=q"))] 11997 "ix86_match_ccmode (insn, CCGOCmode) 11998 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 11999 && (optimize_size 12000 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12001 "sar{b}\t{%2, %0|%0, %2}" 12002 [(set_attr "type" "ishift") 12003 (set_attr "mode" "QI")]) 12004 12005 12006;; Logical shift instructions 12007 12008;; See comment above `ashldi3' about how this works. 12009 12010(define_expand "lshrti3" 12011 [(parallel [(set (match_operand:TI 0 "register_operand" "") 12012 (lshiftrt:TI (match_operand:TI 1 "register_operand" "") 12013 (match_operand:QI 2 "nonmemory_operand" ""))) 12014 (clobber (reg:CC FLAGS_REG))])] 12015 "TARGET_64BIT" 12016{ 12017 if (! immediate_operand (operands[2], QImode)) 12018 { 12019 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2])); 12020 DONE; 12021 } 12022 ix86_expand_binary_operator (LSHIFTRT, TImode, operands); 12023 DONE; 12024}) 12025 12026(define_insn "lshrti3_1" 12027 [(set (match_operand:TI 0 "register_operand" "=r") 12028 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0") 12029 (match_operand:QI 2 "register_operand" "c"))) 12030 (clobber (match_scratch:DI 3 "=&r")) 12031 (clobber (reg:CC FLAGS_REG))] 12032 "TARGET_64BIT" 12033 "#" 12034 [(set_attr "type" "multi")]) 12035 12036(define_insn "*lshrti3_2" 12037 [(set (match_operand:TI 0 "register_operand" "=r") 12038 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0") 12039 (match_operand:QI 2 "immediate_operand" "O"))) 12040 (clobber (reg:CC FLAGS_REG))] 12041 "TARGET_64BIT" 12042 "#" 12043 [(set_attr "type" "multi")]) 12044 12045(define_split 12046 [(set (match_operand:TI 0 "register_operand" "") 12047 (lshiftrt:TI (match_operand:TI 1 "register_operand" "") 12048 (match_operand:QI 2 "register_operand" ""))) 12049 (clobber (match_scratch:DI 3 "")) 12050 (clobber (reg:CC FLAGS_REG))] 12051 "TARGET_64BIT && reload_completed" 12052 [(const_int 0)] 12053 "ix86_split_lshr (operands, operands[3], TImode); DONE;") 12054 12055(define_split 12056 [(set (match_operand:TI 0 "register_operand" "") 12057 (lshiftrt:TI (match_operand:TI 1 "register_operand" "") 12058 (match_operand:QI 2 "immediate_operand" ""))) 12059 (clobber (reg:CC FLAGS_REG))] 12060 "TARGET_64BIT && reload_completed" 12061 [(const_int 0)] 12062 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;") 12063 12064(define_expand "lshrdi3" 12065 [(set (match_operand:DI 0 "shiftdi_operand" "") 12066 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") 12067 (match_operand:QI 2 "nonmemory_operand" "")))] 12068 "" 12069 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;") 12070 12071(define_insn "*lshrdi3_1_one_bit_rex64" 12072 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12073 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12074 (match_operand:QI 2 "const1_operand" ""))) 12075 (clobber (reg:CC FLAGS_REG))] 12076 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12077 && (TARGET_SHIFT1 || optimize_size)" 12078 "shr{q}\t%0" 12079 [(set_attr "type" "ishift") 12080 (set (attr "length") 12081 (if_then_else (match_operand:DI 0 "register_operand" "") 12082 (const_string "2") 12083 (const_string "*")))]) 12084 12085(define_insn "*lshrdi3_1_rex64" 12086 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 12087 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 12088 (match_operand:QI 2 "nonmemory_operand" "J,c"))) 12089 (clobber (reg:CC FLAGS_REG))] 12090 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12091 "@ 12092 shr{q}\t{%2, %0|%0, %2} 12093 shr{q}\t{%b2, %0|%0, %b2}" 12094 [(set_attr "type" "ishift") 12095 (set_attr "mode" "DI")]) 12096 12097;; This pattern can't accept a variable shift count, since shifts by 12098;; zero don't affect the flags. We assume that shifts by constant 12099;; zero are optimized away. 12100(define_insn "*lshrdi3_cmp_one_bit_rex64" 12101 [(set (reg FLAGS_REG) 12102 (compare 12103 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12104 (match_operand:QI 2 "const1_operand" "")) 12105 (const_int 0))) 12106 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12107 (lshiftrt:DI (match_dup 1) (match_dup 2)))] 12108 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12109 && (TARGET_SHIFT1 || optimize_size) 12110 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12111 "shr{q}\t%0" 12112 [(set_attr "type" "ishift") 12113 (set (attr "length") 12114 (if_then_else (match_operand:DI 0 "register_operand" "") 12115 (const_string "2") 12116 (const_string "*")))]) 12117 12118(define_insn "*lshrdi3_cconly_one_bit_rex64" 12119 [(set (reg FLAGS_REG) 12120 (compare 12121 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12122 (match_operand:QI 2 "const1_operand" "")) 12123 (const_int 0))) 12124 (clobber (match_scratch:DI 0 "=r"))] 12125 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12126 && (TARGET_SHIFT1 || optimize_size) 12127 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12128 "shr{q}\t%0" 12129 [(set_attr "type" "ishift") 12130 (set_attr "length" "2")]) 12131 12132;; This pattern can't accept a variable shift count, since shifts by 12133;; zero don't affect the flags. We assume that shifts by constant 12134;; zero are optimized away. 12135(define_insn "*lshrdi3_cmp_rex64" 12136 [(set (reg FLAGS_REG) 12137 (compare 12138 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12139 (match_operand:QI 2 "const_int_operand" "e")) 12140 (const_int 0))) 12141 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12142 (lshiftrt:DI (match_dup 1) (match_dup 2)))] 12143 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12144 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12145 && (optimize_size 12146 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12147 "shr{q}\t{%2, %0|%0, %2}" 12148 [(set_attr "type" "ishift") 12149 (set_attr "mode" "DI")]) 12150 12151(define_insn "*lshrdi3_cconly_rex64" 12152 [(set (reg FLAGS_REG) 12153 (compare 12154 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12155 (match_operand:QI 2 "const_int_operand" "e")) 12156 (const_int 0))) 12157 (clobber (match_scratch:DI 0 "=r"))] 12158 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12159 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12160 && (optimize_size 12161 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12162 "shr{q}\t{%2, %0|%0, %2}" 12163 [(set_attr "type" "ishift") 12164 (set_attr "mode" "DI")]) 12165 12166(define_insn "*lshrdi3_1" 12167 [(set (match_operand:DI 0 "register_operand" "=r") 12168 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") 12169 (match_operand:QI 2 "nonmemory_operand" "Jc"))) 12170 (clobber (reg:CC FLAGS_REG))] 12171 "!TARGET_64BIT" 12172 "#" 12173 [(set_attr "type" "multi")]) 12174 12175;; By default we don't ask for a scratch register, because when DImode 12176;; values are manipulated, registers are already at a premium. But if 12177;; we have one handy, we won't turn it away. 12178(define_peephole2 12179 [(match_scratch:SI 3 "r") 12180 (parallel [(set (match_operand:DI 0 "register_operand" "") 12181 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 12182 (match_operand:QI 2 "nonmemory_operand" ""))) 12183 (clobber (reg:CC FLAGS_REG))]) 12184 (match_dup 3)] 12185 "!TARGET_64BIT && TARGET_CMOVE" 12186 [(const_int 0)] 12187 "ix86_split_lshr (operands, operands[3], DImode); DONE;") 12188 12189(define_split 12190 [(set (match_operand:DI 0 "register_operand" "") 12191 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 12192 (match_operand:QI 2 "nonmemory_operand" ""))) 12193 (clobber (reg:CC FLAGS_REG))] 12194 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) 12195 ? flow2_completed : reload_completed)" 12196 [(const_int 0)] 12197 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;") 12198 12199(define_expand "lshrsi3" 12200 [(set (match_operand:SI 0 "nonimmediate_operand" "") 12201 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") 12202 (match_operand:QI 2 "nonmemory_operand" ""))) 12203 (clobber (reg:CC FLAGS_REG))] 12204 "" 12205 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;") 12206 12207(define_insn "*lshrsi3_1_one_bit" 12208 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12209 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12210 (match_operand:QI 2 "const1_operand" ""))) 12211 (clobber (reg:CC FLAGS_REG))] 12212 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12213 && (TARGET_SHIFT1 || optimize_size)" 12214 "shr{l}\t%0" 12215 [(set_attr "type" "ishift") 12216 (set (attr "length") 12217 (if_then_else (match_operand:SI 0 "register_operand" "") 12218 (const_string "2") 12219 (const_string "*")))]) 12220 12221(define_insn "*lshrsi3_1_one_bit_zext" 12222 [(set (match_operand:DI 0 "register_operand" "=r") 12223 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0")) 12224 (match_operand:QI 2 "const1_operand" ""))) 12225 (clobber (reg:CC FLAGS_REG))] 12226 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12227 && (TARGET_SHIFT1 || optimize_size)" 12228 "shr{l}\t%k0" 12229 [(set_attr "type" "ishift") 12230 (set_attr "length" "2")]) 12231 12232(define_insn "*lshrsi3_1" 12233 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 12234 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12235 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12236 (clobber (reg:CC FLAGS_REG))] 12237 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12238 "@ 12239 shr{l}\t{%2, %0|%0, %2} 12240 shr{l}\t{%b2, %0|%0, %b2}" 12241 [(set_attr "type" "ishift") 12242 (set_attr "mode" "SI")]) 12243 12244(define_insn "*lshrsi3_1_zext" 12245 [(set (match_operand:DI 0 "register_operand" "=r,r") 12246 (zero_extend:DI 12247 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12248 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 12249 (clobber (reg:CC FLAGS_REG))] 12250 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12251 "@ 12252 shr{l}\t{%2, %k0|%k0, %2} 12253 shr{l}\t{%b2, %k0|%k0, %b2}" 12254 [(set_attr "type" "ishift") 12255 (set_attr "mode" "SI")]) 12256 12257;; This pattern can't accept a variable shift count, since shifts by 12258;; zero don't affect the flags. We assume that shifts by constant 12259;; zero are optimized away. 12260(define_insn "*lshrsi3_one_bit_cmp" 12261 [(set (reg FLAGS_REG) 12262 (compare 12263 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12264 (match_operand:QI 2 "const1_operand" "")) 12265 (const_int 0))) 12266 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12267 (lshiftrt:SI (match_dup 1) (match_dup 2)))] 12268 "ix86_match_ccmode (insn, CCGOCmode) 12269 && (TARGET_SHIFT1 || optimize_size) 12270 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12271 "shr{l}\t%0" 12272 [(set_attr "type" "ishift") 12273 (set (attr "length") 12274 (if_then_else (match_operand:SI 0 "register_operand" "") 12275 (const_string "2") 12276 (const_string "*")))]) 12277 12278(define_insn "*lshrsi3_one_bit_cconly" 12279 [(set (reg FLAGS_REG) 12280 (compare 12281 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12282 (match_operand:QI 2 "const1_operand" "")) 12283 (const_int 0))) 12284 (clobber (match_scratch:SI 0 "=r"))] 12285 "ix86_match_ccmode (insn, CCGOCmode) 12286 && (TARGET_SHIFT1 || optimize_size) 12287 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12288 "shr{l}\t%0" 12289 [(set_attr "type" "ishift") 12290 (set_attr "length" "2")]) 12291 12292(define_insn "*lshrsi3_cmp_one_bit_zext" 12293 [(set (reg FLAGS_REG) 12294 (compare 12295 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 12296 (match_operand:QI 2 "const1_operand" "")) 12297 (const_int 0))) 12298 (set (match_operand:DI 0 "register_operand" "=r") 12299 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 12300 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12301 && (TARGET_SHIFT1 || optimize_size) 12302 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12303 "shr{l}\t%k0" 12304 [(set_attr "type" "ishift") 12305 (set_attr "length" "2")]) 12306 12307;; This pattern can't accept a variable shift count, since shifts by 12308;; zero don't affect the flags. We assume that shifts by constant 12309;; zero are optimized away. 12310(define_insn "*lshrsi3_cmp" 12311 [(set (reg FLAGS_REG) 12312 (compare 12313 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12314 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12315 (const_int 0))) 12316 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12317 (lshiftrt:SI (match_dup 1) (match_dup 2)))] 12318 "ix86_match_ccmode (insn, CCGOCmode) 12319 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12320 && (optimize_size 12321 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12322 "shr{l}\t{%2, %0|%0, %2}" 12323 [(set_attr "type" "ishift") 12324 (set_attr "mode" "SI")]) 12325 12326(define_insn "*lshrsi3_cconly" 12327 [(set (reg FLAGS_REG) 12328 (compare 12329 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12330 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12331 (const_int 0))) 12332 (clobber (match_scratch:SI 0 "=r"))] 12333 "ix86_match_ccmode (insn, CCGOCmode) 12334 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12335 && (optimize_size 12336 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12337 "shr{l}\t{%2, %0|%0, %2}" 12338 [(set_attr "type" "ishift") 12339 (set_attr "mode" "SI")]) 12340 12341(define_insn "*lshrsi3_cmp_zext" 12342 [(set (reg FLAGS_REG) 12343 (compare 12344 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 12345 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12346 (const_int 0))) 12347 (set (match_operand:DI 0 "register_operand" "=r") 12348 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 12349 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12350 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12351 && (optimize_size 12352 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12353 "shr{l}\t{%2, %k0|%k0, %2}" 12354 [(set_attr "type" "ishift") 12355 (set_attr "mode" "SI")]) 12356 12357(define_expand "lshrhi3" 12358 [(set (match_operand:HI 0 "nonimmediate_operand" "") 12359 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") 12360 (match_operand:QI 2 "nonmemory_operand" ""))) 12361 (clobber (reg:CC FLAGS_REG))] 12362 "TARGET_HIMODE_MATH" 12363 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;") 12364 12365(define_insn "*lshrhi3_1_one_bit" 12366 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12367 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12368 (match_operand:QI 2 "const1_operand" ""))) 12369 (clobber (reg:CC FLAGS_REG))] 12370 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12371 && (TARGET_SHIFT1 || optimize_size)" 12372 "shr{w}\t%0" 12373 [(set_attr "type" "ishift") 12374 (set (attr "length") 12375 (if_then_else (match_operand 0 "register_operand" "") 12376 (const_string "2") 12377 (const_string "*")))]) 12378 12379(define_insn "*lshrhi3_1" 12380 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 12381 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 12382 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12383 (clobber (reg:CC FLAGS_REG))] 12384 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12385 "@ 12386 shr{w}\t{%2, %0|%0, %2} 12387 shr{w}\t{%b2, %0|%0, %b2}" 12388 [(set_attr "type" "ishift") 12389 (set_attr "mode" "HI")]) 12390 12391;; This pattern can't accept a variable shift count, since shifts by 12392;; zero don't affect the flags. We assume that shifts by constant 12393;; zero are optimized away. 12394(define_insn "*lshrhi3_one_bit_cmp" 12395 [(set (reg FLAGS_REG) 12396 (compare 12397 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12398 (match_operand:QI 2 "const1_operand" "")) 12399 (const_int 0))) 12400 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12401 (lshiftrt:HI (match_dup 1) (match_dup 2)))] 12402 "ix86_match_ccmode (insn, CCGOCmode) 12403 && (TARGET_SHIFT1 || optimize_size) 12404 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12405 "shr{w}\t%0" 12406 [(set_attr "type" "ishift") 12407 (set (attr "length") 12408 (if_then_else (match_operand:SI 0 "register_operand" "") 12409 (const_string "2") 12410 (const_string "*")))]) 12411 12412(define_insn "*lshrhi3_one_bit_cconly" 12413 [(set (reg FLAGS_REG) 12414 (compare 12415 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12416 (match_operand:QI 2 "const1_operand" "")) 12417 (const_int 0))) 12418 (clobber (match_scratch:HI 0 "=r"))] 12419 "ix86_match_ccmode (insn, CCGOCmode) 12420 && (TARGET_SHIFT1 || optimize_size) 12421 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12422 "shr{w}\t%0" 12423 [(set_attr "type" "ishift") 12424 (set_attr "length" "2")]) 12425 12426;; This pattern can't accept a variable shift count, since shifts by 12427;; zero don't affect the flags. We assume that shifts by constant 12428;; zero are optimized away. 12429(define_insn "*lshrhi3_cmp" 12430 [(set (reg FLAGS_REG) 12431 (compare 12432 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12433 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12434 (const_int 0))) 12435 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12436 (lshiftrt:HI (match_dup 1) (match_dup 2)))] 12437 "ix86_match_ccmode (insn, CCGOCmode) 12438 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12439 && (optimize_size 12440 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12441 "shr{w}\t{%2, %0|%0, %2}" 12442 [(set_attr "type" "ishift") 12443 (set_attr "mode" "HI")]) 12444 12445(define_insn "*lshrhi3_cconly" 12446 [(set (reg FLAGS_REG) 12447 (compare 12448 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12449 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12450 (const_int 0))) 12451 (clobber (match_scratch:HI 0 "=r"))] 12452 "ix86_match_ccmode (insn, CCGOCmode) 12453 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12454 && (optimize_size 12455 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12456 "shr{w}\t{%2, %0|%0, %2}" 12457 [(set_attr "type" "ishift") 12458 (set_attr "mode" "HI")]) 12459 12460(define_expand "lshrqi3" 12461 [(set (match_operand:QI 0 "nonimmediate_operand" "") 12462 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "") 12463 (match_operand:QI 2 "nonmemory_operand" ""))) 12464 (clobber (reg:CC FLAGS_REG))] 12465 "TARGET_QIMODE_MATH" 12466 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;") 12467 12468(define_insn "*lshrqi3_1_one_bit" 12469 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12470 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12471 (match_operand:QI 2 "const1_operand" ""))) 12472 (clobber (reg:CC FLAGS_REG))] 12473 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands) 12474 && (TARGET_SHIFT1 || optimize_size)" 12475 "shr{b}\t%0" 12476 [(set_attr "type" "ishift") 12477 (set (attr "length") 12478 (if_then_else (match_operand 0 "register_operand" "") 12479 (const_string "2") 12480 (const_string "*")))]) 12481 12482(define_insn "*lshrqi3_1_one_bit_slp" 12483 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 12484 (lshiftrt:QI (match_dup 0) 12485 (match_operand:QI 1 "const1_operand" ""))) 12486 (clobber (reg:CC FLAGS_REG))] 12487 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12488 && (TARGET_SHIFT1 || optimize_size)" 12489 "shr{b}\t%0" 12490 [(set_attr "type" "ishift1") 12491 (set (attr "length") 12492 (if_then_else (match_operand 0 "register_operand" "") 12493 (const_string "2") 12494 (const_string "*")))]) 12495 12496(define_insn "*lshrqi3_1" 12497 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 12498 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 12499 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12500 (clobber (reg:CC FLAGS_REG))] 12501 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" 12502 "@ 12503 shr{b}\t{%2, %0|%0, %2} 12504 shr{b}\t{%b2, %0|%0, %b2}" 12505 [(set_attr "type" "ishift") 12506 (set_attr "mode" "QI")]) 12507 12508(define_insn "*lshrqi3_1_slp" 12509 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 12510 (lshiftrt:QI (match_dup 0) 12511 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 12512 (clobber (reg:CC FLAGS_REG))] 12513 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12514 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 12515 "@ 12516 shr{b}\t{%1, %0|%0, %1} 12517 shr{b}\t{%b1, %0|%0, %b1}" 12518 [(set_attr "type" "ishift1") 12519 (set_attr "mode" "QI")]) 12520 12521;; This pattern can't accept a variable shift count, since shifts by 12522;; zero don't affect the flags. We assume that shifts by constant 12523;; zero are optimized away. 12524(define_insn "*lshrqi2_one_bit_cmp" 12525 [(set (reg FLAGS_REG) 12526 (compare 12527 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12528 (match_operand:QI 2 "const1_operand" "")) 12529 (const_int 0))) 12530 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12531 (lshiftrt:QI (match_dup 1) (match_dup 2)))] 12532 "ix86_match_ccmode (insn, CCGOCmode) 12533 && (TARGET_SHIFT1 || optimize_size) 12534 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" 12535 "shr{b}\t%0" 12536 [(set_attr "type" "ishift") 12537 (set (attr "length") 12538 (if_then_else (match_operand:SI 0 "register_operand" "") 12539 (const_string "2") 12540 (const_string "*")))]) 12541 12542(define_insn "*lshrqi2_one_bit_cconly" 12543 [(set (reg FLAGS_REG) 12544 (compare 12545 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12546 (match_operand:QI 2 "const1_operand" "")) 12547 (const_int 0))) 12548 (clobber (match_scratch:QI 0 "=q"))] 12549 "ix86_match_ccmode (insn, CCGOCmode) 12550 && (TARGET_SHIFT1 || optimize_size) 12551 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" 12552 "shr{b}\t%0" 12553 [(set_attr "type" "ishift") 12554 (set_attr "length" "2")]) 12555 12556;; This pattern can't accept a variable shift count, since shifts by 12557;; zero don't affect the flags. We assume that shifts by constant 12558;; zero are optimized away. 12559(define_insn "*lshrqi2_cmp" 12560 [(set (reg FLAGS_REG) 12561 (compare 12562 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12563 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12564 (const_int 0))) 12565 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12566 (lshiftrt:QI (match_dup 1) (match_dup 2)))] 12567 "ix86_match_ccmode (insn, CCGOCmode) 12568 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands) 12569 && (optimize_size 12570 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12571 "shr{b}\t{%2, %0|%0, %2}" 12572 [(set_attr "type" "ishift") 12573 (set_attr "mode" "QI")]) 12574 12575(define_insn "*lshrqi2_cconly" 12576 [(set (reg FLAGS_REG) 12577 (compare 12578 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12579 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12580 (const_int 0))) 12581 (clobber (match_scratch:QI 0 "=q"))] 12582 "ix86_match_ccmode (insn, CCGOCmode) 12583 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands) 12584 && (optimize_size 12585 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12586 "shr{b}\t{%2, %0|%0, %2}" 12587 [(set_attr "type" "ishift") 12588 (set_attr "mode" "QI")]) 12589 12590;; Rotate instructions 12591 12592(define_expand "rotldi3" 12593 [(set (match_operand:DI 0 "shiftdi_operand" "") 12594 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "") 12595 (match_operand:QI 2 "nonmemory_operand" ""))) 12596 (clobber (reg:CC FLAGS_REG))] 12597 "" 12598{ 12599 if (TARGET_64BIT) 12600 { 12601 ix86_expand_binary_operator (ROTATE, DImode, operands); 12602 DONE; 12603 } 12604 if (!const_1_to_31_operand (operands[2], VOIDmode)) 12605 FAIL; 12606 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2])); 12607 DONE; 12608}) 12609 12610;; Implement rotation using two double-precision shift instructions 12611;; and a scratch register. 12612(define_insn_and_split "ix86_rotldi3" 12613 [(set (match_operand:DI 0 "register_operand" "=r") 12614 (rotate:DI (match_operand:DI 1 "register_operand" "0") 12615 (match_operand:QI 2 "const_1_to_31_operand" "I"))) 12616 (clobber (reg:CC FLAGS_REG)) 12617 (clobber (match_scratch:SI 3 "=&r"))] 12618 "!TARGET_64BIT" 12619 "" 12620 "&& reload_completed" 12621 [(set (match_dup 3) (match_dup 4)) 12622 (parallel 12623 [(set (match_dup 4) 12624 (ior:SI (ashift:SI (match_dup 4) (match_dup 2)) 12625 (lshiftrt:SI (match_dup 5) 12626 (minus:QI (const_int 32) (match_dup 2))))) 12627 (clobber (reg:CC FLAGS_REG))]) 12628 (parallel 12629 [(set (match_dup 5) 12630 (ior:SI (ashift:SI (match_dup 5) (match_dup 2)) 12631 (lshiftrt:SI (match_dup 3) 12632 (minus:QI (const_int 32) (match_dup 2))))) 12633 (clobber (reg:CC FLAGS_REG))])] 12634 "split_di (operands, 1, operands + 4, operands + 5);") 12635 12636(define_insn "*rotlsi3_1_one_bit_rex64" 12637 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12638 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12639 (match_operand:QI 2 "const1_operand" ""))) 12640 (clobber (reg:CC FLAGS_REG))] 12641 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands) 12642 && (TARGET_SHIFT1 || optimize_size)" 12643 "rol{q}\t%0" 12644 [(set_attr "type" "rotate") 12645 (set (attr "length") 12646 (if_then_else (match_operand:DI 0 "register_operand" "") 12647 (const_string "2") 12648 (const_string "*")))]) 12649 12650(define_insn "*rotldi3_1_rex64" 12651 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 12652 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 12653 (match_operand:QI 2 "nonmemory_operand" "e,c"))) 12654 (clobber (reg:CC FLAGS_REG))] 12655 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)" 12656 "@ 12657 rol{q}\t{%2, %0|%0, %2} 12658 rol{q}\t{%b2, %0|%0, %b2}" 12659 [(set_attr "type" "rotate") 12660 (set_attr "mode" "DI")]) 12661 12662(define_expand "rotlsi3" 12663 [(set (match_operand:SI 0 "nonimmediate_operand" "") 12664 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "") 12665 (match_operand:QI 2 "nonmemory_operand" ""))) 12666 (clobber (reg:CC FLAGS_REG))] 12667 "" 12668 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;") 12669 12670(define_insn "*rotlsi3_1_one_bit" 12671 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12672 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12673 (match_operand:QI 2 "const1_operand" ""))) 12674 (clobber (reg:CC FLAGS_REG))] 12675 "ix86_binary_operator_ok (ROTATE, SImode, operands) 12676 && (TARGET_SHIFT1 || optimize_size)" 12677 "rol{l}\t%0" 12678 [(set_attr "type" "rotate") 12679 (set (attr "length") 12680 (if_then_else (match_operand:SI 0 "register_operand" "") 12681 (const_string "2") 12682 (const_string "*")))]) 12683 12684(define_insn "*rotlsi3_1_one_bit_zext" 12685 [(set (match_operand:DI 0 "register_operand" "=r") 12686 (zero_extend:DI 12687 (rotate:SI (match_operand:SI 1 "register_operand" "0") 12688 (match_operand:QI 2 "const1_operand" "")))) 12689 (clobber (reg:CC FLAGS_REG))] 12690 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands) 12691 && (TARGET_SHIFT1 || optimize_size)" 12692 "rol{l}\t%k0" 12693 [(set_attr "type" "rotate") 12694 (set_attr "length" "2")]) 12695 12696(define_insn "*rotlsi3_1" 12697 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 12698 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12699 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12700 (clobber (reg:CC FLAGS_REG))] 12701 "ix86_binary_operator_ok (ROTATE, SImode, operands)" 12702 "@ 12703 rol{l}\t{%2, %0|%0, %2} 12704 rol{l}\t{%b2, %0|%0, %b2}" 12705 [(set_attr "type" "rotate") 12706 (set_attr "mode" "SI")]) 12707 12708(define_insn "*rotlsi3_1_zext" 12709 [(set (match_operand:DI 0 "register_operand" "=r,r") 12710 (zero_extend:DI 12711 (rotate:SI (match_operand:SI 1 "register_operand" "0,0") 12712 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 12713 (clobber (reg:CC FLAGS_REG))] 12714 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)" 12715 "@ 12716 rol{l}\t{%2, %k0|%k0, %2} 12717 rol{l}\t{%b2, %k0|%k0, %b2}" 12718 [(set_attr "type" "rotate") 12719 (set_attr "mode" "SI")]) 12720 12721(define_expand "rotlhi3" 12722 [(set (match_operand:HI 0 "nonimmediate_operand" "") 12723 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "") 12724 (match_operand:QI 2 "nonmemory_operand" ""))) 12725 (clobber (reg:CC FLAGS_REG))] 12726 "TARGET_HIMODE_MATH" 12727 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;") 12728 12729(define_insn "*rotlhi3_1_one_bit" 12730 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12731 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12732 (match_operand:QI 2 "const1_operand" ""))) 12733 (clobber (reg:CC FLAGS_REG))] 12734 "ix86_binary_operator_ok (ROTATE, HImode, operands) 12735 && (TARGET_SHIFT1 || optimize_size)" 12736 "rol{w}\t%0" 12737 [(set_attr "type" "rotate") 12738 (set (attr "length") 12739 (if_then_else (match_operand 0 "register_operand" "") 12740 (const_string "2") 12741 (const_string "*")))]) 12742 12743(define_insn "*rotlhi3_1" 12744 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 12745 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 12746 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12747 (clobber (reg:CC FLAGS_REG))] 12748 "ix86_binary_operator_ok (ROTATE, HImode, operands)" 12749 "@ 12750 rol{w}\t{%2, %0|%0, %2} 12751 rol{w}\t{%b2, %0|%0, %b2}" 12752 [(set_attr "type" "rotate") 12753 (set_attr "mode" "HI")]) 12754 12755(define_expand "rotlqi3" 12756 [(set (match_operand:QI 0 "nonimmediate_operand" "") 12757 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "") 12758 (match_operand:QI 2 "nonmemory_operand" ""))) 12759 (clobber (reg:CC FLAGS_REG))] 12760 "TARGET_QIMODE_MATH" 12761 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;") 12762 12763(define_insn "*rotlqi3_1_one_bit_slp" 12764 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 12765 (rotate:QI (match_dup 0) 12766 (match_operand:QI 1 "const1_operand" ""))) 12767 (clobber (reg:CC FLAGS_REG))] 12768 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12769 && (TARGET_SHIFT1 || optimize_size)" 12770 "rol{b}\t%0" 12771 [(set_attr "type" "rotate1") 12772 (set (attr "length") 12773 (if_then_else (match_operand 0 "register_operand" "") 12774 (const_string "2") 12775 (const_string "*")))]) 12776 12777(define_insn "*rotlqi3_1_one_bit" 12778 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12779 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12780 (match_operand:QI 2 "const1_operand" ""))) 12781 (clobber (reg:CC FLAGS_REG))] 12782 "ix86_binary_operator_ok (ROTATE, QImode, operands) 12783 && (TARGET_SHIFT1 || optimize_size)" 12784 "rol{b}\t%0" 12785 [(set_attr "type" "rotate") 12786 (set (attr "length") 12787 (if_then_else (match_operand 0 "register_operand" "") 12788 (const_string "2") 12789 (const_string "*")))]) 12790 12791(define_insn "*rotlqi3_1_slp" 12792 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 12793 (rotate:QI (match_dup 0) 12794 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 12795 (clobber (reg:CC FLAGS_REG))] 12796 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12797 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 12798 "@ 12799 rol{b}\t{%1, %0|%0, %1} 12800 rol{b}\t{%b1, %0|%0, %b1}" 12801 [(set_attr "type" "rotate1") 12802 (set_attr "mode" "QI")]) 12803 12804(define_insn "*rotlqi3_1" 12805 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 12806 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 12807 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12808 (clobber (reg:CC FLAGS_REG))] 12809 "ix86_binary_operator_ok (ROTATE, QImode, operands)" 12810 "@ 12811 rol{b}\t{%2, %0|%0, %2} 12812 rol{b}\t{%b2, %0|%0, %b2}" 12813 [(set_attr "type" "rotate") 12814 (set_attr "mode" "QI")]) 12815 12816(define_expand "rotrdi3" 12817 [(set (match_operand:DI 0 "shiftdi_operand" "") 12818 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "") 12819 (match_operand:QI 2 "nonmemory_operand" ""))) 12820 (clobber (reg:CC FLAGS_REG))] 12821 "" 12822{ 12823 if (TARGET_64BIT) 12824 { 12825 ix86_expand_binary_operator (ROTATERT, DImode, operands); 12826 DONE; 12827 } 12828 if (!const_1_to_31_operand (operands[2], VOIDmode)) 12829 FAIL; 12830 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2])); 12831 DONE; 12832}) 12833 12834;; Implement rotation using two double-precision shift instructions 12835;; and a scratch register. 12836(define_insn_and_split "ix86_rotrdi3" 12837 [(set (match_operand:DI 0 "register_operand" "=r") 12838 (rotatert:DI (match_operand:DI 1 "register_operand" "0") 12839 (match_operand:QI 2 "const_1_to_31_operand" "I"))) 12840 (clobber (reg:CC FLAGS_REG)) 12841 (clobber (match_scratch:SI 3 "=&r"))] 12842 "!TARGET_64BIT" 12843 "" 12844 "&& reload_completed" 12845 [(set (match_dup 3) (match_dup 4)) 12846 (parallel 12847 [(set (match_dup 4) 12848 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2)) 12849 (ashift:SI (match_dup 5) 12850 (minus:QI (const_int 32) (match_dup 2))))) 12851 (clobber (reg:CC FLAGS_REG))]) 12852 (parallel 12853 [(set (match_dup 5) 12854 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2)) 12855 (ashift:SI (match_dup 3) 12856 (minus:QI (const_int 32) (match_dup 2))))) 12857 (clobber (reg:CC FLAGS_REG))])] 12858 "split_di (operands, 1, operands + 4, operands + 5);") 12859 12860(define_insn "*rotrdi3_1_one_bit_rex64" 12861 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12862 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12863 (match_operand:QI 2 "const1_operand" ""))) 12864 (clobber (reg:CC FLAGS_REG))] 12865 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands) 12866 && (TARGET_SHIFT1 || optimize_size)" 12867 "ror{q}\t%0" 12868 [(set_attr "type" "rotate") 12869 (set (attr "length") 12870 (if_then_else (match_operand:DI 0 "register_operand" "") 12871 (const_string "2") 12872 (const_string "*")))]) 12873 12874(define_insn "*rotrdi3_1_rex64" 12875 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 12876 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 12877 (match_operand:QI 2 "nonmemory_operand" "J,c"))) 12878 (clobber (reg:CC FLAGS_REG))] 12879 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)" 12880 "@ 12881 ror{q}\t{%2, %0|%0, %2} 12882 ror{q}\t{%b2, %0|%0, %b2}" 12883 [(set_attr "type" "rotate") 12884 (set_attr "mode" "DI")]) 12885 12886(define_expand "rotrsi3" 12887 [(set (match_operand:SI 0 "nonimmediate_operand" "") 12888 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "") 12889 (match_operand:QI 2 "nonmemory_operand" ""))) 12890 (clobber (reg:CC FLAGS_REG))] 12891 "" 12892 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;") 12893 12894(define_insn "*rotrsi3_1_one_bit" 12895 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12896 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12897 (match_operand:QI 2 "const1_operand" ""))) 12898 (clobber (reg:CC FLAGS_REG))] 12899 "ix86_binary_operator_ok (ROTATERT, SImode, operands) 12900 && (TARGET_SHIFT1 || optimize_size)" 12901 "ror{l}\t%0" 12902 [(set_attr "type" "rotate") 12903 (set (attr "length") 12904 (if_then_else (match_operand:SI 0 "register_operand" "") 12905 (const_string "2") 12906 (const_string "*")))]) 12907 12908(define_insn "*rotrsi3_1_one_bit_zext" 12909 [(set (match_operand:DI 0 "register_operand" "=r") 12910 (zero_extend:DI 12911 (rotatert:SI (match_operand:SI 1 "register_operand" "0") 12912 (match_operand:QI 2 "const1_operand" "")))) 12913 (clobber (reg:CC FLAGS_REG))] 12914 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands) 12915 && (TARGET_SHIFT1 || optimize_size)" 12916 "ror{l}\t%k0" 12917 [(set_attr "type" "rotate") 12918 (set (attr "length") 12919 (if_then_else (match_operand:SI 0 "register_operand" "") 12920 (const_string "2") 12921 (const_string "*")))]) 12922 12923(define_insn "*rotrsi3_1" 12924 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 12925 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12926 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12927 (clobber (reg:CC FLAGS_REG))] 12928 "ix86_binary_operator_ok (ROTATERT, SImode, operands)" 12929 "@ 12930 ror{l}\t{%2, %0|%0, %2} 12931 ror{l}\t{%b2, %0|%0, %b2}" 12932 [(set_attr "type" "rotate") 12933 (set_attr "mode" "SI")]) 12934 12935(define_insn "*rotrsi3_1_zext" 12936 [(set (match_operand:DI 0 "register_operand" "=r,r") 12937 (zero_extend:DI 12938 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0") 12939 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 12940 (clobber (reg:CC FLAGS_REG))] 12941 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)" 12942 "@ 12943 ror{l}\t{%2, %k0|%k0, %2} 12944 ror{l}\t{%b2, %k0|%k0, %b2}" 12945 [(set_attr "type" "rotate") 12946 (set_attr "mode" "SI")]) 12947 12948(define_expand "rotrhi3" 12949 [(set (match_operand:HI 0 "nonimmediate_operand" "") 12950 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "") 12951 (match_operand:QI 2 "nonmemory_operand" ""))) 12952 (clobber (reg:CC FLAGS_REG))] 12953 "TARGET_HIMODE_MATH" 12954 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;") 12955 12956(define_insn "*rotrhi3_one_bit" 12957 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12958 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12959 (match_operand:QI 2 "const1_operand" ""))) 12960 (clobber (reg:CC FLAGS_REG))] 12961 "ix86_binary_operator_ok (ROTATERT, HImode, operands) 12962 && (TARGET_SHIFT1 || optimize_size)" 12963 "ror{w}\t%0" 12964 [(set_attr "type" "rotate") 12965 (set (attr "length") 12966 (if_then_else (match_operand 0 "register_operand" "") 12967 (const_string "2") 12968 (const_string "*")))]) 12969 12970(define_insn "*rotrhi3" 12971 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 12972 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 12973 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12974 (clobber (reg:CC FLAGS_REG))] 12975 "ix86_binary_operator_ok (ROTATERT, HImode, operands)" 12976 "@ 12977 ror{w}\t{%2, %0|%0, %2} 12978 ror{w}\t{%b2, %0|%0, %b2}" 12979 [(set_attr "type" "rotate") 12980 (set_attr "mode" "HI")]) 12981 12982(define_expand "rotrqi3" 12983 [(set (match_operand:QI 0 "nonimmediate_operand" "") 12984 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "") 12985 (match_operand:QI 2 "nonmemory_operand" ""))) 12986 (clobber (reg:CC FLAGS_REG))] 12987 "TARGET_QIMODE_MATH" 12988 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;") 12989 12990(define_insn "*rotrqi3_1_one_bit" 12991 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12992 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12993 (match_operand:QI 2 "const1_operand" ""))) 12994 (clobber (reg:CC FLAGS_REG))] 12995 "ix86_binary_operator_ok (ROTATERT, QImode, operands) 12996 && (TARGET_SHIFT1 || optimize_size)" 12997 "ror{b}\t%0" 12998 [(set_attr "type" "rotate") 12999 (set (attr "length") 13000 (if_then_else (match_operand 0 "register_operand" "") 13001 (const_string "2") 13002 (const_string "*")))]) 13003 13004(define_insn "*rotrqi3_1_one_bit_slp" 13005 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 13006 (rotatert:QI (match_dup 0) 13007 (match_operand:QI 1 "const1_operand" ""))) 13008 (clobber (reg:CC FLAGS_REG))] 13009 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 13010 && (TARGET_SHIFT1 || optimize_size)" 13011 "ror{b}\t%0" 13012 [(set_attr "type" "rotate1") 13013 (set (attr "length") 13014 (if_then_else (match_operand 0 "register_operand" "") 13015 (const_string "2") 13016 (const_string "*")))]) 13017 13018(define_insn "*rotrqi3_1" 13019 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 13020 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 13021 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 13022 (clobber (reg:CC FLAGS_REG))] 13023 "ix86_binary_operator_ok (ROTATERT, QImode, operands)" 13024 "@ 13025 ror{b}\t{%2, %0|%0, %2} 13026 ror{b}\t{%b2, %0|%0, %b2}" 13027 [(set_attr "type" "rotate") 13028 (set_attr "mode" "QI")]) 13029 13030(define_insn "*rotrqi3_1_slp" 13031 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 13032 (rotatert:QI (match_dup 0) 13033 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 13034 (clobber (reg:CC FLAGS_REG))] 13035 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 13036 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 13037 "@ 13038 ror{b}\t{%1, %0|%0, %1} 13039 ror{b}\t{%b1, %0|%0, %b1}" 13040 [(set_attr "type" "rotate1") 13041 (set_attr "mode" "QI")]) 13042 13043;; Bit set / bit test instructions 13044 13045(define_expand "extv" 13046 [(set (match_operand:SI 0 "register_operand" "") 13047 (sign_extract:SI (match_operand:SI 1 "register_operand" "") 13048 (match_operand:SI 2 "const8_operand" "") 13049 (match_operand:SI 3 "const8_operand" "")))] 13050 "" 13051{ 13052 /* Handle extractions from %ah et al. */ 13053 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 13054 FAIL; 13055 13056 /* From mips.md: extract_bit_field doesn't verify that our source 13057 matches the predicate, so check it again here. */ 13058 if (! ext_register_operand (operands[1], VOIDmode)) 13059 FAIL; 13060}) 13061 13062(define_expand "extzv" 13063 [(set (match_operand:SI 0 "register_operand" "") 13064 (zero_extract:SI (match_operand 1 "ext_register_operand" "") 13065 (match_operand:SI 2 "const8_operand" "") 13066 (match_operand:SI 3 "const8_operand" "")))] 13067 "" 13068{ 13069 /* Handle extractions from %ah et al. */ 13070 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 13071 FAIL; 13072 13073 /* From mips.md: extract_bit_field doesn't verify that our source 13074 matches the predicate, so check it again here. */ 13075 if (! ext_register_operand (operands[1], VOIDmode)) 13076 FAIL; 13077}) 13078 13079(define_expand "insv" 13080 [(set (zero_extract (match_operand 0 "ext_register_operand" "") 13081 (match_operand 1 "const8_operand" "") 13082 (match_operand 2 "const8_operand" "")) 13083 (match_operand 3 "register_operand" ""))] 13084 "" 13085{ 13086 /* Handle insertions to %ah et al. */ 13087 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8) 13088 FAIL; 13089 13090 /* From mips.md: insert_bit_field doesn't verify that our source 13091 matches the predicate, so check it again here. */ 13092 if (! ext_register_operand (operands[0], VOIDmode)) 13093 FAIL; 13094 13095 if (TARGET_64BIT) 13096 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3])); 13097 else 13098 emit_insn (gen_movsi_insv_1 (operands[0], operands[3])); 13099 13100 DONE; 13101}) 13102 13103;; %%% bts, btr, btc, bt. 13104;; In general these instructions are *slow* when applied to memory, 13105;; since they enforce atomic operation. When applied to registers, 13106;; it depends on the cpu implementation. They're never faster than 13107;; the corresponding and/ior/xor operations, so with 32-bit there's 13108;; no point. But in 64-bit, we can't hold the relevant immediates 13109;; within the instruction itself, so operating on bits in the high 13110;; 32-bits of a register becomes easier. 13111;; 13112;; These are slow on Nocona, but fast on Athlon64. We do require the use 13113;; of btrq and btcq for corner cases of post-reload expansion of absdf and 13114;; negdf respectively, so they can never be disabled entirely. 13115 13116(define_insn "*btsq" 13117 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 13118 (const_int 1) 13119 (match_operand:DI 1 "const_0_to_63_operand" "")) 13120 (const_int 1)) 13121 (clobber (reg:CC FLAGS_REG))] 13122 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 13123 "bts{q} %1,%0" 13124 [(set_attr "type" "alu1")]) 13125 13126(define_insn "*btrq" 13127 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 13128 (const_int 1) 13129 (match_operand:DI 1 "const_0_to_63_operand" "")) 13130 (const_int 0)) 13131 (clobber (reg:CC FLAGS_REG))] 13132 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 13133 "btr{q} %1,%0" 13134 [(set_attr "type" "alu1")]) 13135 13136(define_insn "*btcq" 13137 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 13138 (const_int 1) 13139 (match_operand:DI 1 "const_0_to_63_operand" "")) 13140 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) 13141 (clobber (reg:CC FLAGS_REG))] 13142 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 13143 "btc{q} %1,%0" 13144 [(set_attr "type" "alu1")]) 13145 13146;; Allow Nocona to avoid these instructions if a register is available. 13147 13148(define_peephole2 13149 [(match_scratch:DI 2 "r") 13150 (parallel [(set (zero_extract:DI 13151 (match_operand:DI 0 "register_operand" "") 13152 (const_int 1) 13153 (match_operand:DI 1 "const_0_to_63_operand" "")) 13154 (const_int 1)) 13155 (clobber (reg:CC FLAGS_REG))])] 13156 "TARGET_64BIT && !TARGET_USE_BT" 13157 [(const_int 0)] 13158{ 13159 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 13160 rtx op1; 13161 13162 if (HOST_BITS_PER_WIDE_INT >= 64) 13163 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13164 else if (i < HOST_BITS_PER_WIDE_INT) 13165 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13166 else 13167 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 13168 13169 op1 = immed_double_const (lo, hi, DImode); 13170 if (i >= 31) 13171 { 13172 emit_move_insn (operands[2], op1); 13173 op1 = operands[2]; 13174 } 13175 13176 emit_insn (gen_iordi3 (operands[0], operands[0], op1)); 13177 DONE; 13178}) 13179 13180(define_peephole2 13181 [(match_scratch:DI 2 "r") 13182 (parallel [(set (zero_extract:DI 13183 (match_operand:DI 0 "register_operand" "") 13184 (const_int 1) 13185 (match_operand:DI 1 "const_0_to_63_operand" "")) 13186 (const_int 0)) 13187 (clobber (reg:CC FLAGS_REG))])] 13188 "TARGET_64BIT && !TARGET_USE_BT" 13189 [(const_int 0)] 13190{ 13191 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 13192 rtx op1; 13193 13194 if (HOST_BITS_PER_WIDE_INT >= 64) 13195 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13196 else if (i < HOST_BITS_PER_WIDE_INT) 13197 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13198 else 13199 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 13200 13201 op1 = immed_double_const (~lo, ~hi, DImode); 13202 if (i >= 32) 13203 { 13204 emit_move_insn (operands[2], op1); 13205 op1 = operands[2]; 13206 } 13207 13208 emit_insn (gen_anddi3 (operands[0], operands[0], op1)); 13209 DONE; 13210}) 13211 13212(define_peephole2 13213 [(match_scratch:DI 2 "r") 13214 (parallel [(set (zero_extract:DI 13215 (match_operand:DI 0 "register_operand" "") 13216 (const_int 1) 13217 (match_operand:DI 1 "const_0_to_63_operand" "")) 13218 (not:DI (zero_extract:DI 13219 (match_dup 0) (const_int 1) (match_dup 1)))) 13220 (clobber (reg:CC FLAGS_REG))])] 13221 "TARGET_64BIT && !TARGET_USE_BT" 13222 [(const_int 0)] 13223{ 13224 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 13225 rtx op1; 13226 13227 if (HOST_BITS_PER_WIDE_INT >= 64) 13228 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13229 else if (i < HOST_BITS_PER_WIDE_INT) 13230 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13231 else 13232 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 13233 13234 op1 = immed_double_const (lo, hi, DImode); 13235 if (i >= 31) 13236 { 13237 emit_move_insn (operands[2], op1); 13238 op1 = operands[2]; 13239 } 13240 13241 emit_insn (gen_xordi3 (operands[0], operands[0], op1)); 13242 DONE; 13243}) 13244 13245;; Store-flag instructions. 13246 13247;; For all sCOND expanders, also expand the compare or test insn that 13248;; generates cc0. Generate an equality comparison if `seq' or `sne'. 13249 13250;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way 13251;; to avoid partial register stalls. Otherwise do things the setcc+movzx 13252;; way, which can later delete the movzx if only QImode is needed. 13253 13254(define_expand "seq" 13255 [(set (match_operand:QI 0 "register_operand" "") 13256 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))] 13257 "" 13258 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;") 13259 13260(define_expand "sne" 13261 [(set (match_operand:QI 0 "register_operand" "") 13262 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))] 13263 "" 13264 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;") 13265 13266(define_expand "sgt" 13267 [(set (match_operand:QI 0 "register_operand" "") 13268 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13269 "" 13270 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;") 13271 13272(define_expand "sgtu" 13273 [(set (match_operand:QI 0 "register_operand" "") 13274 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13275 "" 13276 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;") 13277 13278(define_expand "slt" 13279 [(set (match_operand:QI 0 "register_operand" "") 13280 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13281 "" 13282 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;") 13283 13284(define_expand "sltu" 13285 [(set (match_operand:QI 0 "register_operand" "") 13286 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13287 "" 13288 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;") 13289 13290(define_expand "sge" 13291 [(set (match_operand:QI 0 "register_operand" "") 13292 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))] 13293 "" 13294 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;") 13295 13296(define_expand "sgeu" 13297 [(set (match_operand:QI 0 "register_operand" "") 13298 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13299 "" 13300 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;") 13301 13302(define_expand "sle" 13303 [(set (match_operand:QI 0 "register_operand" "") 13304 (le:QI (reg:CC FLAGS_REG) (const_int 0)))] 13305 "" 13306 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;") 13307 13308(define_expand "sleu" 13309 [(set (match_operand:QI 0 "register_operand" "") 13310 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13311 "" 13312 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;") 13313 13314(define_expand "sunordered" 13315 [(set (match_operand:QI 0 "register_operand" "") 13316 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))] 13317 "TARGET_80387 || TARGET_SSE" 13318 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;") 13319 13320(define_expand "sordered" 13321 [(set (match_operand:QI 0 "register_operand" "") 13322 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))] 13323 "TARGET_80387" 13324 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;") 13325 13326(define_expand "suneq" 13327 [(set (match_operand:QI 0 "register_operand" "") 13328 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))] 13329 "TARGET_80387 || TARGET_SSE" 13330 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;") 13331 13332(define_expand "sunge" 13333 [(set (match_operand:QI 0 "register_operand" "") 13334 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))] 13335 "TARGET_80387 || TARGET_SSE" 13336 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;") 13337 13338(define_expand "sungt" 13339 [(set (match_operand:QI 0 "register_operand" "") 13340 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13341 "TARGET_80387 || TARGET_SSE" 13342 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;") 13343 13344(define_expand "sunle" 13345 [(set (match_operand:QI 0 "register_operand" "") 13346 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))] 13347 "TARGET_80387 || TARGET_SSE" 13348 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;") 13349 13350(define_expand "sunlt" 13351 [(set (match_operand:QI 0 "register_operand" "") 13352 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13353 "TARGET_80387 || TARGET_SSE" 13354 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;") 13355 13356(define_expand "sltgt" 13357 [(set (match_operand:QI 0 "register_operand" "") 13358 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13359 "TARGET_80387 || TARGET_SSE" 13360 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;") 13361 13362(define_insn "*setcc_1" 13363 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 13364 (match_operator:QI 1 "ix86_comparison_operator" 13365 [(reg FLAGS_REG) (const_int 0)]))] 13366 "" 13367 "set%C1\t%0" 13368 [(set_attr "type" "setcc") 13369 (set_attr "mode" "QI")]) 13370 13371(define_insn "*setcc_2" 13372 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 13373 (match_operator:QI 1 "ix86_comparison_operator" 13374 [(reg FLAGS_REG) (const_int 0)]))] 13375 "" 13376 "set%C1\t%0" 13377 [(set_attr "type" "setcc") 13378 (set_attr "mode" "QI")]) 13379 13380;; In general it is not safe to assume too much about CCmode registers, 13381;; so simplify-rtx stops when it sees a second one. Under certain 13382;; conditions this is safe on x86, so help combine not create 13383;; 13384;; seta %al 13385;; testb %al, %al 13386;; sete %al 13387 13388(define_split 13389 [(set (match_operand:QI 0 "nonimmediate_operand" "") 13390 (ne:QI (match_operator 1 "ix86_comparison_operator" 13391 [(reg FLAGS_REG) (const_int 0)]) 13392 (const_int 0)))] 13393 "" 13394 [(set (match_dup 0) (match_dup 1))] 13395{ 13396 PUT_MODE (operands[1], QImode); 13397}) 13398 13399(define_split 13400 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 13401 (ne:QI (match_operator 1 "ix86_comparison_operator" 13402 [(reg FLAGS_REG) (const_int 0)]) 13403 (const_int 0)))] 13404 "" 13405 [(set (match_dup 0) (match_dup 1))] 13406{ 13407 PUT_MODE (operands[1], QImode); 13408}) 13409 13410(define_split 13411 [(set (match_operand:QI 0 "nonimmediate_operand" "") 13412 (eq:QI (match_operator 1 "ix86_comparison_operator" 13413 [(reg FLAGS_REG) (const_int 0)]) 13414 (const_int 0)))] 13415 "" 13416 [(set (match_dup 0) (match_dup 1))] 13417{ 13418 rtx new_op1 = copy_rtx (operands[1]); 13419 operands[1] = new_op1; 13420 PUT_MODE (new_op1, QImode); 13421 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), 13422 GET_MODE (XEXP (new_op1, 0)))); 13423 13424 /* Make sure that (a) the CCmode we have for the flags is strong 13425 enough for the reversed compare or (b) we have a valid FP compare. */ 13426 if (! ix86_comparison_operator (new_op1, VOIDmode)) 13427 FAIL; 13428}) 13429 13430(define_split 13431 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 13432 (eq:QI (match_operator 1 "ix86_comparison_operator" 13433 [(reg FLAGS_REG) (const_int 0)]) 13434 (const_int 0)))] 13435 "" 13436 [(set (match_dup 0) (match_dup 1))] 13437{ 13438 rtx new_op1 = copy_rtx (operands[1]); 13439 operands[1] = new_op1; 13440 PUT_MODE (new_op1, QImode); 13441 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), 13442 GET_MODE (XEXP (new_op1, 0)))); 13443 13444 /* Make sure that (a) the CCmode we have for the flags is strong 13445 enough for the reversed compare or (b) we have a valid FP compare. */ 13446 if (! ix86_comparison_operator (new_op1, VOIDmode)) 13447 FAIL; 13448}) 13449 13450;; The SSE store flag instructions saves 0 or 0xffffffff to the result. 13451;; subsequent logical operations are used to imitate conditional moves. 13452;; 0xffffffff is NaN, but not in normalized form, so we can't represent 13453;; it directly. 13454 13455(define_insn "*sse_setccsf" 13456 [(set (match_operand:SF 0 "register_operand" "=x") 13457 (match_operator:SF 1 "sse_comparison_operator" 13458 [(match_operand:SF 2 "register_operand" "0") 13459 (match_operand:SF 3 "nonimmediate_operand" "xm")]))] 13460 "TARGET_SSE" 13461 "cmp%D1ss\t{%3, %0|%0, %3}" 13462 [(set_attr "type" "ssecmp") 13463 (set_attr "mode" "SF")]) 13464 13465(define_insn "*sse_setccdf" 13466 [(set (match_operand:DF 0 "register_operand" "=Y") 13467 (match_operator:DF 1 "sse_comparison_operator" 13468 [(match_operand:DF 2 "register_operand" "0") 13469 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))] 13470 "TARGET_SSE2" 13471 "cmp%D1sd\t{%3, %0|%0, %3}" 13472 [(set_attr "type" "ssecmp") 13473 (set_attr "mode" "DF")]) 13474 13475;; Basic conditional jump instructions. 13476;; We ignore the overflow flag for signed branch instructions. 13477 13478;; For all bCOND expanders, also expand the compare or test insn that 13479;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'. 13480 13481(define_expand "beq" 13482 [(set (pc) 13483 (if_then_else (match_dup 1) 13484 (label_ref (match_operand 0 "" "")) 13485 (pc)))] 13486 "" 13487 "ix86_expand_branch (EQ, operands[0]); DONE;") 13488 13489(define_expand "bne" 13490 [(set (pc) 13491 (if_then_else (match_dup 1) 13492 (label_ref (match_operand 0 "" "")) 13493 (pc)))] 13494 "" 13495 "ix86_expand_branch (NE, operands[0]); DONE;") 13496 13497(define_expand "bgt" 13498 [(set (pc) 13499 (if_then_else (match_dup 1) 13500 (label_ref (match_operand 0 "" "")) 13501 (pc)))] 13502 "" 13503 "ix86_expand_branch (GT, operands[0]); DONE;") 13504 13505(define_expand "bgtu" 13506 [(set (pc) 13507 (if_then_else (match_dup 1) 13508 (label_ref (match_operand 0 "" "")) 13509 (pc)))] 13510 "" 13511 "ix86_expand_branch (GTU, operands[0]); DONE;") 13512 13513(define_expand "blt" 13514 [(set (pc) 13515 (if_then_else (match_dup 1) 13516 (label_ref (match_operand 0 "" "")) 13517 (pc)))] 13518 "" 13519 "ix86_expand_branch (LT, operands[0]); DONE;") 13520 13521(define_expand "bltu" 13522 [(set (pc) 13523 (if_then_else (match_dup 1) 13524 (label_ref (match_operand 0 "" "")) 13525 (pc)))] 13526 "" 13527 "ix86_expand_branch (LTU, operands[0]); DONE;") 13528 13529(define_expand "bge" 13530 [(set (pc) 13531 (if_then_else (match_dup 1) 13532 (label_ref (match_operand 0 "" "")) 13533 (pc)))] 13534 "" 13535 "ix86_expand_branch (GE, operands[0]); DONE;") 13536 13537(define_expand "bgeu" 13538 [(set (pc) 13539 (if_then_else (match_dup 1) 13540 (label_ref (match_operand 0 "" "")) 13541 (pc)))] 13542 "" 13543 "ix86_expand_branch (GEU, operands[0]); DONE;") 13544 13545(define_expand "ble" 13546 [(set (pc) 13547 (if_then_else (match_dup 1) 13548 (label_ref (match_operand 0 "" "")) 13549 (pc)))] 13550 "" 13551 "ix86_expand_branch (LE, operands[0]); DONE;") 13552 13553(define_expand "bleu" 13554 [(set (pc) 13555 (if_then_else (match_dup 1) 13556 (label_ref (match_operand 0 "" "")) 13557 (pc)))] 13558 "" 13559 "ix86_expand_branch (LEU, operands[0]); DONE;") 13560 13561(define_expand "bunordered" 13562 [(set (pc) 13563 (if_then_else (match_dup 1) 13564 (label_ref (match_operand 0 "" "")) 13565 (pc)))] 13566 "TARGET_80387 || TARGET_SSE_MATH" 13567 "ix86_expand_branch (UNORDERED, operands[0]); DONE;") 13568 13569(define_expand "bordered" 13570 [(set (pc) 13571 (if_then_else (match_dup 1) 13572 (label_ref (match_operand 0 "" "")) 13573 (pc)))] 13574 "TARGET_80387 || TARGET_SSE_MATH" 13575 "ix86_expand_branch (ORDERED, operands[0]); DONE;") 13576 13577(define_expand "buneq" 13578 [(set (pc) 13579 (if_then_else (match_dup 1) 13580 (label_ref (match_operand 0 "" "")) 13581 (pc)))] 13582 "TARGET_80387 || TARGET_SSE_MATH" 13583 "ix86_expand_branch (UNEQ, operands[0]); DONE;") 13584 13585(define_expand "bunge" 13586 [(set (pc) 13587 (if_then_else (match_dup 1) 13588 (label_ref (match_operand 0 "" "")) 13589 (pc)))] 13590 "TARGET_80387 || TARGET_SSE_MATH" 13591 "ix86_expand_branch (UNGE, operands[0]); DONE;") 13592 13593(define_expand "bungt" 13594 [(set (pc) 13595 (if_then_else (match_dup 1) 13596 (label_ref (match_operand 0 "" "")) 13597 (pc)))] 13598 "TARGET_80387 || TARGET_SSE_MATH" 13599 "ix86_expand_branch (UNGT, operands[0]); DONE;") 13600 13601(define_expand "bunle" 13602 [(set (pc) 13603 (if_then_else (match_dup 1) 13604 (label_ref (match_operand 0 "" "")) 13605 (pc)))] 13606 "TARGET_80387 || TARGET_SSE_MATH" 13607 "ix86_expand_branch (UNLE, operands[0]); DONE;") 13608 13609(define_expand "bunlt" 13610 [(set (pc) 13611 (if_then_else (match_dup 1) 13612 (label_ref (match_operand 0 "" "")) 13613 (pc)))] 13614 "TARGET_80387 || TARGET_SSE_MATH" 13615 "ix86_expand_branch (UNLT, operands[0]); DONE;") 13616 13617(define_expand "bltgt" 13618 [(set (pc) 13619 (if_then_else (match_dup 1) 13620 (label_ref (match_operand 0 "" "")) 13621 (pc)))] 13622 "TARGET_80387 || TARGET_SSE_MATH" 13623 "ix86_expand_branch (LTGT, operands[0]); DONE;") 13624 13625(define_insn "*jcc_1" 13626 [(set (pc) 13627 (if_then_else (match_operator 1 "ix86_comparison_operator" 13628 [(reg FLAGS_REG) (const_int 0)]) 13629 (label_ref (match_operand 0 "" "")) 13630 (pc)))] 13631 "" 13632 "%+j%C1\t%l0" 13633 [(set_attr "type" "ibr") 13634 (set_attr "modrm" "0") 13635 (set (attr "length") 13636 (if_then_else (and (ge (minus (match_dup 0) (pc)) 13637 (const_int -126)) 13638 (lt (minus (match_dup 0) (pc)) 13639 (const_int 128))) 13640 (const_int 2) 13641 (const_int 6)))]) 13642 13643(define_insn "*jcc_2" 13644 [(set (pc) 13645 (if_then_else (match_operator 1 "ix86_comparison_operator" 13646 [(reg FLAGS_REG) (const_int 0)]) 13647 (pc) 13648 (label_ref (match_operand 0 "" ""))))] 13649 "" 13650 "%+j%c1\t%l0" 13651 [(set_attr "type" "ibr") 13652 (set_attr "modrm" "0") 13653 (set (attr "length") 13654 (if_then_else (and (ge (minus (match_dup 0) (pc)) 13655 (const_int -126)) 13656 (lt (minus (match_dup 0) (pc)) 13657 (const_int 128))) 13658 (const_int 2) 13659 (const_int 6)))]) 13660 13661;; In general it is not safe to assume too much about CCmode registers, 13662;; so simplify-rtx stops when it sees a second one. Under certain 13663;; conditions this is safe on x86, so help combine not create 13664;; 13665;; seta %al 13666;; testb %al, %al 13667;; je Lfoo 13668 13669(define_split 13670 [(set (pc) 13671 (if_then_else (ne (match_operator 0 "ix86_comparison_operator" 13672 [(reg FLAGS_REG) (const_int 0)]) 13673 (const_int 0)) 13674 (label_ref (match_operand 1 "" "")) 13675 (pc)))] 13676 "" 13677 [(set (pc) 13678 (if_then_else (match_dup 0) 13679 (label_ref (match_dup 1)) 13680 (pc)))] 13681{ 13682 PUT_MODE (operands[0], VOIDmode); 13683}) 13684 13685(define_split 13686 [(set (pc) 13687 (if_then_else (eq (match_operator 0 "ix86_comparison_operator" 13688 [(reg FLAGS_REG) (const_int 0)]) 13689 (const_int 0)) 13690 (label_ref (match_operand 1 "" "")) 13691 (pc)))] 13692 "" 13693 [(set (pc) 13694 (if_then_else (match_dup 0) 13695 (label_ref (match_dup 1)) 13696 (pc)))] 13697{ 13698 rtx new_op0 = copy_rtx (operands[0]); 13699 operands[0] = new_op0; 13700 PUT_MODE (new_op0, VOIDmode); 13701 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0), 13702 GET_MODE (XEXP (new_op0, 0)))); 13703 13704 /* Make sure that (a) the CCmode we have for the flags is strong 13705 enough for the reversed compare or (b) we have a valid FP compare. */ 13706 if (! ix86_comparison_operator (new_op0, VOIDmode)) 13707 FAIL; 13708}) 13709 13710;; Define combination compare-and-branch fp compare instructions to use 13711;; during early optimization. Splitting the operation apart early makes 13712;; for bad code when we want to reverse the operation. 13713 13714(define_insn "*fp_jcc_1_mixed" 13715 [(set (pc) 13716 (if_then_else (match_operator 0 "comparison_operator" 13717 [(match_operand 1 "register_operand" "f,x") 13718 (match_operand 2 "nonimmediate_operand" "f,xm")]) 13719 (label_ref (match_operand 3 "" "")) 13720 (pc))) 13721 (clobber (reg:CCFP FPSR_REG)) 13722 (clobber (reg:CCFP FLAGS_REG))] 13723 "TARGET_MIX_SSE_I387 13724 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13725 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13726 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13727 "#") 13728 13729(define_insn "*fp_jcc_1_sse" 13730 [(set (pc) 13731 (if_then_else (match_operator 0 "comparison_operator" 13732 [(match_operand 1 "register_operand" "x") 13733 (match_operand 2 "nonimmediate_operand" "xm")]) 13734 (label_ref (match_operand 3 "" "")) 13735 (pc))) 13736 (clobber (reg:CCFP FPSR_REG)) 13737 (clobber (reg:CCFP FLAGS_REG))] 13738 "TARGET_SSE_MATH 13739 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13740 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13741 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13742 "#") 13743 13744(define_insn "*fp_jcc_1_387" 13745 [(set (pc) 13746 (if_then_else (match_operator 0 "comparison_operator" 13747 [(match_operand 1 "register_operand" "f") 13748 (match_operand 2 "register_operand" "f")]) 13749 (label_ref (match_operand 3 "" "")) 13750 (pc))) 13751 (clobber (reg:CCFP FPSR_REG)) 13752 (clobber (reg:CCFP FLAGS_REG))] 13753 "TARGET_CMOVE && TARGET_80387 13754 && FLOAT_MODE_P (GET_MODE (operands[1])) 13755 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13756 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13757 "#") 13758 13759(define_insn "*fp_jcc_2_mixed" 13760 [(set (pc) 13761 (if_then_else (match_operator 0 "comparison_operator" 13762 [(match_operand 1 "register_operand" "f,x") 13763 (match_operand 2 "nonimmediate_operand" "f,xm")]) 13764 (pc) 13765 (label_ref (match_operand 3 "" "")))) 13766 (clobber (reg:CCFP FPSR_REG)) 13767 (clobber (reg:CCFP FLAGS_REG))] 13768 "TARGET_MIX_SSE_I387 13769 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13770 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13771 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13772 "#") 13773 13774(define_insn "*fp_jcc_2_sse" 13775 [(set (pc) 13776 (if_then_else (match_operator 0 "comparison_operator" 13777 [(match_operand 1 "register_operand" "x") 13778 (match_operand 2 "nonimmediate_operand" "xm")]) 13779 (pc) 13780 (label_ref (match_operand 3 "" "")))) 13781 (clobber (reg:CCFP FPSR_REG)) 13782 (clobber (reg:CCFP FLAGS_REG))] 13783 "TARGET_SSE_MATH 13784 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13785 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13786 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13787 "#") 13788 13789(define_insn "*fp_jcc_2_387" 13790 [(set (pc) 13791 (if_then_else (match_operator 0 "comparison_operator" 13792 [(match_operand 1 "register_operand" "f") 13793 (match_operand 2 "register_operand" "f")]) 13794 (pc) 13795 (label_ref (match_operand 3 "" "")))) 13796 (clobber (reg:CCFP FPSR_REG)) 13797 (clobber (reg:CCFP FLAGS_REG))] 13798 "TARGET_CMOVE && TARGET_80387 13799 && FLOAT_MODE_P (GET_MODE (operands[1])) 13800 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13801 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13802 "#") 13803 13804(define_insn "*fp_jcc_3_387" 13805 [(set (pc) 13806 (if_then_else (match_operator 0 "comparison_operator" 13807 [(match_operand 1 "register_operand" "f") 13808 (match_operand 2 "nonimmediate_operand" "fm")]) 13809 (label_ref (match_operand 3 "" "")) 13810 (pc))) 13811 (clobber (reg:CCFP FPSR_REG)) 13812 (clobber (reg:CCFP FLAGS_REG)) 13813 (clobber (match_scratch:HI 4 "=a"))] 13814 "TARGET_80387 13815 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) 13816 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13817 && !ix86_use_fcomi_compare (GET_CODE (operands[0])) 13818 && SELECT_CC_MODE (GET_CODE (operands[0]), 13819 operands[1], operands[2]) == CCFPmode 13820 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13821 "#") 13822 13823(define_insn "*fp_jcc_4_387" 13824 [(set (pc) 13825 (if_then_else (match_operator 0 "comparison_operator" 13826 [(match_operand 1 "register_operand" "f") 13827 (match_operand 2 "nonimmediate_operand" "fm")]) 13828 (pc) 13829 (label_ref (match_operand 3 "" "")))) 13830 (clobber (reg:CCFP FPSR_REG)) 13831 (clobber (reg:CCFP FLAGS_REG)) 13832 (clobber (match_scratch:HI 4 "=a"))] 13833 "TARGET_80387 13834 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) 13835 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13836 && !ix86_use_fcomi_compare (GET_CODE (operands[0])) 13837 && SELECT_CC_MODE (GET_CODE (operands[0]), 13838 operands[1], operands[2]) == CCFPmode 13839 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13840 "#") 13841 13842(define_insn "*fp_jcc_5_387" 13843 [(set (pc) 13844 (if_then_else (match_operator 0 "comparison_operator" 13845 [(match_operand 1 "register_operand" "f") 13846 (match_operand 2 "register_operand" "f")]) 13847 (label_ref (match_operand 3 "" "")) 13848 (pc))) 13849 (clobber (reg:CCFP FPSR_REG)) 13850 (clobber (reg:CCFP FLAGS_REG)) 13851 (clobber (match_scratch:HI 4 "=a"))] 13852 "TARGET_80387 13853 && FLOAT_MODE_P (GET_MODE (operands[1])) 13854 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13855 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13856 "#") 13857 13858(define_insn "*fp_jcc_6_387" 13859 [(set (pc) 13860 (if_then_else (match_operator 0 "comparison_operator" 13861 [(match_operand 1 "register_operand" "f") 13862 (match_operand 2 "register_operand" "f")]) 13863 (pc) 13864 (label_ref (match_operand 3 "" "")))) 13865 (clobber (reg:CCFP FPSR_REG)) 13866 (clobber (reg:CCFP FLAGS_REG)) 13867 (clobber (match_scratch:HI 4 "=a"))] 13868 "TARGET_80387 13869 && FLOAT_MODE_P (GET_MODE (operands[1])) 13870 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13871 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13872 "#") 13873 13874(define_insn "*fp_jcc_7_387" 13875 [(set (pc) 13876 (if_then_else (match_operator 0 "comparison_operator" 13877 [(match_operand 1 "register_operand" "f") 13878 (match_operand 2 "const0_operand" "X")]) 13879 (label_ref (match_operand 3 "" "")) 13880 (pc))) 13881 (clobber (reg:CCFP FPSR_REG)) 13882 (clobber (reg:CCFP FLAGS_REG)) 13883 (clobber (match_scratch:HI 4 "=a"))] 13884 "TARGET_80387 13885 && FLOAT_MODE_P (GET_MODE (operands[1])) 13886 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13887 && !ix86_use_fcomi_compare (GET_CODE (operands[0])) 13888 && SELECT_CC_MODE (GET_CODE (operands[0]), 13889 operands[1], operands[2]) == CCFPmode 13890 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13891 "#") 13892 13893;; The order of operands in *fp_jcc_8_387 is forced by combine in 13894;; simplify_comparison () function. Float operator is treated as RTX_OBJ 13895;; with a precedence over other operators and is always put in the first 13896;; place. Swap condition and operands to match ficom instruction. 13897 13898(define_insn "*fp_jcc_8<mode>_387" 13899 [(set (pc) 13900 (if_then_else (match_operator 0 "comparison_operator" 13901 [(match_operator 1 "float_operator" 13902 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")]) 13903 (match_operand 3 "register_operand" "f,f")]) 13904 (label_ref (match_operand 4 "" "")) 13905 (pc))) 13906 (clobber (reg:CCFP FPSR_REG)) 13907 (clobber (reg:CCFP FLAGS_REG)) 13908 (clobber (match_scratch:HI 5 "=a,a"))] 13909 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 13910 && FLOAT_MODE_P (GET_MODE (operands[3])) 13911 && GET_MODE (operands[1]) == GET_MODE (operands[3]) 13912 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0]))) 13913 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode 13914 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))" 13915 "#") 13916 13917(define_split 13918 [(set (pc) 13919 (if_then_else (match_operator 0 "comparison_operator" 13920 [(match_operand 1 "register_operand" "") 13921 (match_operand 2 "nonimmediate_operand" "")]) 13922 (match_operand 3 "" "") 13923 (match_operand 4 "" ""))) 13924 (clobber (reg:CCFP FPSR_REG)) 13925 (clobber (reg:CCFP FLAGS_REG))] 13926 "reload_completed" 13927 [(const_int 0)] 13928{ 13929 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 13930 operands[3], operands[4], NULL_RTX, NULL_RTX); 13931 DONE; 13932}) 13933 13934(define_split 13935 [(set (pc) 13936 (if_then_else (match_operator 0 "comparison_operator" 13937 [(match_operand 1 "register_operand" "") 13938 (match_operand 2 "general_operand" "")]) 13939 (match_operand 3 "" "") 13940 (match_operand 4 "" ""))) 13941 (clobber (reg:CCFP FPSR_REG)) 13942 (clobber (reg:CCFP FLAGS_REG)) 13943 (clobber (match_scratch:HI 5 "=a"))] 13944 "reload_completed" 13945 [(const_int 0)] 13946{ 13947 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 13948 operands[3], operands[4], operands[5], NULL_RTX); 13949 DONE; 13950}) 13951 13952(define_split 13953 [(set (pc) 13954 (if_then_else (match_operator 0 "comparison_operator" 13955 [(match_operator 1 "float_operator" 13956 [(match_operand:X87MODEI12 2 "memory_operand" "")]) 13957 (match_operand 3 "register_operand" "")]) 13958 (match_operand 4 "" "") 13959 (match_operand 5 "" ""))) 13960 (clobber (reg:CCFP FPSR_REG)) 13961 (clobber (reg:CCFP FLAGS_REG)) 13962 (clobber (match_scratch:HI 6 "=a"))] 13963 "reload_completed" 13964 [(const_int 0)] 13965{ 13966 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]); 13967 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), 13968 operands[3], operands[7], 13969 operands[4], operands[5], operands[6], NULL_RTX); 13970 DONE; 13971}) 13972 13973;; %%% Kill this when reload knows how to do it. 13974(define_split 13975 [(set (pc) 13976 (if_then_else (match_operator 0 "comparison_operator" 13977 [(match_operator 1 "float_operator" 13978 [(match_operand:X87MODEI12 2 "register_operand" "")]) 13979 (match_operand 3 "register_operand" "")]) 13980 (match_operand 4 "" "") 13981 (match_operand 5 "" ""))) 13982 (clobber (reg:CCFP FPSR_REG)) 13983 (clobber (reg:CCFP FLAGS_REG)) 13984 (clobber (match_scratch:HI 6 "=a"))] 13985 "reload_completed" 13986 [(const_int 0)] 13987{ 13988 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); 13989 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]); 13990 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), 13991 operands[3], operands[7], 13992 operands[4], operands[5], operands[6], operands[2]); 13993 DONE; 13994}) 13995 13996;; Unconditional and other jump instructions 13997 13998(define_insn "jump" 13999 [(set (pc) 14000 (label_ref (match_operand 0 "" "")))] 14001 "" 14002 "jmp\t%l0" 14003 [(set_attr "type" "ibr") 14004 (set (attr "length") 14005 (if_then_else (and (ge (minus (match_dup 0) (pc)) 14006 (const_int -126)) 14007 (lt (minus (match_dup 0) (pc)) 14008 (const_int 128))) 14009 (const_int 2) 14010 (const_int 5))) 14011 (set_attr "modrm" "0")]) 14012 14013(define_expand "indirect_jump" 14014 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))] 14015 "" 14016 "") 14017 14018(define_insn "*indirect_jump" 14019 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))] 14020 "!TARGET_64BIT" 14021 "jmp\t%A0" 14022 [(set_attr "type" "ibr") 14023 (set_attr "length_immediate" "0")]) 14024 14025(define_insn "*indirect_jump_rtx64" 14026 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))] 14027 "TARGET_64BIT" 14028 "jmp\t%A0" 14029 [(set_attr "type" "ibr") 14030 (set_attr "length_immediate" "0")]) 14031 14032(define_expand "tablejump" 14033 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm")) 14034 (use (label_ref (match_operand 1 "" "")))])] 14035 "" 14036{ 14037 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit) 14038 relative. Convert the relative address to an absolute address. */ 14039 if (flag_pic) 14040 { 14041 rtx op0, op1; 14042 enum rtx_code code; 14043 14044 if (TARGET_64BIT) 14045 { 14046 code = PLUS; 14047 op0 = operands[0]; 14048 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]); 14049 } 14050 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA) 14051 { 14052 code = PLUS; 14053 op0 = operands[0]; 14054 op1 = pic_offset_table_rtx; 14055 } 14056 else 14057 { 14058 code = MINUS; 14059 op0 = pic_offset_table_rtx; 14060 op1 = operands[0]; 14061 } 14062 14063 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0, 14064 OPTAB_DIRECT); 14065 } 14066}) 14067 14068(define_insn "*tablejump_1" 14069 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm")) 14070 (use (label_ref (match_operand 1 "" "")))] 14071 "!TARGET_64BIT" 14072 "jmp\t%A0" 14073 [(set_attr "type" "ibr") 14074 (set_attr "length_immediate" "0")]) 14075 14076(define_insn "*tablejump_1_rtx64" 14077 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm")) 14078 (use (label_ref (match_operand 1 "" "")))] 14079 "TARGET_64BIT" 14080 "jmp\t%A0" 14081 [(set_attr "type" "ibr") 14082 (set_attr "length_immediate" "0")]) 14083 14084;; Convert setcc + movzbl to xor + setcc if operands don't overlap. 14085 14086(define_peephole2 14087 [(set (reg FLAGS_REG) (match_operand 0 "" "")) 14088 (set (match_operand:QI 1 "register_operand" "") 14089 (match_operator:QI 2 "ix86_comparison_operator" 14090 [(reg FLAGS_REG) (const_int 0)])) 14091 (set (match_operand 3 "q_regs_operand" "") 14092 (zero_extend (match_dup 1)))] 14093 "(peep2_reg_dead_p (3, operands[1]) 14094 || operands_match_p (operands[1], operands[3])) 14095 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 14096 [(set (match_dup 4) (match_dup 0)) 14097 (set (strict_low_part (match_dup 5)) 14098 (match_dup 2))] 14099{ 14100 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 14101 operands[5] = gen_lowpart (QImode, operands[3]); 14102 ix86_expand_clear (operands[3]); 14103}) 14104 14105;; Similar, but match zero_extendhisi2_and, which adds a clobber. 14106 14107(define_peephole2 14108 [(set (reg FLAGS_REG) (match_operand 0 "" "")) 14109 (set (match_operand:QI 1 "register_operand" "") 14110 (match_operator:QI 2 "ix86_comparison_operator" 14111 [(reg FLAGS_REG) (const_int 0)])) 14112 (parallel [(set (match_operand 3 "q_regs_operand" "") 14113 (zero_extend (match_dup 1))) 14114 (clobber (reg:CC FLAGS_REG))])] 14115 "(peep2_reg_dead_p (3, operands[1]) 14116 || operands_match_p (operands[1], operands[3])) 14117 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 14118 [(set (match_dup 4) (match_dup 0)) 14119 (set (strict_low_part (match_dup 5)) 14120 (match_dup 2))] 14121{ 14122 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 14123 operands[5] = gen_lowpart (QImode, operands[3]); 14124 ix86_expand_clear (operands[3]); 14125}) 14126 14127;; Call instructions. 14128 14129;; The predicates normally associated with named expanders are not properly 14130;; checked for calls. This is a bug in the generic code, but it isn't that 14131;; easy to fix. Ignore it for now and be prepared to fix things up. 14132 14133;; Call subroutine returning no value. 14134 14135(define_expand "call_pop" 14136 [(parallel [(call (match_operand:QI 0 "" "") 14137 (match_operand:SI 1 "" "")) 14138 (set (reg:SI SP_REG) 14139 (plus:SI (reg:SI SP_REG) 14140 (match_operand:SI 3 "" "")))])] 14141 "!TARGET_64BIT" 14142{ 14143 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0); 14144 DONE; 14145}) 14146 14147(define_insn "*call_pop_0" 14148 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" "")) 14149 (match_operand:SI 1 "" "")) 14150 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 14151 (match_operand:SI 2 "immediate_operand" "")))] 14152 "!TARGET_64BIT" 14153{ 14154 if (SIBLING_CALL_P (insn)) 14155 return "jmp\t%P0"; 14156 else 14157 return "call\t%P0"; 14158} 14159 [(set_attr "type" "call")]) 14160 14161(define_insn "*call_pop_1" 14162 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm")) 14163 (match_operand:SI 1 "" "")) 14164 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 14165 (match_operand:SI 2 "immediate_operand" "i")))] 14166 "!TARGET_64BIT" 14167{ 14168 if (constant_call_address_operand (operands[0], Pmode)) 14169 { 14170 if (SIBLING_CALL_P (insn)) 14171 return "jmp\t%P0"; 14172 else 14173 return "call\t%P0"; 14174 } 14175 if (SIBLING_CALL_P (insn)) 14176 return "jmp\t%A0"; 14177 else 14178 return "call\t%A0"; 14179} 14180 [(set_attr "type" "call")]) 14181 14182(define_expand "call" 14183 [(call (match_operand:QI 0 "" "") 14184 (match_operand 1 "" "")) 14185 (use (match_operand 2 "" ""))] 14186 "" 14187{ 14188 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0); 14189 DONE; 14190}) 14191 14192(define_expand "sibcall" 14193 [(call (match_operand:QI 0 "" "") 14194 (match_operand 1 "" "")) 14195 (use (match_operand 2 "" ""))] 14196 "" 14197{ 14198 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1); 14199 DONE; 14200}) 14201 14202(define_insn "*call_0" 14203 [(call (mem:QI (match_operand 0 "constant_call_address_operand" "")) 14204 (match_operand 1 "" ""))] 14205 "" 14206{ 14207 if (SIBLING_CALL_P (insn)) 14208 return "jmp\t%P0"; 14209 else 14210 return "call\t%P0"; 14211} 14212 [(set_attr "type" "call")]) 14213 14214(define_insn "*call_1" 14215 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm")) 14216 (match_operand 1 "" ""))] 14217 "!SIBLING_CALL_P (insn) && !TARGET_64BIT" 14218{ 14219 if (constant_call_address_operand (operands[0], Pmode)) 14220 return "call\t%P0"; 14221 return "call\t%A0"; 14222} 14223 [(set_attr "type" "call")]) 14224 14225(define_insn "*sibcall_1" 14226 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a")) 14227 (match_operand 1 "" ""))] 14228 "SIBLING_CALL_P (insn) && !TARGET_64BIT" 14229{ 14230 if (constant_call_address_operand (operands[0], Pmode)) 14231 return "jmp\t%P0"; 14232 return "jmp\t%A0"; 14233} 14234 [(set_attr "type" "call")]) 14235 14236(define_insn "*call_1_rex64" 14237 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm")) 14238 (match_operand 1 "" ""))] 14239 "!SIBLING_CALL_P (insn) && TARGET_64BIT" 14240{ 14241 if (constant_call_address_operand (operands[0], Pmode)) 14242 return "call\t%P0"; 14243 return "call\t%A0"; 14244} 14245 [(set_attr "type" "call")]) 14246 14247(define_insn "*sibcall_1_rex64" 14248 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" "")) 14249 (match_operand 1 "" ""))] 14250 "SIBLING_CALL_P (insn) && TARGET_64BIT" 14251 "jmp\t%P0" 14252 [(set_attr "type" "call")]) 14253 14254(define_insn "*sibcall_1_rex64_v" 14255 [(call (mem:QI (reg:DI 40)) 14256 (match_operand 0 "" ""))] 14257 "SIBLING_CALL_P (insn) && TARGET_64BIT" 14258 "jmp\t*%%r11" 14259 [(set_attr "type" "call")]) 14260 14261 14262;; Call subroutine, returning value in operand 0 14263 14264(define_expand "call_value_pop" 14265 [(parallel [(set (match_operand 0 "" "") 14266 (call (match_operand:QI 1 "" "") 14267 (match_operand:SI 2 "" ""))) 14268 (set (reg:SI SP_REG) 14269 (plus:SI (reg:SI SP_REG) 14270 (match_operand:SI 4 "" "")))])] 14271 "!TARGET_64BIT" 14272{ 14273 ix86_expand_call (operands[0], operands[1], operands[2], 14274 operands[3], operands[4], 0); 14275 DONE; 14276}) 14277 14278(define_expand "call_value" 14279 [(set (match_operand 0 "" "") 14280 (call (match_operand:QI 1 "" "") 14281 (match_operand:SI 2 "" ""))) 14282 (use (match_operand:SI 3 "" ""))] 14283 ;; Operand 2 not used on the i386. 14284 "" 14285{ 14286 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0); 14287 DONE; 14288}) 14289 14290(define_expand "sibcall_value" 14291 [(set (match_operand 0 "" "") 14292 (call (match_operand:QI 1 "" "") 14293 (match_operand:SI 2 "" ""))) 14294 (use (match_operand:SI 3 "" ""))] 14295 ;; Operand 2 not used on the i386. 14296 "" 14297{ 14298 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1); 14299 DONE; 14300}) 14301 14302;; Call subroutine returning any type. 14303 14304(define_expand "untyped_call" 14305 [(parallel [(call (match_operand 0 "" "") 14306 (const_int 0)) 14307 (match_operand 1 "" "") 14308 (match_operand 2 "" "")])] 14309 "" 14310{ 14311 int i; 14312 14313 /* In order to give reg-stack an easier job in validating two 14314 coprocessor registers as containing a possible return value, 14315 simply pretend the untyped call returns a complex long double 14316 value. */ 14317 14318 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387 14319 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL), 14320 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1), 14321 NULL, 0); 14322 14323 for (i = 0; i < XVECLEN (operands[2], 0); i++) 14324 { 14325 rtx set = XVECEXP (operands[2], 0, i); 14326 emit_move_insn (SET_DEST (set), SET_SRC (set)); 14327 } 14328 14329 /* The optimizer does not know that the call sets the function value 14330 registers we stored in the result block. We avoid problems by 14331 claiming that all hard registers are used and clobbered at this 14332 point. */ 14333 emit_insn (gen_blockage (const0_rtx)); 14334 14335 DONE; 14336}) 14337 14338;; Prologue and epilogue instructions 14339 14340;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 14341;; all of memory. This blocks insns from being moved across this point. 14342 14343(define_insn "blockage" 14344 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)] 14345 "" 14346 "" 14347 [(set_attr "length" "0")]) 14348 14349;; Insn emitted into the body of a function to return from a function. 14350;; This is only done if the function's epilogue is known to be simple. 14351;; See comments for ix86_can_use_return_insn_p in i386.c. 14352 14353(define_expand "return" 14354 [(return)] 14355 "ix86_can_use_return_insn_p ()" 14356{ 14357 if (current_function_pops_args) 14358 { 14359 rtx popc = GEN_INT (current_function_pops_args); 14360 emit_jump_insn (gen_return_pop_internal (popc)); 14361 DONE; 14362 } 14363}) 14364 14365(define_insn "return_internal" 14366 [(return)] 14367 "reload_completed" 14368 "ret" 14369 [(set_attr "length" "1") 14370 (set_attr "length_immediate" "0") 14371 (set_attr "modrm" "0")]) 14372 14373;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET 14374;; instruction Athlon and K8 have. 14375 14376(define_insn "return_internal_long" 14377 [(return) 14378 (unspec [(const_int 0)] UNSPEC_REP)] 14379 "reload_completed" 14380 "rep {;} ret" 14381 [(set_attr "length" "1") 14382 (set_attr "length_immediate" "0") 14383 (set_attr "prefix_rep" "1") 14384 (set_attr "modrm" "0")]) 14385 14386(define_insn "return_pop_internal" 14387 [(return) 14388 (use (match_operand:SI 0 "const_int_operand" ""))] 14389 "reload_completed" 14390 "ret\t%0" 14391 [(set_attr "length" "3") 14392 (set_attr "length_immediate" "2") 14393 (set_attr "modrm" "0")]) 14394 14395(define_insn "return_indirect_internal" 14396 [(return) 14397 (use (match_operand:SI 0 "register_operand" "r"))] 14398 "reload_completed" 14399 "jmp\t%A0" 14400 [(set_attr "type" "ibr") 14401 (set_attr "length_immediate" "0")]) 14402 14403(define_insn "nop" 14404 [(const_int 0)] 14405 "" 14406 "nop" 14407 [(set_attr "length" "1") 14408 (set_attr "length_immediate" "0") 14409 (set_attr "modrm" "0")]) 14410 14411;; Align to 16-byte boundary, max skip in op0. Used to avoid 14412;; branch prediction penalty for the third jump in a 16-byte 14413;; block on K8. 14414 14415(define_insn "align" 14416 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)] 14417 "" 14418{ 14419#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN 14420 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0])); 14421#else 14422 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that. 14423 The align insn is used to avoid 3 jump instructions in the row to improve 14424 branch prediction and the benefits hardly outweigh the cost of extra 8 14425 nops on the average inserted by full alignment pseudo operation. */ 14426#endif 14427 return ""; 14428} 14429 [(set_attr "length" "16")]) 14430 14431(define_expand "prologue" 14432 [(const_int 1)] 14433 "" 14434 "ix86_expand_prologue (); DONE;") 14435 14436(define_insn "set_got" 14437 [(set (match_operand:SI 0 "register_operand" "=r") 14438 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 14439 (clobber (reg:CC FLAGS_REG))] 14440 "!TARGET_64BIT" 14441 { return output_set_got (operands[0], NULL_RTX); } 14442 [(set_attr "type" "multi") 14443 (set_attr "length" "12")]) 14444 14445(define_insn "set_got_labelled" 14446 [(set (match_operand:SI 0 "register_operand" "=r") 14447 (unspec:SI [(label_ref (match_operand 1 "" ""))] 14448 UNSPEC_SET_GOT)) 14449 (clobber (reg:CC FLAGS_REG))] 14450 "!TARGET_64BIT" 14451 { return output_set_got (operands[0], operands[1]); } 14452 [(set_attr "type" "multi") 14453 (set_attr "length" "12")]) 14454 14455(define_insn "set_got_rex64" 14456 [(set (match_operand:DI 0 "register_operand" "=r") 14457 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))] 14458 "TARGET_64BIT" 14459 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0" 14460 [(set_attr "type" "lea") 14461 (set_attr "length" "6")]) 14462 14463(define_expand "epilogue" 14464 [(const_int 1)] 14465 "" 14466 "ix86_expand_epilogue (1); DONE;") 14467 14468(define_expand "sibcall_epilogue" 14469 [(const_int 1)] 14470 "" 14471 "ix86_expand_epilogue (0); DONE;") 14472 14473(define_expand "eh_return" 14474 [(use (match_operand 0 "register_operand" ""))] 14475 "" 14476{ 14477 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0]; 14478 14479 /* Tricky bit: we write the address of the handler to which we will 14480 be returning into someone else's stack frame, one word below the 14481 stack address we wish to restore. */ 14482 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa); 14483 tmp = plus_constant (tmp, -UNITS_PER_WORD); 14484 tmp = gen_rtx_MEM (Pmode, tmp); 14485 emit_move_insn (tmp, ra); 14486 14487 if (Pmode == SImode) 14488 emit_jump_insn (gen_eh_return_si (sa)); 14489 else 14490 emit_jump_insn (gen_eh_return_di (sa)); 14491 emit_barrier (); 14492 DONE; 14493}) 14494 14495(define_insn_and_split "eh_return_si" 14496 [(set (pc) 14497 (unspec [(match_operand:SI 0 "register_operand" "c")] 14498 UNSPEC_EH_RETURN))] 14499 "!TARGET_64BIT" 14500 "#" 14501 "reload_completed" 14502 [(const_int 1)] 14503 "ix86_expand_epilogue (2); DONE;") 14504 14505(define_insn_and_split "eh_return_di" 14506 [(set (pc) 14507 (unspec [(match_operand:DI 0 "register_operand" "c")] 14508 UNSPEC_EH_RETURN))] 14509 "TARGET_64BIT" 14510 "#" 14511 "reload_completed" 14512 [(const_int 1)] 14513 "ix86_expand_epilogue (2); DONE;") 14514 14515(define_insn "leave" 14516 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4))) 14517 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG))) 14518 (clobber (mem:BLK (scratch)))] 14519 "!TARGET_64BIT" 14520 "leave" 14521 [(set_attr "type" "leave")]) 14522 14523(define_insn "leave_rex64" 14524 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8))) 14525 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG))) 14526 (clobber (mem:BLK (scratch)))] 14527 "TARGET_64BIT" 14528 "leave" 14529 [(set_attr "type" "leave")]) 14530 14531(define_expand "ffssi2" 14532 [(parallel 14533 [(set (match_operand:SI 0 "register_operand" "") 14534 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" ""))) 14535 (clobber (match_scratch:SI 2 "")) 14536 (clobber (reg:CC FLAGS_REG))])] 14537 "" 14538 "") 14539 14540(define_insn_and_split "*ffs_cmove" 14541 [(set (match_operand:SI 0 "register_operand" "=r") 14542 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 14543 (clobber (match_scratch:SI 2 "=&r")) 14544 (clobber (reg:CC FLAGS_REG))] 14545 "TARGET_CMOVE" 14546 "#" 14547 "&& reload_completed" 14548 [(set (match_dup 2) (const_int -1)) 14549 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0))) 14550 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 14551 (set (match_dup 0) (if_then_else:SI 14552 (eq (reg:CCZ FLAGS_REG) (const_int 0)) 14553 (match_dup 2) 14554 (match_dup 0))) 14555 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 14556 (clobber (reg:CC FLAGS_REG))])] 14557 "") 14558 14559(define_insn_and_split "*ffs_no_cmove" 14560 [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 14561 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 14562 (clobber (match_scratch:SI 2 "=&q")) 14563 (clobber (reg:CC FLAGS_REG))] 14564 "" 14565 "#" 14566 "reload_completed" 14567 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0))) 14568 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 14569 (set (strict_low_part (match_dup 3)) 14570 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0))) 14571 (parallel [(set (match_dup 2) (neg:SI (match_dup 2))) 14572 (clobber (reg:CC FLAGS_REG))]) 14573 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2))) 14574 (clobber (reg:CC FLAGS_REG))]) 14575 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 14576 (clobber (reg:CC FLAGS_REG))])] 14577{ 14578 operands[3] = gen_lowpart (QImode, operands[2]); 14579 ix86_expand_clear (operands[2]); 14580}) 14581 14582(define_insn "*ffssi_1" 14583 [(set (reg:CCZ FLAGS_REG) 14584 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm") 14585 (const_int 0))) 14586 (set (match_operand:SI 0 "register_operand" "=r") 14587 (ctz:SI (match_dup 1)))] 14588 "" 14589 "bsf{l}\t{%1, %0|%0, %1}" 14590 [(set_attr "prefix_0f" "1")]) 14591 14592(define_expand "ffsdi2" 14593 [(parallel 14594 [(set (match_operand:DI 0 "register_operand" "") 14595 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" ""))) 14596 (clobber (match_scratch:DI 2 "")) 14597 (clobber (reg:CC FLAGS_REG))])] 14598 "TARGET_64BIT && TARGET_CMOVE" 14599 "") 14600 14601(define_insn_and_split "*ffs_rex64" 14602 [(set (match_operand:DI 0 "register_operand" "=r") 14603 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))) 14604 (clobber (match_scratch:DI 2 "=&r")) 14605 (clobber (reg:CC FLAGS_REG))] 14606 "TARGET_64BIT && TARGET_CMOVE" 14607 "#" 14608 "&& reload_completed" 14609 [(set (match_dup 2) (const_int -1)) 14610 (parallel [(set (reg:CCZ FLAGS_REG) 14611 (compare:CCZ (match_dup 1) (const_int 0))) 14612 (set (match_dup 0) (ctz:DI (match_dup 1)))]) 14613 (set (match_dup 0) (if_then_else:DI 14614 (eq (reg:CCZ FLAGS_REG) (const_int 0)) 14615 (match_dup 2) 14616 (match_dup 0))) 14617 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1))) 14618 (clobber (reg:CC FLAGS_REG))])] 14619 "") 14620 14621(define_insn "*ffsdi_1" 14622 [(set (reg:CCZ FLAGS_REG) 14623 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm") 14624 (const_int 0))) 14625 (set (match_operand:DI 0 "register_operand" "=r") 14626 (ctz:DI (match_dup 1)))] 14627 "TARGET_64BIT" 14628 "bsf{q}\t{%1, %0|%0, %1}" 14629 [(set_attr "prefix_0f" "1")]) 14630 14631(define_insn "ctzsi2" 14632 [(set (match_operand:SI 0 "register_operand" "=r") 14633 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 14634 (clobber (reg:CC FLAGS_REG))] 14635 "" 14636 "bsf{l}\t{%1, %0|%0, %1}" 14637 [(set_attr "prefix_0f" "1")]) 14638 14639(define_insn "ctzdi2" 14640 [(set (match_operand:DI 0 "register_operand" "=r") 14641 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))) 14642 (clobber (reg:CC FLAGS_REG))] 14643 "TARGET_64BIT" 14644 "bsf{q}\t{%1, %0|%0, %1}" 14645 [(set_attr "prefix_0f" "1")]) 14646 14647(define_expand "clzsi2" 14648 [(parallel 14649 [(set (match_operand:SI 0 "register_operand" "") 14650 (minus:SI (const_int 31) 14651 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))) 14652 (clobber (reg:CC FLAGS_REG))]) 14653 (parallel 14654 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31))) 14655 (clobber (reg:CC FLAGS_REG))])] 14656 "" 14657{ 14658 if (TARGET_ABM) 14659 { 14660 emit_insn (gen_clzsi2_abm (operands[0], operands[1])); 14661 DONE; 14662 } 14663}) 14664 14665(define_insn "clzsi2_abm" 14666 [(set (match_operand:SI 0 "register_operand" "=r") 14667 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))) 14668 (clobber (reg:CC FLAGS_REG))] 14669 "TARGET_ABM" 14670 "lzcnt{l}\t{%1, %0|%0, %1}" 14671 [(set_attr "prefix_rep" "1") 14672 (set_attr "type" "bitmanip") 14673 (set_attr "mode" "SI")]) 14674 14675(define_insn "*bsr" 14676 [(set (match_operand:SI 0 "register_operand" "=r") 14677 (minus:SI (const_int 31) 14678 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))) 14679 (clobber (reg:CC FLAGS_REG))] 14680 "" 14681 "bsr{l}\t{%1, %0|%0, %1}" 14682 [(set_attr "prefix_0f" "1") 14683 (set_attr "mode" "SI")]) 14684 14685(define_insn "popcountsi2" 14686 [(set (match_operand:SI 0 "register_operand" "=r") 14687 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" ""))) 14688 (clobber (reg:CC FLAGS_REG))] 14689 "TARGET_POPCNT" 14690 "popcnt{l}\t{%1, %0|%0, %1}" 14691 [(set_attr "prefix_rep" "1") 14692 (set_attr "type" "bitmanip") 14693 (set_attr "mode" "SI")]) 14694 14695(define_insn "*popcountsi2_cmp" 14696 [(set (reg FLAGS_REG) 14697 (compare 14698 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm")) 14699 (const_int 0))) 14700 (set (match_operand:SI 0 "register_operand" "=r") 14701 (popcount:SI (match_dup 1)))] 14702 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" 14703 "popcnt{l}\t{%1, %0|%0, %1}" 14704 [(set_attr "prefix_rep" "1") 14705 (set_attr "type" "bitmanip") 14706 (set_attr "mode" "SI")]) 14707 14708(define_insn "*popcountsi2_cmp_zext" 14709 [(set (reg FLAGS_REG) 14710 (compare 14711 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm")) 14712 (const_int 0))) 14713 (set (match_operand:DI 0 "register_operand" "=r") 14714 (zero_extend:DI(popcount:SI (match_dup 1))))] 14715 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" 14716 "popcnt{l}\t{%1, %0|%0, %1}" 14717 [(set_attr "prefix_rep" "1") 14718 (set_attr "type" "bitmanip") 14719 (set_attr "mode" "SI")]) 14720 14721(define_expand "clzdi2" 14722 [(parallel 14723 [(set (match_operand:DI 0 "register_operand" "") 14724 (minus:DI (const_int 63) 14725 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))) 14726 (clobber (reg:CC FLAGS_REG))]) 14727 (parallel 14728 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63))) 14729 (clobber (reg:CC FLAGS_REG))])] 14730 "TARGET_64BIT" 14731{ 14732 if (TARGET_ABM) 14733 { 14734 emit_insn (gen_clzdi2_abm (operands[0], operands[1])); 14735 DONE; 14736 } 14737}) 14738 14739(define_insn "clzdi2_abm" 14740 [(set (match_operand:DI 0 "register_operand" "=r") 14741 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))) 14742 (clobber (reg:CC FLAGS_REG))] 14743 "TARGET_64BIT && TARGET_ABM" 14744 "lzcnt{q}\t{%1, %0|%0, %1}" 14745 [(set_attr "prefix_rep" "1") 14746 (set_attr "type" "bitmanip") 14747 (set_attr "mode" "DI")]) 14748 14749(define_insn "*bsr_rex64" 14750 [(set (match_operand:DI 0 "register_operand" "=r") 14751 (minus:DI (const_int 63) 14752 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) 14753 (clobber (reg:CC FLAGS_REG))] 14754 "TARGET_64BIT" 14755 "bsr{q}\t{%1, %0|%0, %1}" 14756 [(set_attr "prefix_0f" "1") 14757 (set_attr "mode" "DI")]) 14758 14759(define_insn "popcountdi2" 14760 [(set (match_operand:DI 0 "register_operand" "=r") 14761 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" ""))) 14762 (clobber (reg:CC FLAGS_REG))] 14763 "TARGET_64BIT && TARGET_POPCNT" 14764 "popcnt{q}\t{%1, %0|%0, %1}" 14765 [(set_attr "prefix_rep" "1") 14766 (set_attr "type" "bitmanip") 14767 (set_attr "mode" "DI")]) 14768 14769(define_insn "*popcountdi2_cmp" 14770 [(set (reg FLAGS_REG) 14771 (compare 14772 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm")) 14773 (const_int 0))) 14774 (set (match_operand:DI 0 "register_operand" "=r") 14775 (popcount:DI (match_dup 1)))] 14776 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" 14777 "popcnt{q}\t{%1, %0|%0, %1}" 14778 [(set_attr "prefix_rep" "1") 14779 (set_attr "type" "bitmanip") 14780 (set_attr "mode" "DI")]) 14781 14782(define_expand "clzhi2" 14783 [(parallel 14784 [(set (match_operand:HI 0 "register_operand" "") 14785 (minus:HI (const_int 15) 14786 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))) 14787 (clobber (reg:CC FLAGS_REG))]) 14788 (parallel 14789 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15))) 14790 (clobber (reg:CC FLAGS_REG))])] 14791 "" 14792{ 14793 if (TARGET_ABM) 14794 { 14795 emit_insn (gen_clzhi2_abm (operands[0], operands[1])); 14796 DONE; 14797 } 14798}) 14799 14800(define_insn "clzhi2_abm" 14801 [(set (match_operand:HI 0 "register_operand" "=r") 14802 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))) 14803 (clobber (reg:CC FLAGS_REG))] 14804 "TARGET_ABM" 14805 "lzcnt{w}\t{%1, %0|%0, %1}" 14806 [(set_attr "prefix_rep" "1") 14807 (set_attr "type" "bitmanip") 14808 (set_attr "mode" "HI")]) 14809 14810(define_insn "*bsrhi" 14811 [(set (match_operand:HI 0 "register_operand" "=r") 14812 (minus:HI (const_int 15) 14813 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))) 14814 (clobber (reg:CC FLAGS_REG))] 14815 "" 14816 "bsr{w}\t{%1, %0|%0, %1}" 14817 [(set_attr "prefix_0f" "1") 14818 (set_attr "mode" "HI")]) 14819 14820(define_insn "popcounthi2" 14821 [(set (match_operand:HI 0 "register_operand" "=r") 14822 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" ""))) 14823 (clobber (reg:CC FLAGS_REG))] 14824 "TARGET_POPCNT" 14825 "popcnt{w}\t{%1, %0|%0, %1}" 14826 [(set_attr "prefix_rep" "1") 14827 (set_attr "type" "bitmanip") 14828 (set_attr "mode" "HI")]) 14829 14830(define_insn "*popcounthi2_cmp" 14831 [(set (reg FLAGS_REG) 14832 (compare 14833 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm")) 14834 (const_int 0))) 14835 (set (match_operand:HI 0 "register_operand" "=r") 14836 (popcount:HI (match_dup 1)))] 14837 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)" 14838 "popcnt{w}\t{%1, %0|%0, %1}" 14839 [(set_attr "prefix_rep" "1") 14840 (set_attr "type" "bitmanip") 14841 (set_attr "mode" "HI")]) 14842 14843;; Thread-local storage patterns for ELF. 14844;; 14845;; Note that these code sequences must appear exactly as shown 14846;; in order to allow linker relaxation. 14847 14848(define_insn "*tls_global_dynamic_32_gnu" 14849 [(set (match_operand:SI 0 "register_operand" "=a") 14850 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14851 (match_operand:SI 2 "tls_symbolic_operand" "") 14852 (match_operand:SI 3 "call_insn_operand" "")] 14853 UNSPEC_TLS_GD)) 14854 (clobber (match_scratch:SI 4 "=d")) 14855 (clobber (match_scratch:SI 5 "=c")) 14856 (clobber (reg:CC FLAGS_REG))] 14857 "!TARGET_64BIT && TARGET_GNU_TLS" 14858 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3" 14859 [(set_attr "type" "multi") 14860 (set_attr "length" "12")]) 14861 14862(define_insn "*tls_global_dynamic_32_sun" 14863 [(set (match_operand:SI 0 "register_operand" "=a") 14864 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14865 (match_operand:SI 2 "tls_symbolic_operand" "") 14866 (match_operand:SI 3 "call_insn_operand" "")] 14867 UNSPEC_TLS_GD)) 14868 (clobber (match_scratch:SI 4 "=d")) 14869 (clobber (match_scratch:SI 5 "=c")) 14870 (clobber (reg:CC FLAGS_REG))] 14871 "!TARGET_64BIT && TARGET_SUN_TLS" 14872 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]} 14873 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop" 14874 [(set_attr "type" "multi") 14875 (set_attr "length" "14")]) 14876 14877(define_expand "tls_global_dynamic_32" 14878 [(parallel [(set (match_operand:SI 0 "register_operand" "") 14879 (unspec:SI 14880 [(match_dup 2) 14881 (match_operand:SI 1 "tls_symbolic_operand" "") 14882 (match_dup 3)] 14883 UNSPEC_TLS_GD)) 14884 (clobber (match_scratch:SI 4 "")) 14885 (clobber (match_scratch:SI 5 "")) 14886 (clobber (reg:CC FLAGS_REG))])] 14887 "" 14888{ 14889 if (flag_pic) 14890 operands[2] = pic_offset_table_rtx; 14891 else 14892 { 14893 operands[2] = gen_reg_rtx (Pmode); 14894 emit_insn (gen_set_got (operands[2])); 14895 } 14896 if (TARGET_GNU2_TLS) 14897 { 14898 emit_insn (gen_tls_dynamic_gnu2_32 14899 (operands[0], operands[1], operands[2])); 14900 DONE; 14901 } 14902 operands[3] = ix86_tls_get_addr (); 14903}) 14904 14905(define_insn "*tls_global_dynamic_64" 14906 [(set (match_operand:DI 0 "register_operand" "=a") 14907 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" "")) 14908 (match_operand:DI 3 "" ""))) 14909 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 14910 UNSPEC_TLS_GD)] 14911 "TARGET_64BIT" 14912 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2" 14913 [(set_attr "type" "multi") 14914 (set_attr "length" "16")]) 14915 14916(define_expand "tls_global_dynamic_64" 14917 [(parallel [(set (match_operand:DI 0 "register_operand" "") 14918 (call:DI (mem:QI (match_dup 2)) (const_int 0))) 14919 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 14920 UNSPEC_TLS_GD)])] 14921 "" 14922{ 14923 if (TARGET_GNU2_TLS) 14924 { 14925 emit_insn (gen_tls_dynamic_gnu2_64 14926 (operands[0], operands[1])); 14927 DONE; 14928 } 14929 operands[2] = ix86_tls_get_addr (); 14930}) 14931 14932(define_insn "*tls_local_dynamic_base_32_gnu" 14933 [(set (match_operand:SI 0 "register_operand" "=a") 14934 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14935 (match_operand:SI 2 "call_insn_operand" "")] 14936 UNSPEC_TLS_LD_BASE)) 14937 (clobber (match_scratch:SI 3 "=d")) 14938 (clobber (match_scratch:SI 4 "=c")) 14939 (clobber (reg:CC FLAGS_REG))] 14940 "!TARGET_64BIT && TARGET_GNU_TLS" 14941 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2" 14942 [(set_attr "type" "multi") 14943 (set_attr "length" "11")]) 14944 14945(define_insn "*tls_local_dynamic_base_32_sun" 14946 [(set (match_operand:SI 0 "register_operand" "=a") 14947 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14948 (match_operand:SI 2 "call_insn_operand" "")] 14949 UNSPEC_TLS_LD_BASE)) 14950 (clobber (match_scratch:SI 3 "=d")) 14951 (clobber (match_scratch:SI 4 "=c")) 14952 (clobber (reg:CC FLAGS_REG))] 14953 "!TARGET_64BIT && TARGET_SUN_TLS" 14954 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]} 14955 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3" 14956 [(set_attr "type" "multi") 14957 (set_attr "length" "13")]) 14958 14959(define_expand "tls_local_dynamic_base_32" 14960 [(parallel [(set (match_operand:SI 0 "register_operand" "") 14961 (unspec:SI [(match_dup 1) (match_dup 2)] 14962 UNSPEC_TLS_LD_BASE)) 14963 (clobber (match_scratch:SI 3 "")) 14964 (clobber (match_scratch:SI 4 "")) 14965 (clobber (reg:CC FLAGS_REG))])] 14966 "" 14967{ 14968 if (flag_pic) 14969 operands[1] = pic_offset_table_rtx; 14970 else 14971 { 14972 operands[1] = gen_reg_rtx (Pmode); 14973 emit_insn (gen_set_got (operands[1])); 14974 } 14975 if (TARGET_GNU2_TLS) 14976 { 14977 emit_insn (gen_tls_dynamic_gnu2_32 14978 (operands[0], ix86_tls_module_base (), operands[1])); 14979 DONE; 14980 } 14981 operands[2] = ix86_tls_get_addr (); 14982}) 14983 14984(define_insn "*tls_local_dynamic_base_64" 14985 [(set (match_operand:DI 0 "register_operand" "=a") 14986 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" "")) 14987 (match_operand:DI 2 "" ""))) 14988 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)] 14989 "TARGET_64BIT" 14990 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1" 14991 [(set_attr "type" "multi") 14992 (set_attr "length" "12")]) 14993 14994(define_expand "tls_local_dynamic_base_64" 14995 [(parallel [(set (match_operand:DI 0 "register_operand" "") 14996 (call:DI (mem:QI (match_dup 1)) (const_int 0))) 14997 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])] 14998 "" 14999{ 15000 if (TARGET_GNU2_TLS) 15001 { 15002 emit_insn (gen_tls_dynamic_gnu2_64 15003 (operands[0], ix86_tls_module_base ())); 15004 DONE; 15005 } 15006 operands[1] = ix86_tls_get_addr (); 15007}) 15008 15009;; Local dynamic of a single variable is a lose. Show combine how 15010;; to convert that back to global dynamic. 15011 15012(define_insn_and_split "*tls_local_dynamic_32_once" 15013 [(set (match_operand:SI 0 "register_operand" "=a") 15014 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b") 15015 (match_operand:SI 2 "call_insn_operand" "")] 15016 UNSPEC_TLS_LD_BASE) 15017 (const:SI (unspec:SI 15018 [(match_operand:SI 3 "tls_symbolic_operand" "")] 15019 UNSPEC_DTPOFF)))) 15020 (clobber (match_scratch:SI 4 "=d")) 15021 (clobber (match_scratch:SI 5 "=c")) 15022 (clobber (reg:CC FLAGS_REG))] 15023 "" 15024 "#" 15025 "" 15026 [(parallel [(set (match_dup 0) 15027 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)] 15028 UNSPEC_TLS_GD)) 15029 (clobber (match_dup 4)) 15030 (clobber (match_dup 5)) 15031 (clobber (reg:CC FLAGS_REG))])] 15032 "") 15033 15034;; Load and add the thread base pointer from %gs:0. 15035 15036(define_insn "*load_tp_si" 15037 [(set (match_operand:SI 0 "register_operand" "=r") 15038 (unspec:SI [(const_int 0)] UNSPEC_TP))] 15039 "!TARGET_64BIT" 15040 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}" 15041 [(set_attr "type" "imov") 15042 (set_attr "modrm" "0") 15043 (set_attr "length" "7") 15044 (set_attr "memory" "load") 15045 (set_attr "imm_disp" "false")]) 15046 15047(define_insn "*add_tp_si" 15048 [(set (match_operand:SI 0 "register_operand" "=r") 15049 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) 15050 (match_operand:SI 1 "register_operand" "0"))) 15051 (clobber (reg:CC FLAGS_REG))] 15052 "!TARGET_64BIT" 15053 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}" 15054 [(set_attr "type" "alu") 15055 (set_attr "modrm" "0") 15056 (set_attr "length" "7") 15057 (set_attr "memory" "load") 15058 (set_attr "imm_disp" "false")]) 15059 15060(define_insn "*load_tp_di" 15061 [(set (match_operand:DI 0 "register_operand" "=r") 15062 (unspec:DI [(const_int 0)] UNSPEC_TP))] 15063 "TARGET_64BIT" 15064 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}" 15065 [(set_attr "type" "imov") 15066 (set_attr "modrm" "0") 15067 (set_attr "length" "7") 15068 (set_attr "memory" "load") 15069 (set_attr "imm_disp" "false")]) 15070 15071(define_insn "*add_tp_di" 15072 [(set (match_operand:DI 0 "register_operand" "=r") 15073 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP) 15074 (match_operand:DI 1 "register_operand" "0"))) 15075 (clobber (reg:CC FLAGS_REG))] 15076 "TARGET_64BIT" 15077 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}" 15078 [(set_attr "type" "alu") 15079 (set_attr "modrm" "0") 15080 (set_attr "length" "7") 15081 (set_attr "memory" "load") 15082 (set_attr "imm_disp" "false")]) 15083 15084;; GNU2 TLS patterns can be split. 15085 15086(define_expand "tls_dynamic_gnu2_32" 15087 [(set (match_dup 3) 15088 (plus:SI (match_operand:SI 2 "register_operand" "") 15089 (const:SI 15090 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")] 15091 UNSPEC_TLSDESC)))) 15092 (parallel 15093 [(set (match_operand:SI 0 "register_operand" "") 15094 (unspec:SI [(match_dup 1) (match_dup 3) 15095 (match_dup 2) (reg:SI SP_REG)] 15096 UNSPEC_TLSDESC)) 15097 (clobber (reg:CC FLAGS_REG))])] 15098 "!TARGET_64BIT && TARGET_GNU2_TLS" 15099{ 15100 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); 15101 ix86_tls_descriptor_calls_expanded_in_cfun = true; 15102}) 15103 15104(define_insn "*tls_dynamic_lea_32" 15105 [(set (match_operand:SI 0 "register_operand" "=r") 15106 (plus:SI (match_operand:SI 1 "register_operand" "b") 15107 (const:SI 15108 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")] 15109 UNSPEC_TLSDESC))))] 15110 "!TARGET_64BIT && TARGET_GNU2_TLS" 15111 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}" 15112 [(set_attr "type" "lea") 15113 (set_attr "mode" "SI") 15114 (set_attr "length" "6") 15115 (set_attr "length_address" "4")]) 15116 15117(define_insn "*tls_dynamic_call_32" 15118 [(set (match_operand:SI 0 "register_operand" "=a") 15119 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "") 15120 (match_operand:SI 2 "register_operand" "0") 15121 ;; we have to make sure %ebx still points to the GOT 15122 (match_operand:SI 3 "register_operand" "b") 15123 (reg:SI SP_REG)] 15124 UNSPEC_TLSDESC)) 15125 (clobber (reg:CC FLAGS_REG))] 15126 "!TARGET_64BIT && TARGET_GNU2_TLS" 15127 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}" 15128 [(set_attr "type" "call") 15129 (set_attr "length" "2") 15130 (set_attr "length_address" "0")]) 15131 15132(define_insn_and_split "*tls_dynamic_gnu2_combine_32" 15133 [(set (match_operand:SI 0 "register_operand" "=&a") 15134 (plus:SI 15135 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "") 15136 (match_operand:SI 4 "" "") 15137 (match_operand:SI 2 "register_operand" "b") 15138 (reg:SI SP_REG)] 15139 UNSPEC_TLSDESC) 15140 (const:SI (unspec:SI 15141 [(match_operand:SI 1 "tls_symbolic_operand" "")] 15142 UNSPEC_DTPOFF)))) 15143 (clobber (reg:CC FLAGS_REG))] 15144 "!TARGET_64BIT && TARGET_GNU2_TLS" 15145 "#" 15146 "" 15147 [(set (match_dup 0) (match_dup 5))] 15148{ 15149 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); 15150 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2])); 15151}) 15152 15153(define_expand "tls_dynamic_gnu2_64" 15154 [(set (match_dup 2) 15155 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 15156 UNSPEC_TLSDESC)) 15157 (parallel 15158 [(set (match_operand:DI 0 "register_operand" "") 15159 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)] 15160 UNSPEC_TLSDESC)) 15161 (clobber (reg:CC FLAGS_REG))])] 15162 "TARGET_64BIT && TARGET_GNU2_TLS" 15163{ 15164 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); 15165 ix86_tls_descriptor_calls_expanded_in_cfun = true; 15166}) 15167 15168(define_insn "*tls_dynamic_lea_64" 15169 [(set (match_operand:DI 0 "register_operand" "=r") 15170 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 15171 UNSPEC_TLSDESC))] 15172 "TARGET_64BIT && TARGET_GNU2_TLS" 15173 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}" 15174 [(set_attr "type" "lea") 15175 (set_attr "mode" "DI") 15176 (set_attr "length" "7") 15177 (set_attr "length_address" "4")]) 15178 15179(define_insn "*tls_dynamic_call_64" 15180 [(set (match_operand:DI 0 "register_operand" "=a") 15181 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "") 15182 (match_operand:DI 2 "register_operand" "0") 15183 (reg:DI SP_REG)] 15184 UNSPEC_TLSDESC)) 15185 (clobber (reg:CC FLAGS_REG))] 15186 "TARGET_64BIT && TARGET_GNU2_TLS" 15187 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}" 15188 [(set_attr "type" "call") 15189 (set_attr "length" "2") 15190 (set_attr "length_address" "0")]) 15191 15192(define_insn_and_split "*tls_dynamic_gnu2_combine_64" 15193 [(set (match_operand:DI 0 "register_operand" "=&a") 15194 (plus:DI 15195 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "") 15196 (match_operand:DI 3 "" "") 15197 (reg:DI SP_REG)] 15198 UNSPEC_TLSDESC) 15199 (const:DI (unspec:DI 15200 [(match_operand:DI 1 "tls_symbolic_operand" "")] 15201 UNSPEC_DTPOFF)))) 15202 (clobber (reg:CC FLAGS_REG))] 15203 "TARGET_64BIT && TARGET_GNU2_TLS" 15204 "#" 15205 "" 15206 [(set (match_dup 0) (match_dup 4))] 15207{ 15208 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); 15209 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1])); 15210}) 15211 15212;; 15213 15214;; These patterns match the binary 387 instructions for addM3, subM3, 15215;; mulM3 and divM3. There are three patterns for each of DFmode and 15216;; SFmode. The first is the normal insn, the second the same insn but 15217;; with one operand a conversion, and the third the same insn but with 15218;; the other operand a conversion. The conversion may be SFmode or 15219;; SImode if the target mode DFmode, but only SImode if the target mode 15220;; is SFmode. 15221 15222;; Gcc is slightly more smart about handling normal two address instructions 15223;; so use special patterns for add and mull. 15224 15225(define_insn "*fop_sf_comm_mixed" 15226 [(set (match_operand:SF 0 "register_operand" "=f,x") 15227 (match_operator:SF 3 "binary_fp_operator" 15228 [(match_operand:SF 1 "nonimmediate_operand" "%0,0") 15229 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))] 15230 "TARGET_MIX_SSE_I387 15231 && COMMUTATIVE_ARITH_P (operands[3]) 15232 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15233 "* return output_387_binary_op (insn, operands);" 15234 [(set (attr "type") 15235 (if_then_else (eq_attr "alternative" "1") 15236 (if_then_else (match_operand:SF 3 "mult_operator" "") 15237 (const_string "ssemul") 15238 (const_string "sseadd")) 15239 (if_then_else (match_operand:SF 3 "mult_operator" "") 15240 (const_string "fmul") 15241 (const_string "fop")))) 15242 (set_attr "mode" "SF")]) 15243 15244(define_insn "*fop_sf_comm_sse" 15245 [(set (match_operand:SF 0 "register_operand" "=x") 15246 (match_operator:SF 3 "binary_fp_operator" 15247 [(match_operand:SF 1 "nonimmediate_operand" "%0") 15248 (match_operand:SF 2 "nonimmediate_operand" "xm")]))] 15249 "TARGET_SSE_MATH 15250 && COMMUTATIVE_ARITH_P (operands[3]) 15251 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15252 "* return output_387_binary_op (insn, operands);" 15253 [(set (attr "type") 15254 (if_then_else (match_operand:SF 3 "mult_operator" "") 15255 (const_string "ssemul") 15256 (const_string "sseadd"))) 15257 (set_attr "mode" "SF")]) 15258 15259(define_insn "*fop_sf_comm_i387" 15260 [(set (match_operand:SF 0 "register_operand" "=f") 15261 (match_operator:SF 3 "binary_fp_operator" 15262 [(match_operand:SF 1 "nonimmediate_operand" "%0") 15263 (match_operand:SF 2 "nonimmediate_operand" "fm")]))] 15264 "TARGET_80387 15265 && COMMUTATIVE_ARITH_P (operands[3]) 15266 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15267 "* return output_387_binary_op (insn, operands);" 15268 [(set (attr "type") 15269 (if_then_else (match_operand:SF 3 "mult_operator" "") 15270 (const_string "fmul") 15271 (const_string "fop"))) 15272 (set_attr "mode" "SF")]) 15273 15274(define_insn "*fop_sf_1_mixed" 15275 [(set (match_operand:SF 0 "register_operand" "=f,f,x") 15276 (match_operator:SF 3 "binary_fp_operator" 15277 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0") 15278 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))] 15279 "TARGET_MIX_SSE_I387 15280 && !COMMUTATIVE_ARITH_P (operands[3]) 15281 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15282 "* return output_387_binary_op (insn, operands);" 15283 [(set (attr "type") 15284 (cond [(and (eq_attr "alternative" "2") 15285 (match_operand:SF 3 "mult_operator" "")) 15286 (const_string "ssemul") 15287 (and (eq_attr "alternative" "2") 15288 (match_operand:SF 3 "div_operator" "")) 15289 (const_string "ssediv") 15290 (eq_attr "alternative" "2") 15291 (const_string "sseadd") 15292 (match_operand:SF 3 "mult_operator" "") 15293 (const_string "fmul") 15294 (match_operand:SF 3 "div_operator" "") 15295 (const_string "fdiv") 15296 ] 15297 (const_string "fop"))) 15298 (set_attr "mode" "SF")]) 15299 15300(define_insn "*fop_sf_1_sse" 15301 [(set (match_operand:SF 0 "register_operand" "=x") 15302 (match_operator:SF 3 "binary_fp_operator" 15303 [(match_operand:SF 1 "register_operand" "0") 15304 (match_operand:SF 2 "nonimmediate_operand" "xm")]))] 15305 "TARGET_SSE_MATH 15306 && !COMMUTATIVE_ARITH_P (operands[3])" 15307 "* return output_387_binary_op (insn, operands);" 15308 [(set (attr "type") 15309 (cond [(match_operand:SF 3 "mult_operator" "") 15310 (const_string "ssemul") 15311 (match_operand:SF 3 "div_operator" "") 15312 (const_string "ssediv") 15313 ] 15314 (const_string "sseadd"))) 15315 (set_attr "mode" "SF")]) 15316 15317;; This pattern is not fully shadowed by the pattern above. 15318(define_insn "*fop_sf_1_i387" 15319 [(set (match_operand:SF 0 "register_operand" "=f,f") 15320 (match_operator:SF 3 "binary_fp_operator" 15321 [(match_operand:SF 1 "nonimmediate_operand" "0,fm") 15322 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))] 15323 "TARGET_80387 && !TARGET_SSE_MATH 15324 && !COMMUTATIVE_ARITH_P (operands[3]) 15325 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15326 "* return output_387_binary_op (insn, operands);" 15327 [(set (attr "type") 15328 (cond [(match_operand:SF 3 "mult_operator" "") 15329 (const_string "fmul") 15330 (match_operand:SF 3 "div_operator" "") 15331 (const_string "fdiv") 15332 ] 15333 (const_string "fop"))) 15334 (set_attr "mode" "SF")]) 15335 15336;; ??? Add SSE splitters for these! 15337(define_insn "*fop_sf_2<mode>_i387" 15338 [(set (match_operand:SF 0 "register_operand" "=f,f") 15339 (match_operator:SF 3 "binary_fp_operator" 15340 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r")) 15341 (match_operand:SF 2 "register_operand" "0,0")]))] 15342 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH" 15343 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15344 [(set (attr "type") 15345 (cond [(match_operand:SF 3 "mult_operator" "") 15346 (const_string "fmul") 15347 (match_operand:SF 3 "div_operator" "") 15348 (const_string "fdiv") 15349 ] 15350 (const_string "fop"))) 15351 (set_attr "fp_int_src" "true") 15352 (set_attr "mode" "<MODE>")]) 15353 15354(define_insn "*fop_sf_3<mode>_i387" 15355 [(set (match_operand:SF 0 "register_operand" "=f,f") 15356 (match_operator:SF 3 "binary_fp_operator" 15357 [(match_operand:SF 1 "register_operand" "0,0") 15358 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))] 15359 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH" 15360 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15361 [(set (attr "type") 15362 (cond [(match_operand:SF 3 "mult_operator" "") 15363 (const_string "fmul") 15364 (match_operand:SF 3 "div_operator" "") 15365 (const_string "fdiv") 15366 ] 15367 (const_string "fop"))) 15368 (set_attr "fp_int_src" "true") 15369 (set_attr "mode" "<MODE>")]) 15370 15371(define_insn "*fop_df_comm_mixed" 15372 [(set (match_operand:DF 0 "register_operand" "=f,Y") 15373 (match_operator:DF 3 "binary_fp_operator" 15374 [(match_operand:DF 1 "nonimmediate_operand" "%0,0") 15375 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))] 15376 "TARGET_SSE2 && TARGET_MIX_SSE_I387 15377 && COMMUTATIVE_ARITH_P (operands[3]) 15378 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15379 "* return output_387_binary_op (insn, operands);" 15380 [(set (attr "type") 15381 (if_then_else (eq_attr "alternative" "1") 15382 (if_then_else (match_operand:DF 3 "mult_operator" "") 15383 (const_string "ssemul") 15384 (const_string "sseadd")) 15385 (if_then_else (match_operand:DF 3 "mult_operator" "") 15386 (const_string "fmul") 15387 (const_string "fop")))) 15388 (set_attr "mode" "DF")]) 15389 15390(define_insn "*fop_df_comm_sse" 15391 [(set (match_operand:DF 0 "register_operand" "=Y") 15392 (match_operator:DF 3 "binary_fp_operator" 15393 [(match_operand:DF 1 "nonimmediate_operand" "%0") 15394 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))] 15395 "TARGET_SSE2 && TARGET_SSE_MATH 15396 && COMMUTATIVE_ARITH_P (operands[3]) 15397 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15398 "* return output_387_binary_op (insn, operands);" 15399 [(set (attr "type") 15400 (if_then_else (match_operand:DF 3 "mult_operator" "") 15401 (const_string "ssemul") 15402 (const_string "sseadd"))) 15403 (set_attr "mode" "DF")]) 15404 15405(define_insn "*fop_df_comm_i387" 15406 [(set (match_operand:DF 0 "register_operand" "=f") 15407 (match_operator:DF 3 "binary_fp_operator" 15408 [(match_operand:DF 1 "nonimmediate_operand" "%0") 15409 (match_operand:DF 2 "nonimmediate_operand" "fm")]))] 15410 "TARGET_80387 15411 && COMMUTATIVE_ARITH_P (operands[3]) 15412 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15413 "* return output_387_binary_op (insn, operands);" 15414 [(set (attr "type") 15415 (if_then_else (match_operand:DF 3 "mult_operator" "") 15416 (const_string "fmul") 15417 (const_string "fop"))) 15418 (set_attr "mode" "DF")]) 15419 15420(define_insn "*fop_df_1_mixed" 15421 [(set (match_operand:DF 0 "register_operand" "=f,f,Y") 15422 (match_operator:DF 3 "binary_fp_operator" 15423 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0") 15424 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))] 15425 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387 15426 && !COMMUTATIVE_ARITH_P (operands[3]) 15427 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15428 "* return output_387_binary_op (insn, operands);" 15429 [(set (attr "type") 15430 (cond [(and (eq_attr "alternative" "2") 15431 (match_operand:DF 3 "mult_operator" "")) 15432 (const_string "ssemul") 15433 (and (eq_attr "alternative" "2") 15434 (match_operand:DF 3 "div_operator" "")) 15435 (const_string "ssediv") 15436 (eq_attr "alternative" "2") 15437 (const_string "sseadd") 15438 (match_operand:DF 3 "mult_operator" "") 15439 (const_string "fmul") 15440 (match_operand:DF 3 "div_operator" "") 15441 (const_string "fdiv") 15442 ] 15443 (const_string "fop"))) 15444 (set_attr "mode" "DF")]) 15445 15446(define_insn "*fop_df_1_sse" 15447 [(set (match_operand:DF 0 "register_operand" "=Y") 15448 (match_operator:DF 3 "binary_fp_operator" 15449 [(match_operand:DF 1 "register_operand" "0") 15450 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))] 15451 "TARGET_SSE2 && TARGET_SSE_MATH 15452 && !COMMUTATIVE_ARITH_P (operands[3])" 15453 "* return output_387_binary_op (insn, operands);" 15454 [(set_attr "mode" "DF") 15455 (set (attr "type") 15456 (cond [(match_operand:DF 3 "mult_operator" "") 15457 (const_string "ssemul") 15458 (match_operand:DF 3 "div_operator" "") 15459 (const_string "ssediv") 15460 ] 15461 (const_string "sseadd")))]) 15462 15463;; This pattern is not fully shadowed by the pattern above. 15464(define_insn "*fop_df_1_i387" 15465 [(set (match_operand:DF 0 "register_operand" "=f,f") 15466 (match_operator:DF 3 "binary_fp_operator" 15467 [(match_operand:DF 1 "nonimmediate_operand" "0,fm") 15468 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))] 15469 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH) 15470 && !COMMUTATIVE_ARITH_P (operands[3]) 15471 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15472 "* return output_387_binary_op (insn, operands);" 15473 [(set (attr "type") 15474 (cond [(match_operand:DF 3 "mult_operator" "") 15475 (const_string "fmul") 15476 (match_operand:DF 3 "div_operator" "") 15477 (const_string "fdiv") 15478 ] 15479 (const_string "fop"))) 15480 (set_attr "mode" "DF")]) 15481 15482;; ??? Add SSE splitters for these! 15483(define_insn "*fop_df_2<mode>_i387" 15484 [(set (match_operand:DF 0 "register_operand" "=f,f") 15485 (match_operator:DF 3 "binary_fp_operator" 15486 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r")) 15487 (match_operand:DF 2 "register_operand" "0,0")]))] 15488 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 15489 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15490 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15491 [(set (attr "type") 15492 (cond [(match_operand:DF 3 "mult_operator" "") 15493 (const_string "fmul") 15494 (match_operand:DF 3 "div_operator" "") 15495 (const_string "fdiv") 15496 ] 15497 (const_string "fop"))) 15498 (set_attr "fp_int_src" "true") 15499 (set_attr "mode" "<MODE>")]) 15500 15501(define_insn "*fop_df_3<mode>_i387" 15502 [(set (match_operand:DF 0 "register_operand" "=f,f") 15503 (match_operator:DF 3 "binary_fp_operator" 15504 [(match_operand:DF 1 "register_operand" "0,0") 15505 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))] 15506 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 15507 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15508 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15509 [(set (attr "type") 15510 (cond [(match_operand:DF 3 "mult_operator" "") 15511 (const_string "fmul") 15512 (match_operand:DF 3 "div_operator" "") 15513 (const_string "fdiv") 15514 ] 15515 (const_string "fop"))) 15516 (set_attr "fp_int_src" "true") 15517 (set_attr "mode" "<MODE>")]) 15518 15519(define_insn "*fop_df_4_i387" 15520 [(set (match_operand:DF 0 "register_operand" "=f,f") 15521 (match_operator:DF 3 "binary_fp_operator" 15522 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0")) 15523 (match_operand:DF 2 "register_operand" "0,f")]))] 15524 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH) 15525 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15526 "* return output_387_binary_op (insn, operands);" 15527 [(set (attr "type") 15528 (cond [(match_operand:DF 3 "mult_operator" "") 15529 (const_string "fmul") 15530 (match_operand:DF 3 "div_operator" "") 15531 (const_string "fdiv") 15532 ] 15533 (const_string "fop"))) 15534 (set_attr "mode" "SF")]) 15535 15536(define_insn "*fop_df_5_i387" 15537 [(set (match_operand:DF 0 "register_operand" "=f,f") 15538 (match_operator:DF 3 "binary_fp_operator" 15539 [(match_operand:DF 1 "register_operand" "0,f") 15540 (float_extend:DF 15541 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15542 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15543 "* return output_387_binary_op (insn, operands);" 15544 [(set (attr "type") 15545 (cond [(match_operand:DF 3 "mult_operator" "") 15546 (const_string "fmul") 15547 (match_operand:DF 3 "div_operator" "") 15548 (const_string "fdiv") 15549 ] 15550 (const_string "fop"))) 15551 (set_attr "mode" "SF")]) 15552 15553(define_insn "*fop_df_6_i387" 15554 [(set (match_operand:DF 0 "register_operand" "=f,f") 15555 (match_operator:DF 3 "binary_fp_operator" 15556 [(float_extend:DF 15557 (match_operand:SF 1 "register_operand" "0,f")) 15558 (float_extend:DF 15559 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15560 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15561 "* return output_387_binary_op (insn, operands);" 15562 [(set (attr "type") 15563 (cond [(match_operand:DF 3 "mult_operator" "") 15564 (const_string "fmul") 15565 (match_operand:DF 3 "div_operator" "") 15566 (const_string "fdiv") 15567 ] 15568 (const_string "fop"))) 15569 (set_attr "mode" "SF")]) 15570 15571(define_insn "*fop_xf_comm_i387" 15572 [(set (match_operand:XF 0 "register_operand" "=f") 15573 (match_operator:XF 3 "binary_fp_operator" 15574 [(match_operand:XF 1 "register_operand" "%0") 15575 (match_operand:XF 2 "register_operand" "f")]))] 15576 "TARGET_80387 15577 && COMMUTATIVE_ARITH_P (operands[3])" 15578 "* return output_387_binary_op (insn, operands);" 15579 [(set (attr "type") 15580 (if_then_else (match_operand:XF 3 "mult_operator" "") 15581 (const_string "fmul") 15582 (const_string "fop"))) 15583 (set_attr "mode" "XF")]) 15584 15585(define_insn "*fop_xf_1_i387" 15586 [(set (match_operand:XF 0 "register_operand" "=f,f") 15587 (match_operator:XF 3 "binary_fp_operator" 15588 [(match_operand:XF 1 "register_operand" "0,f") 15589 (match_operand:XF 2 "register_operand" "f,0")]))] 15590 "TARGET_80387 15591 && !COMMUTATIVE_ARITH_P (operands[3])" 15592 "* return output_387_binary_op (insn, operands);" 15593 [(set (attr "type") 15594 (cond [(match_operand:XF 3 "mult_operator" "") 15595 (const_string "fmul") 15596 (match_operand:XF 3 "div_operator" "") 15597 (const_string "fdiv") 15598 ] 15599 (const_string "fop"))) 15600 (set_attr "mode" "XF")]) 15601 15602(define_insn "*fop_xf_2<mode>_i387" 15603 [(set (match_operand:XF 0 "register_operand" "=f,f") 15604 (match_operator:XF 3 "binary_fp_operator" 15605 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r")) 15606 (match_operand:XF 2 "register_operand" "0,0")]))] 15607 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP" 15608 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15609 [(set (attr "type") 15610 (cond [(match_operand:XF 3 "mult_operator" "") 15611 (const_string "fmul") 15612 (match_operand:XF 3 "div_operator" "") 15613 (const_string "fdiv") 15614 ] 15615 (const_string "fop"))) 15616 (set_attr "fp_int_src" "true") 15617 (set_attr "mode" "<MODE>")]) 15618 15619(define_insn "*fop_xf_3<mode>_i387" 15620 [(set (match_operand:XF 0 "register_operand" "=f,f") 15621 (match_operator:XF 3 "binary_fp_operator" 15622 [(match_operand:XF 1 "register_operand" "0,0") 15623 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))] 15624 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP" 15625 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15626 [(set (attr "type") 15627 (cond [(match_operand:XF 3 "mult_operator" "") 15628 (const_string "fmul") 15629 (match_operand:XF 3 "div_operator" "") 15630 (const_string "fdiv") 15631 ] 15632 (const_string "fop"))) 15633 (set_attr "fp_int_src" "true") 15634 (set_attr "mode" "<MODE>")]) 15635 15636(define_insn "*fop_xf_4_i387" 15637 [(set (match_operand:XF 0 "register_operand" "=f,f") 15638 (match_operator:XF 3 "binary_fp_operator" 15639 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0")) 15640 (match_operand:XF 2 "register_operand" "0,f")]))] 15641 "TARGET_80387" 15642 "* return output_387_binary_op (insn, operands);" 15643 [(set (attr "type") 15644 (cond [(match_operand:XF 3 "mult_operator" "") 15645 (const_string "fmul") 15646 (match_operand:XF 3 "div_operator" "") 15647 (const_string "fdiv") 15648 ] 15649 (const_string "fop"))) 15650 (set_attr "mode" "SF")]) 15651 15652(define_insn "*fop_xf_5_i387" 15653 [(set (match_operand:XF 0 "register_operand" "=f,f") 15654 (match_operator:XF 3 "binary_fp_operator" 15655 [(match_operand:XF 1 "register_operand" "0,f") 15656 (float_extend:XF 15657 (match_operand 2 "nonimmediate_operand" "fm,0"))]))] 15658 "TARGET_80387" 15659 "* return output_387_binary_op (insn, operands);" 15660 [(set (attr "type") 15661 (cond [(match_operand:XF 3 "mult_operator" "") 15662 (const_string "fmul") 15663 (match_operand:XF 3 "div_operator" "") 15664 (const_string "fdiv") 15665 ] 15666 (const_string "fop"))) 15667 (set_attr "mode" "SF")]) 15668 15669(define_insn "*fop_xf_6_i387" 15670 [(set (match_operand:XF 0 "register_operand" "=f,f") 15671 (match_operator:XF 3 "binary_fp_operator" 15672 [(float_extend:XF 15673 (match_operand 1 "register_operand" "0,f")) 15674 (float_extend:XF 15675 (match_operand 2 "nonimmediate_operand" "fm,0"))]))] 15676 "TARGET_80387" 15677 "* return output_387_binary_op (insn, operands);" 15678 [(set (attr "type") 15679 (cond [(match_operand:XF 3 "mult_operator" "") 15680 (const_string "fmul") 15681 (match_operand:XF 3 "div_operator" "") 15682 (const_string "fdiv") 15683 ] 15684 (const_string "fop"))) 15685 (set_attr "mode" "SF")]) 15686 15687(define_split 15688 [(set (match_operand 0 "register_operand" "") 15689 (match_operator 3 "binary_fp_operator" 15690 [(float (match_operand:X87MODEI12 1 "register_operand" "")) 15691 (match_operand 2 "register_operand" "")]))] 15692 "TARGET_80387 && reload_completed 15693 && FLOAT_MODE_P (GET_MODE (operands[0]))" 15694 [(const_int 0)] 15695{ 15696 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]); 15697 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); 15698 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 15699 gen_rtx_fmt_ee (GET_CODE (operands[3]), 15700 GET_MODE (operands[3]), 15701 operands[4], 15702 operands[2]))); 15703 ix86_free_from_memory (GET_MODE (operands[1])); 15704 DONE; 15705}) 15706 15707(define_split 15708 [(set (match_operand 0 "register_operand" "") 15709 (match_operator 3 "binary_fp_operator" 15710 [(match_operand 1 "register_operand" "") 15711 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))] 15712 "TARGET_80387 && reload_completed 15713 && FLOAT_MODE_P (GET_MODE (operands[0]))" 15714 [(const_int 0)] 15715{ 15716 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); 15717 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); 15718 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 15719 gen_rtx_fmt_ee (GET_CODE (operands[3]), 15720 GET_MODE (operands[3]), 15721 operands[1], 15722 operands[4]))); 15723 ix86_free_from_memory (GET_MODE (operands[2])); 15724 DONE; 15725}) 15726 15727;; FPU special functions. 15728 15729(define_expand "sqrtsf2" 15730 [(set (match_operand:SF 0 "register_operand" "") 15731 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))] 15732 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH" 15733{ 15734 if (!TARGET_SSE_MATH) 15735 operands[1] = force_reg (SFmode, operands[1]); 15736}) 15737 15738(define_insn "*sqrtsf2_mixed" 15739 [(set (match_operand:SF 0 "register_operand" "=f,x") 15740 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))] 15741 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387" 15742 "@ 15743 fsqrt 15744 sqrtss\t{%1, %0|%0, %1}" 15745 [(set_attr "type" "fpspc,sse") 15746 (set_attr "mode" "SF,SF") 15747 (set_attr "athlon_decode" "direct,*") 15748 (set_attr "amdfam10_decode" "direct,*")]) 15749 15750(define_insn "*sqrtsf2_sse" 15751 [(set (match_operand:SF 0 "register_operand" "=x") 15752 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))] 15753 "TARGET_SSE_MATH" 15754 "sqrtss\t{%1, %0|%0, %1}" 15755 [(set_attr "type" "sse") 15756 (set_attr "mode" "SF") 15757 (set_attr "athlon_decode" "*") 15758 (set_attr "amdfam10_decode" "*")]) 15759 15760(define_insn "*sqrtsf2_i387" 15761 [(set (match_operand:SF 0 "register_operand" "=f") 15762 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))] 15763 "TARGET_USE_FANCY_MATH_387" 15764 "fsqrt" 15765 [(set_attr "type" "fpspc") 15766 (set_attr "mode" "SF") 15767 (set_attr "athlon_decode" "direct") 15768 (set_attr "amdfam10_decode" "direct")]) 15769 15770(define_expand "sqrtdf2" 15771 [(set (match_operand:DF 0 "register_operand" "") 15772 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))] 15773 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 15774{ 15775 if (!(TARGET_SSE2 && TARGET_SSE_MATH)) 15776 operands[1] = force_reg (DFmode, operands[1]); 15777}) 15778 15779(define_insn "*sqrtdf2_mixed" 15780 [(set (match_operand:DF 0 "register_operand" "=f,Y") 15781 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))] 15782 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387" 15783 "@ 15784 fsqrt 15785 sqrtsd\t{%1, %0|%0, %1}" 15786 [(set_attr "type" "fpspc,sse") 15787 (set_attr "mode" "DF,DF") 15788 (set_attr "athlon_decode" "direct,*") 15789 (set_attr "amdfam10_decode" "direct,*")]) 15790 15791(define_insn "*sqrtdf2_sse" 15792 [(set (match_operand:DF 0 "register_operand" "=Y") 15793 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))] 15794 "TARGET_SSE2 && TARGET_SSE_MATH" 15795 "sqrtsd\t{%1, %0|%0, %1}" 15796 [(set_attr "type" "sse") 15797 (set_attr "mode" "DF") 15798 (set_attr "athlon_decode" "*") 15799 (set_attr "amdfam10_decode" "*")]) 15800 15801(define_insn "*sqrtdf2_i387" 15802 [(set (match_operand:DF 0 "register_operand" "=f") 15803 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))] 15804 "TARGET_USE_FANCY_MATH_387" 15805 "fsqrt" 15806 [(set_attr "type" "fpspc") 15807 (set_attr "mode" "DF") 15808 (set_attr "athlon_decode" "direct") 15809 (set_attr "amdfam10_decode" "direct")]) 15810 15811(define_insn "*sqrtextendsfdf2_i387" 15812 [(set (match_operand:DF 0 "register_operand" "=f") 15813 (sqrt:DF (float_extend:DF 15814 (match_operand:SF 1 "register_operand" "0"))))] 15815 "TARGET_USE_FANCY_MATH_387 15816 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)" 15817 "fsqrt" 15818 [(set_attr "type" "fpspc") 15819 (set_attr "mode" "DF") 15820 (set_attr "athlon_decode" "direct") 15821 (set_attr "amdfam10_decode" "direct")]) 15822 15823(define_insn "sqrtxf2" 15824 [(set (match_operand:XF 0 "register_operand" "=f") 15825 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] 15826 "TARGET_USE_FANCY_MATH_387" 15827 "fsqrt" 15828 [(set_attr "type" "fpspc") 15829 (set_attr "mode" "XF") 15830 (set_attr "athlon_decode" "direct") 15831 (set_attr "amdfam10_decode" "direct")]) 15832 15833(define_insn "*sqrtextendsfxf2_i387" 15834 [(set (match_operand:XF 0 "register_operand" "=f") 15835 (sqrt:XF (float_extend:XF 15836 (match_operand:SF 1 "register_operand" "0"))))] 15837 "TARGET_USE_FANCY_MATH_387" 15838 "fsqrt" 15839 [(set_attr "type" "fpspc") 15840 (set_attr "mode" "XF") 15841 (set_attr "athlon_decode" "direct") 15842 (set_attr "amdfam10_decode" "direct")]) 15843 15844(define_insn "*sqrtextenddfxf2_i387" 15845 [(set (match_operand:XF 0 "register_operand" "=f") 15846 (sqrt:XF (float_extend:XF 15847 (match_operand:DF 1 "register_operand" "0"))))] 15848 "TARGET_USE_FANCY_MATH_387" 15849 "fsqrt" 15850 [(set_attr "type" "fpspc") 15851 (set_attr "mode" "XF") 15852 (set_attr "athlon_decode" "direct") 15853 (set_attr "amdfam10_decode" "direct")]) 15854 15855(define_insn "fpremxf4" 15856 [(set (match_operand:XF 0 "register_operand" "=f") 15857 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15858 (match_operand:XF 3 "register_operand" "1")] 15859 UNSPEC_FPREM_F)) 15860 (set (match_operand:XF 1 "register_operand" "=u") 15861 (unspec:XF [(match_dup 2) (match_dup 3)] 15862 UNSPEC_FPREM_U)) 15863 (set (reg:CCFP FPSR_REG) 15864 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))] 15865 "TARGET_USE_FANCY_MATH_387 15866 && flag_unsafe_math_optimizations" 15867 "fprem" 15868 [(set_attr "type" "fpspc") 15869 (set_attr "mode" "XF")]) 15870 15871(define_expand "fmodsf3" 15872 [(use (match_operand:SF 0 "register_operand" "")) 15873 (use (match_operand:SF 1 "register_operand" "")) 15874 (use (match_operand:SF 2 "register_operand" ""))] 15875 "TARGET_USE_FANCY_MATH_387 15876 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15877 && flag_unsafe_math_optimizations" 15878{ 15879 rtx label = gen_label_rtx (); 15880 15881 rtx op1 = gen_reg_rtx (XFmode); 15882 rtx op2 = gen_reg_rtx (XFmode); 15883 15884 emit_insn(gen_extendsfxf2 (op1, operands[1])); 15885 emit_insn(gen_extendsfxf2 (op2, operands[2])); 15886 15887 emit_label (label); 15888 15889 emit_insn (gen_fpremxf4 (op1, op2, op1, op2)); 15890 ix86_emit_fp_unordered_jump (label); 15891 15892 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1)); 15893 DONE; 15894}) 15895 15896(define_expand "fmoddf3" 15897 [(use (match_operand:DF 0 "register_operand" "")) 15898 (use (match_operand:DF 1 "register_operand" "")) 15899 (use (match_operand:DF 2 "register_operand" ""))] 15900 "TARGET_USE_FANCY_MATH_387 15901 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15902 && flag_unsafe_math_optimizations" 15903{ 15904 rtx label = gen_label_rtx (); 15905 15906 rtx op1 = gen_reg_rtx (XFmode); 15907 rtx op2 = gen_reg_rtx (XFmode); 15908 15909 emit_insn (gen_extenddfxf2 (op1, operands[1])); 15910 emit_insn (gen_extenddfxf2 (op2, operands[2])); 15911 15912 emit_label (label); 15913 15914 emit_insn (gen_fpremxf4 (op1, op2, op1, op2)); 15915 ix86_emit_fp_unordered_jump (label); 15916 15917 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1)); 15918 DONE; 15919}) 15920 15921(define_expand "fmodxf3" 15922 [(use (match_operand:XF 0 "register_operand" "")) 15923 (use (match_operand:XF 1 "register_operand" "")) 15924 (use (match_operand:XF 2 "register_operand" ""))] 15925 "TARGET_USE_FANCY_MATH_387 15926 && flag_unsafe_math_optimizations" 15927{ 15928 rtx label = gen_label_rtx (); 15929 15930 emit_label (label); 15931 15932 emit_insn (gen_fpremxf4 (operands[1], operands[2], 15933 operands[1], operands[2])); 15934 ix86_emit_fp_unordered_jump (label); 15935 15936 emit_move_insn (operands[0], operands[1]); 15937 DONE; 15938}) 15939 15940(define_insn "fprem1xf4" 15941 [(set (match_operand:XF 0 "register_operand" "=f") 15942 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15943 (match_operand:XF 3 "register_operand" "1")] 15944 UNSPEC_FPREM1_F)) 15945 (set (match_operand:XF 1 "register_operand" "=u") 15946 (unspec:XF [(match_dup 2) (match_dup 3)] 15947 UNSPEC_FPREM1_U)) 15948 (set (reg:CCFP FPSR_REG) 15949 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))] 15950 "TARGET_USE_FANCY_MATH_387 15951 && flag_unsafe_math_optimizations" 15952 "fprem1" 15953 [(set_attr "type" "fpspc") 15954 (set_attr "mode" "XF")]) 15955 15956(define_expand "dremsf3" 15957 [(use (match_operand:SF 0 "register_operand" "")) 15958 (use (match_operand:SF 1 "register_operand" "")) 15959 (use (match_operand:SF 2 "register_operand" ""))] 15960 "TARGET_USE_FANCY_MATH_387 15961 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15962 && flag_unsafe_math_optimizations" 15963{ 15964 rtx label = gen_label_rtx (); 15965 15966 rtx op1 = gen_reg_rtx (XFmode); 15967 rtx op2 = gen_reg_rtx (XFmode); 15968 15969 emit_insn(gen_extendsfxf2 (op1, operands[1])); 15970 emit_insn(gen_extendsfxf2 (op2, operands[2])); 15971 15972 emit_label (label); 15973 15974 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2)); 15975 ix86_emit_fp_unordered_jump (label); 15976 15977 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1)); 15978 DONE; 15979}) 15980 15981(define_expand "dremdf3" 15982 [(use (match_operand:DF 0 "register_operand" "")) 15983 (use (match_operand:DF 1 "register_operand" "")) 15984 (use (match_operand:DF 2 "register_operand" ""))] 15985 "TARGET_USE_FANCY_MATH_387 15986 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15987 && flag_unsafe_math_optimizations" 15988{ 15989 rtx label = gen_label_rtx (); 15990 15991 rtx op1 = gen_reg_rtx (XFmode); 15992 rtx op2 = gen_reg_rtx (XFmode); 15993 15994 emit_insn (gen_extenddfxf2 (op1, operands[1])); 15995 emit_insn (gen_extenddfxf2 (op2, operands[2])); 15996 15997 emit_label (label); 15998 15999 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2)); 16000 ix86_emit_fp_unordered_jump (label); 16001 16002 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1)); 16003 DONE; 16004}) 16005 16006(define_expand "dremxf3" 16007 [(use (match_operand:XF 0 "register_operand" "")) 16008 (use (match_operand:XF 1 "register_operand" "")) 16009 (use (match_operand:XF 2 "register_operand" ""))] 16010 "TARGET_USE_FANCY_MATH_387 16011 && flag_unsafe_math_optimizations" 16012{ 16013 rtx label = gen_label_rtx (); 16014 16015 emit_label (label); 16016 16017 emit_insn (gen_fprem1xf4 (operands[1], operands[2], 16018 operands[1], operands[2])); 16019 ix86_emit_fp_unordered_jump (label); 16020 16021 emit_move_insn (operands[0], operands[1]); 16022 DONE; 16023}) 16024 16025(define_insn "*sindf2" 16026 [(set (match_operand:DF 0 "register_operand" "=f") 16027 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))] 16028 "TARGET_USE_FANCY_MATH_387 16029 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16030 && flag_unsafe_math_optimizations" 16031 "fsin" 16032 [(set_attr "type" "fpspc") 16033 (set_attr "mode" "DF")]) 16034 16035(define_insn "*sinsf2" 16036 [(set (match_operand:SF 0 "register_operand" "=f") 16037 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))] 16038 "TARGET_USE_FANCY_MATH_387 16039 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16040 && flag_unsafe_math_optimizations" 16041 "fsin" 16042 [(set_attr "type" "fpspc") 16043 (set_attr "mode" "SF")]) 16044 16045(define_insn "*sinextendsfdf2" 16046 [(set (match_operand:DF 0 "register_operand" "=f") 16047 (unspec:DF [(float_extend:DF 16048 (match_operand:SF 1 "register_operand" "0"))] 16049 UNSPEC_SIN))] 16050 "TARGET_USE_FANCY_MATH_387 16051 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16052 && flag_unsafe_math_optimizations" 16053 "fsin" 16054 [(set_attr "type" "fpspc") 16055 (set_attr "mode" "DF")]) 16056 16057(define_insn "*sinxf2" 16058 [(set (match_operand:XF 0 "register_operand" "=f") 16059 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))] 16060 "TARGET_USE_FANCY_MATH_387 16061 && flag_unsafe_math_optimizations" 16062 "fsin" 16063 [(set_attr "type" "fpspc") 16064 (set_attr "mode" "XF")]) 16065 16066(define_insn "*cosdf2" 16067 [(set (match_operand:DF 0 "register_operand" "=f") 16068 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))] 16069 "TARGET_USE_FANCY_MATH_387 16070 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16071 && flag_unsafe_math_optimizations" 16072 "fcos" 16073 [(set_attr "type" "fpspc") 16074 (set_attr "mode" "DF")]) 16075 16076(define_insn "*cossf2" 16077 [(set (match_operand:SF 0 "register_operand" "=f") 16078 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))] 16079 "TARGET_USE_FANCY_MATH_387 16080 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16081 && flag_unsafe_math_optimizations" 16082 "fcos" 16083 [(set_attr "type" "fpspc") 16084 (set_attr "mode" "SF")]) 16085 16086(define_insn "*cosextendsfdf2" 16087 [(set (match_operand:DF 0 "register_operand" "=f") 16088 (unspec:DF [(float_extend:DF 16089 (match_operand:SF 1 "register_operand" "0"))] 16090 UNSPEC_COS))] 16091 "TARGET_USE_FANCY_MATH_387 16092 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16093 && flag_unsafe_math_optimizations" 16094 "fcos" 16095 [(set_attr "type" "fpspc") 16096 (set_attr "mode" "DF")]) 16097 16098(define_insn "*cosxf2" 16099 [(set (match_operand:XF 0 "register_operand" "=f") 16100 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))] 16101 "TARGET_USE_FANCY_MATH_387 16102 && flag_unsafe_math_optimizations" 16103 "fcos" 16104 [(set_attr "type" "fpspc") 16105 (set_attr "mode" "XF")]) 16106 16107;; With sincos pattern defined, sin and cos builtin function will be 16108;; expanded to sincos pattern with one of its outputs left unused. 16109;; Cse pass will detected, if two sincos patterns can be combined, 16110;; otherwise sincos pattern will be split back to sin or cos pattern, 16111;; depending on the unused output. 16112 16113(define_insn "sincosdf3" 16114 [(set (match_operand:DF 0 "register_operand" "=f") 16115 (unspec:DF [(match_operand:DF 2 "register_operand" "0")] 16116 UNSPEC_SINCOS_COS)) 16117 (set (match_operand:DF 1 "register_operand" "=u") 16118 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16119 "TARGET_USE_FANCY_MATH_387 16120 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16121 && flag_unsafe_math_optimizations" 16122 "fsincos" 16123 [(set_attr "type" "fpspc") 16124 (set_attr "mode" "DF")]) 16125 16126(define_split 16127 [(set (match_operand:DF 0 "register_operand" "") 16128 (unspec:DF [(match_operand:DF 2 "register_operand" "")] 16129 UNSPEC_SINCOS_COS)) 16130 (set (match_operand:DF 1 "register_operand" "") 16131 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16132 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 16133 && !reload_completed && !reload_in_progress" 16134 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))] 16135 "") 16136 16137(define_split 16138 [(set (match_operand:DF 0 "register_operand" "") 16139 (unspec:DF [(match_operand:DF 2 "register_operand" "")] 16140 UNSPEC_SINCOS_COS)) 16141 (set (match_operand:DF 1 "register_operand" "") 16142 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16143 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 16144 && !reload_completed && !reload_in_progress" 16145 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))] 16146 "") 16147 16148(define_insn "sincossf3" 16149 [(set (match_operand:SF 0 "register_operand" "=f") 16150 (unspec:SF [(match_operand:SF 2 "register_operand" "0")] 16151 UNSPEC_SINCOS_COS)) 16152 (set (match_operand:SF 1 "register_operand" "=u") 16153 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16154 "TARGET_USE_FANCY_MATH_387 16155 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16156 && flag_unsafe_math_optimizations" 16157 "fsincos" 16158 [(set_attr "type" "fpspc") 16159 (set_attr "mode" "SF")]) 16160 16161(define_split 16162 [(set (match_operand:SF 0 "register_operand" "") 16163 (unspec:SF [(match_operand:SF 2 "register_operand" "")] 16164 UNSPEC_SINCOS_COS)) 16165 (set (match_operand:SF 1 "register_operand" "") 16166 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16167 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 16168 && !reload_completed && !reload_in_progress" 16169 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))] 16170 "") 16171 16172(define_split 16173 [(set (match_operand:SF 0 "register_operand" "") 16174 (unspec:SF [(match_operand:SF 2 "register_operand" "")] 16175 UNSPEC_SINCOS_COS)) 16176 (set (match_operand:SF 1 "register_operand" "") 16177 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16178 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 16179 && !reload_completed && !reload_in_progress" 16180 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))] 16181 "") 16182 16183(define_insn "*sincosextendsfdf3" 16184 [(set (match_operand:DF 0 "register_operand" "=f") 16185 (unspec:DF [(float_extend:DF 16186 (match_operand:SF 2 "register_operand" "0"))] 16187 UNSPEC_SINCOS_COS)) 16188 (set (match_operand:DF 1 "register_operand" "=u") 16189 (unspec:DF [(float_extend:DF 16190 (match_dup 2))] UNSPEC_SINCOS_SIN))] 16191 "TARGET_USE_FANCY_MATH_387 16192 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16193 && flag_unsafe_math_optimizations" 16194 "fsincos" 16195 [(set_attr "type" "fpspc") 16196 (set_attr "mode" "DF")]) 16197 16198(define_split 16199 [(set (match_operand:DF 0 "register_operand" "") 16200 (unspec:DF [(float_extend:DF 16201 (match_operand:SF 2 "register_operand" ""))] 16202 UNSPEC_SINCOS_COS)) 16203 (set (match_operand:DF 1 "register_operand" "") 16204 (unspec:DF [(float_extend:DF 16205 (match_dup 2))] UNSPEC_SINCOS_SIN))] 16206 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 16207 && !reload_completed && !reload_in_progress" 16208 [(set (match_dup 1) (unspec:DF [(float_extend:DF 16209 (match_dup 2))] UNSPEC_SIN))] 16210 "") 16211 16212(define_split 16213 [(set (match_operand:DF 0 "register_operand" "") 16214 (unspec:DF [(float_extend:DF 16215 (match_operand:SF 2 "register_operand" ""))] 16216 UNSPEC_SINCOS_COS)) 16217 (set (match_operand:DF 1 "register_operand" "") 16218 (unspec:DF [(float_extend:DF 16219 (match_dup 2))] UNSPEC_SINCOS_SIN))] 16220 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 16221 && !reload_completed && !reload_in_progress" 16222 [(set (match_dup 0) (unspec:DF [(float_extend:DF 16223 (match_dup 2))] UNSPEC_COS))] 16224 "") 16225 16226(define_insn "sincosxf3" 16227 [(set (match_operand:XF 0 "register_operand" "=f") 16228 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 16229 UNSPEC_SINCOS_COS)) 16230 (set (match_operand:XF 1 "register_operand" "=u") 16231 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16232 "TARGET_USE_FANCY_MATH_387 16233 && flag_unsafe_math_optimizations" 16234 "fsincos" 16235 [(set_attr "type" "fpspc") 16236 (set_attr "mode" "XF")]) 16237 16238(define_split 16239 [(set (match_operand:XF 0 "register_operand" "") 16240 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 16241 UNSPEC_SINCOS_COS)) 16242 (set (match_operand:XF 1 "register_operand" "") 16243 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16244 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 16245 && !reload_completed && !reload_in_progress" 16246 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))] 16247 "") 16248 16249(define_split 16250 [(set (match_operand:XF 0 "register_operand" "") 16251 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 16252 UNSPEC_SINCOS_COS)) 16253 (set (match_operand:XF 1 "register_operand" "") 16254 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 16255 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 16256 && !reload_completed && !reload_in_progress" 16257 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))] 16258 "") 16259 16260(define_insn "*tandf3_1" 16261 [(set (match_operand:DF 0 "register_operand" "=f") 16262 (unspec:DF [(match_operand:DF 2 "register_operand" "0")] 16263 UNSPEC_TAN_ONE)) 16264 (set (match_operand:DF 1 "register_operand" "=u") 16265 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))] 16266 "TARGET_USE_FANCY_MATH_387 16267 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16268 && flag_unsafe_math_optimizations" 16269 "fptan" 16270 [(set_attr "type" "fpspc") 16271 (set_attr "mode" "DF")]) 16272 16273;; optimize sequence: fptan 16274;; fstp %st(0) 16275;; fld1 16276;; into fptan insn. 16277 16278(define_peephole2 16279 [(parallel[(set (match_operand:DF 0 "register_operand" "") 16280 (unspec:DF [(match_operand:DF 2 "register_operand" "")] 16281 UNSPEC_TAN_ONE)) 16282 (set (match_operand:DF 1 "register_operand" "") 16283 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]) 16284 (set (match_dup 0) 16285 (match_operand:DF 3 "immediate_operand" ""))] 16286 "standard_80387_constant_p (operands[3]) == 2" 16287 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE)) 16288 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])] 16289 "") 16290 16291(define_expand "tandf2" 16292 [(parallel [(set (match_dup 2) 16293 (unspec:DF [(match_operand:DF 1 "register_operand" "")] 16294 UNSPEC_TAN_ONE)) 16295 (set (match_operand:DF 0 "register_operand" "") 16296 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])] 16297 "TARGET_USE_FANCY_MATH_387 16298 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16299 && flag_unsafe_math_optimizations" 16300{ 16301 operands[2] = gen_reg_rtx (DFmode); 16302}) 16303 16304(define_insn "*tansf3_1" 16305 [(set (match_operand:SF 0 "register_operand" "=f") 16306 (unspec:SF [(match_operand:SF 2 "register_operand" "0")] 16307 UNSPEC_TAN_ONE)) 16308 (set (match_operand:SF 1 "register_operand" "=u") 16309 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))] 16310 "TARGET_USE_FANCY_MATH_387 16311 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16312 && flag_unsafe_math_optimizations" 16313 "fptan" 16314 [(set_attr "type" "fpspc") 16315 (set_attr "mode" "SF")]) 16316 16317;; optimize sequence: fptan 16318;; fstp %st(0) 16319;; fld1 16320;; into fptan insn. 16321 16322(define_peephole2 16323 [(parallel[(set (match_operand:SF 0 "register_operand" "") 16324 (unspec:SF [(match_operand:SF 2 "register_operand" "")] 16325 UNSPEC_TAN_ONE)) 16326 (set (match_operand:SF 1 "register_operand" "") 16327 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]) 16328 (set (match_dup 0) 16329 (match_operand:SF 3 "immediate_operand" ""))] 16330 "standard_80387_constant_p (operands[3]) == 2" 16331 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE)) 16332 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])] 16333 "") 16334 16335(define_expand "tansf2" 16336 [(parallel [(set (match_dup 2) 16337 (unspec:SF [(match_operand:SF 1 "register_operand" "")] 16338 UNSPEC_TAN_ONE)) 16339 (set (match_operand:SF 0 "register_operand" "") 16340 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])] 16341 "TARGET_USE_FANCY_MATH_387 16342 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16343 && flag_unsafe_math_optimizations" 16344{ 16345 operands[2] = gen_reg_rtx (SFmode); 16346}) 16347 16348(define_insn "*tanxf3_1" 16349 [(set (match_operand:XF 0 "register_operand" "=f") 16350 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 16351 UNSPEC_TAN_ONE)) 16352 (set (match_operand:XF 1 "register_operand" "=u") 16353 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))] 16354 "TARGET_USE_FANCY_MATH_387 16355 && flag_unsafe_math_optimizations" 16356 "fptan" 16357 [(set_attr "type" "fpspc") 16358 (set_attr "mode" "XF")]) 16359 16360;; optimize sequence: fptan 16361;; fstp %st(0) 16362;; fld1 16363;; into fptan insn. 16364 16365(define_peephole2 16366 [(parallel[(set (match_operand:XF 0 "register_operand" "") 16367 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 16368 UNSPEC_TAN_ONE)) 16369 (set (match_operand:XF 1 "register_operand" "") 16370 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]) 16371 (set (match_dup 0) 16372 (match_operand:XF 3 "immediate_operand" ""))] 16373 "standard_80387_constant_p (operands[3]) == 2" 16374 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE)) 16375 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])] 16376 "") 16377 16378(define_expand "tanxf2" 16379 [(parallel [(set (match_dup 2) 16380 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 16381 UNSPEC_TAN_ONE)) 16382 (set (match_operand:XF 0 "register_operand" "") 16383 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])] 16384 "TARGET_USE_FANCY_MATH_387 16385 && flag_unsafe_math_optimizations" 16386{ 16387 operands[2] = gen_reg_rtx (XFmode); 16388}) 16389 16390(define_insn "atan2df3_1" 16391 [(set (match_operand:DF 0 "register_operand" "=f") 16392 (unspec:DF [(match_operand:DF 2 "register_operand" "0") 16393 (match_operand:DF 1 "register_operand" "u")] 16394 UNSPEC_FPATAN)) 16395 (clobber (match_scratch:DF 3 "=1"))] 16396 "TARGET_USE_FANCY_MATH_387 16397 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16398 && flag_unsafe_math_optimizations" 16399 "fpatan" 16400 [(set_attr "type" "fpspc") 16401 (set_attr "mode" "DF")]) 16402 16403(define_expand "atan2df3" 16404 [(use (match_operand:DF 0 "register_operand" "")) 16405 (use (match_operand:DF 2 "register_operand" "")) 16406 (use (match_operand:DF 1 "register_operand" ""))] 16407 "TARGET_USE_FANCY_MATH_387 16408 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16409 && flag_unsafe_math_optimizations" 16410{ 16411 rtx copy = gen_reg_rtx (DFmode); 16412 emit_move_insn (copy, operands[1]); 16413 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2])); 16414 DONE; 16415}) 16416 16417(define_expand "atandf2" 16418 [(parallel [(set (match_operand:DF 0 "register_operand" "") 16419 (unspec:DF [(match_dup 2) 16420 (match_operand:DF 1 "register_operand" "")] 16421 UNSPEC_FPATAN)) 16422 (clobber (match_scratch:DF 3 ""))])] 16423 "TARGET_USE_FANCY_MATH_387 16424 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16425 && flag_unsafe_math_optimizations" 16426{ 16427 operands[2] = gen_reg_rtx (DFmode); 16428 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */ 16429}) 16430 16431(define_insn "atan2sf3_1" 16432 [(set (match_operand:SF 0 "register_operand" "=f") 16433 (unspec:SF [(match_operand:SF 2 "register_operand" "0") 16434 (match_operand:SF 1 "register_operand" "u")] 16435 UNSPEC_FPATAN)) 16436 (clobber (match_scratch:SF 3 "=1"))] 16437 "TARGET_USE_FANCY_MATH_387 16438 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16439 && flag_unsafe_math_optimizations" 16440 "fpatan" 16441 [(set_attr "type" "fpspc") 16442 (set_attr "mode" "SF")]) 16443 16444(define_expand "atan2sf3" 16445 [(use (match_operand:SF 0 "register_operand" "")) 16446 (use (match_operand:SF 2 "register_operand" "")) 16447 (use (match_operand:SF 1 "register_operand" ""))] 16448 "TARGET_USE_FANCY_MATH_387 16449 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16450 && flag_unsafe_math_optimizations" 16451{ 16452 rtx copy = gen_reg_rtx (SFmode); 16453 emit_move_insn (copy, operands[1]); 16454 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2])); 16455 DONE; 16456}) 16457 16458(define_expand "atansf2" 16459 [(parallel [(set (match_operand:SF 0 "register_operand" "") 16460 (unspec:SF [(match_dup 2) 16461 (match_operand:SF 1 "register_operand" "")] 16462 UNSPEC_FPATAN)) 16463 (clobber (match_scratch:SF 3 ""))])] 16464 "TARGET_USE_FANCY_MATH_387 16465 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16466 && flag_unsafe_math_optimizations" 16467{ 16468 operands[2] = gen_reg_rtx (SFmode); 16469 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */ 16470}) 16471 16472(define_insn "atan2xf3_1" 16473 [(set (match_operand:XF 0 "register_operand" "=f") 16474 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16475 (match_operand:XF 1 "register_operand" "u")] 16476 UNSPEC_FPATAN)) 16477 (clobber (match_scratch:XF 3 "=1"))] 16478 "TARGET_USE_FANCY_MATH_387 16479 && flag_unsafe_math_optimizations" 16480 "fpatan" 16481 [(set_attr "type" "fpspc") 16482 (set_attr "mode" "XF")]) 16483 16484(define_expand "atan2xf3" 16485 [(use (match_operand:XF 0 "register_operand" "")) 16486 (use (match_operand:XF 2 "register_operand" "")) 16487 (use (match_operand:XF 1 "register_operand" ""))] 16488 "TARGET_USE_FANCY_MATH_387 16489 && flag_unsafe_math_optimizations" 16490{ 16491 rtx copy = gen_reg_rtx (XFmode); 16492 emit_move_insn (copy, operands[1]); 16493 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2])); 16494 DONE; 16495}) 16496 16497(define_expand "atanxf2" 16498 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16499 (unspec:XF [(match_dup 2) 16500 (match_operand:XF 1 "register_operand" "")] 16501 UNSPEC_FPATAN)) 16502 (clobber (match_scratch:XF 3 ""))])] 16503 "TARGET_USE_FANCY_MATH_387 16504 && flag_unsafe_math_optimizations" 16505{ 16506 operands[2] = gen_reg_rtx (XFmode); 16507 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 16508}) 16509 16510(define_expand "asindf2" 16511 [(set (match_dup 2) 16512 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16513 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16514 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16515 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16516 (parallel [(set (match_dup 7) 16517 (unspec:XF [(match_dup 6) (match_dup 2)] 16518 UNSPEC_FPATAN)) 16519 (clobber (match_scratch:XF 8 ""))]) 16520 (set (match_operand:DF 0 "register_operand" "") 16521 (float_truncate:DF (match_dup 7)))] 16522 "TARGET_USE_FANCY_MATH_387 16523 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16524 && flag_unsafe_math_optimizations" 16525{ 16526 int i; 16527 16528 for (i=2; i<8; i++) 16529 operands[i] = gen_reg_rtx (XFmode); 16530 16531 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16532}) 16533 16534(define_expand "asinsf2" 16535 [(set (match_dup 2) 16536 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16537 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16538 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16539 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16540 (parallel [(set (match_dup 7) 16541 (unspec:XF [(match_dup 6) (match_dup 2)] 16542 UNSPEC_FPATAN)) 16543 (clobber (match_scratch:XF 8 ""))]) 16544 (set (match_operand:SF 0 "register_operand" "") 16545 (float_truncate:SF (match_dup 7)))] 16546 "TARGET_USE_FANCY_MATH_387 16547 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16548 && flag_unsafe_math_optimizations" 16549{ 16550 int i; 16551 16552 for (i=2; i<8; i++) 16553 operands[i] = gen_reg_rtx (XFmode); 16554 16555 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16556}) 16557 16558(define_expand "asinxf2" 16559 [(set (match_dup 2) 16560 (mult:XF (match_operand:XF 1 "register_operand" "") 16561 (match_dup 1))) 16562 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 16563 (set (match_dup 5) (sqrt:XF (match_dup 4))) 16564 (parallel [(set (match_operand:XF 0 "register_operand" "") 16565 (unspec:XF [(match_dup 5) (match_dup 1)] 16566 UNSPEC_FPATAN)) 16567 (clobber (match_scratch:XF 6 ""))])] 16568 "TARGET_USE_FANCY_MATH_387 16569 && flag_unsafe_math_optimizations" 16570{ 16571 int i; 16572 16573 for (i=2; i<6; i++) 16574 operands[i] = gen_reg_rtx (XFmode); 16575 16576 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16577}) 16578 16579(define_expand "acosdf2" 16580 [(set (match_dup 2) 16581 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16582 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16583 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16584 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16585 (parallel [(set (match_dup 7) 16586 (unspec:XF [(match_dup 2) (match_dup 6)] 16587 UNSPEC_FPATAN)) 16588 (clobber (match_scratch:XF 8 ""))]) 16589 (set (match_operand:DF 0 "register_operand" "") 16590 (float_truncate:DF (match_dup 7)))] 16591 "TARGET_USE_FANCY_MATH_387 16592 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16593 && flag_unsafe_math_optimizations" 16594{ 16595 int i; 16596 16597 for (i=2; i<8; i++) 16598 operands[i] = gen_reg_rtx (XFmode); 16599 16600 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16601}) 16602 16603(define_expand "acossf2" 16604 [(set (match_dup 2) 16605 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16606 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16607 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16608 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16609 (parallel [(set (match_dup 7) 16610 (unspec:XF [(match_dup 2) (match_dup 6)] 16611 UNSPEC_FPATAN)) 16612 (clobber (match_scratch:XF 8 ""))]) 16613 (set (match_operand:SF 0 "register_operand" "") 16614 (float_truncate:SF (match_dup 7)))] 16615 "TARGET_USE_FANCY_MATH_387 16616 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16617 && flag_unsafe_math_optimizations" 16618{ 16619 int i; 16620 16621 for (i=2; i<8; i++) 16622 operands[i] = gen_reg_rtx (XFmode); 16623 16624 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16625}) 16626 16627(define_expand "acosxf2" 16628 [(set (match_dup 2) 16629 (mult:XF (match_operand:XF 1 "register_operand" "") 16630 (match_dup 1))) 16631 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 16632 (set (match_dup 5) (sqrt:XF (match_dup 4))) 16633 (parallel [(set (match_operand:XF 0 "register_operand" "") 16634 (unspec:XF [(match_dup 1) (match_dup 5)] 16635 UNSPEC_FPATAN)) 16636 (clobber (match_scratch:XF 6 ""))])] 16637 "TARGET_USE_FANCY_MATH_387 16638 && flag_unsafe_math_optimizations" 16639{ 16640 int i; 16641 16642 for (i=2; i<6; i++) 16643 operands[i] = gen_reg_rtx (XFmode); 16644 16645 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16646}) 16647 16648(define_insn "fyl2x_xf3" 16649 [(set (match_operand:XF 0 "register_operand" "=f") 16650 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16651 (match_operand:XF 1 "register_operand" "u")] 16652 UNSPEC_FYL2X)) 16653 (clobber (match_scratch:XF 3 "=1"))] 16654 "TARGET_USE_FANCY_MATH_387 16655 && flag_unsafe_math_optimizations" 16656 "fyl2x" 16657 [(set_attr "type" "fpspc") 16658 (set_attr "mode" "XF")]) 16659 16660(define_expand "logsf2" 16661 [(set (match_dup 2) 16662 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16663 (parallel [(set (match_dup 4) 16664 (unspec:XF [(match_dup 2) 16665 (match_dup 3)] UNSPEC_FYL2X)) 16666 (clobber (match_scratch:XF 5 ""))]) 16667 (set (match_operand:SF 0 "register_operand" "") 16668 (float_truncate:SF (match_dup 4)))] 16669 "TARGET_USE_FANCY_MATH_387 16670 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16671 && flag_unsafe_math_optimizations" 16672{ 16673 rtx temp; 16674 16675 operands[2] = gen_reg_rtx (XFmode); 16676 operands[3] = gen_reg_rtx (XFmode); 16677 operands[4] = gen_reg_rtx (XFmode); 16678 16679 temp = standard_80387_constant_rtx (4); /* fldln2 */ 16680 emit_move_insn (operands[3], temp); 16681}) 16682 16683(define_expand "logdf2" 16684 [(set (match_dup 2) 16685 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16686 (parallel [(set (match_dup 4) 16687 (unspec:XF [(match_dup 2) 16688 (match_dup 3)] UNSPEC_FYL2X)) 16689 (clobber (match_scratch:XF 5 ""))]) 16690 (set (match_operand:DF 0 "register_operand" "") 16691 (float_truncate:DF (match_dup 4)))] 16692 "TARGET_USE_FANCY_MATH_387 16693 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16694 && flag_unsafe_math_optimizations" 16695{ 16696 rtx temp; 16697 16698 operands[2] = gen_reg_rtx (XFmode); 16699 operands[3] = gen_reg_rtx (XFmode); 16700 operands[4] = gen_reg_rtx (XFmode); 16701 16702 temp = standard_80387_constant_rtx (4); /* fldln2 */ 16703 emit_move_insn (operands[3], temp); 16704}) 16705 16706(define_expand "logxf2" 16707 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16708 (unspec:XF [(match_operand:XF 1 "register_operand" "") 16709 (match_dup 2)] UNSPEC_FYL2X)) 16710 (clobber (match_scratch:XF 3 ""))])] 16711 "TARGET_USE_FANCY_MATH_387 16712 && flag_unsafe_math_optimizations" 16713{ 16714 rtx temp; 16715 16716 operands[2] = gen_reg_rtx (XFmode); 16717 temp = standard_80387_constant_rtx (4); /* fldln2 */ 16718 emit_move_insn (operands[2], temp); 16719}) 16720 16721(define_expand "log10sf2" 16722 [(set (match_dup 2) 16723 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16724 (parallel [(set (match_dup 4) 16725 (unspec:XF [(match_dup 2) 16726 (match_dup 3)] UNSPEC_FYL2X)) 16727 (clobber (match_scratch:XF 5 ""))]) 16728 (set (match_operand:SF 0 "register_operand" "") 16729 (float_truncate:SF (match_dup 4)))] 16730 "TARGET_USE_FANCY_MATH_387 16731 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16732 && flag_unsafe_math_optimizations" 16733{ 16734 rtx temp; 16735 16736 operands[2] = gen_reg_rtx (XFmode); 16737 operands[3] = gen_reg_rtx (XFmode); 16738 operands[4] = gen_reg_rtx (XFmode); 16739 16740 temp = standard_80387_constant_rtx (3); /* fldlg2 */ 16741 emit_move_insn (operands[3], temp); 16742}) 16743 16744(define_expand "log10df2" 16745 [(set (match_dup 2) 16746 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16747 (parallel [(set (match_dup 4) 16748 (unspec:XF [(match_dup 2) 16749 (match_dup 3)] UNSPEC_FYL2X)) 16750 (clobber (match_scratch:XF 5 ""))]) 16751 (set (match_operand:DF 0 "register_operand" "") 16752 (float_truncate:DF (match_dup 4)))] 16753 "TARGET_USE_FANCY_MATH_387 16754 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16755 && flag_unsafe_math_optimizations" 16756{ 16757 rtx temp; 16758 16759 operands[2] = gen_reg_rtx (XFmode); 16760 operands[3] = gen_reg_rtx (XFmode); 16761 operands[4] = gen_reg_rtx (XFmode); 16762 16763 temp = standard_80387_constant_rtx (3); /* fldlg2 */ 16764 emit_move_insn (operands[3], temp); 16765}) 16766 16767(define_expand "log10xf2" 16768 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16769 (unspec:XF [(match_operand:XF 1 "register_operand" "") 16770 (match_dup 2)] UNSPEC_FYL2X)) 16771 (clobber (match_scratch:XF 3 ""))])] 16772 "TARGET_USE_FANCY_MATH_387 16773 && flag_unsafe_math_optimizations" 16774{ 16775 rtx temp; 16776 16777 operands[2] = gen_reg_rtx (XFmode); 16778 temp = standard_80387_constant_rtx (3); /* fldlg2 */ 16779 emit_move_insn (operands[2], temp); 16780}) 16781 16782(define_expand "log2sf2" 16783 [(set (match_dup 2) 16784 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16785 (parallel [(set (match_dup 4) 16786 (unspec:XF [(match_dup 2) 16787 (match_dup 3)] UNSPEC_FYL2X)) 16788 (clobber (match_scratch:XF 5 ""))]) 16789 (set (match_operand:SF 0 "register_operand" "") 16790 (float_truncate:SF (match_dup 4)))] 16791 "TARGET_USE_FANCY_MATH_387 16792 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16793 && flag_unsafe_math_optimizations" 16794{ 16795 operands[2] = gen_reg_rtx (XFmode); 16796 operands[3] = gen_reg_rtx (XFmode); 16797 operands[4] = gen_reg_rtx (XFmode); 16798 16799 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16800}) 16801 16802(define_expand "log2df2" 16803 [(set (match_dup 2) 16804 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16805 (parallel [(set (match_dup 4) 16806 (unspec:XF [(match_dup 2) 16807 (match_dup 3)] UNSPEC_FYL2X)) 16808 (clobber (match_scratch:XF 5 ""))]) 16809 (set (match_operand:DF 0 "register_operand" "") 16810 (float_truncate:DF (match_dup 4)))] 16811 "TARGET_USE_FANCY_MATH_387 16812 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16813 && flag_unsafe_math_optimizations" 16814{ 16815 operands[2] = gen_reg_rtx (XFmode); 16816 operands[3] = gen_reg_rtx (XFmode); 16817 operands[4] = gen_reg_rtx (XFmode); 16818 16819 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16820}) 16821 16822(define_expand "log2xf2" 16823 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16824 (unspec:XF [(match_operand:XF 1 "register_operand" "") 16825 (match_dup 2)] UNSPEC_FYL2X)) 16826 (clobber (match_scratch:XF 3 ""))])] 16827 "TARGET_USE_FANCY_MATH_387 16828 && flag_unsafe_math_optimizations" 16829{ 16830 operands[2] = gen_reg_rtx (XFmode); 16831 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 16832}) 16833 16834(define_insn "fyl2xp1_xf3" 16835 [(set (match_operand:XF 0 "register_operand" "=f") 16836 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16837 (match_operand:XF 1 "register_operand" "u")] 16838 UNSPEC_FYL2XP1)) 16839 (clobber (match_scratch:XF 3 "=1"))] 16840 "TARGET_USE_FANCY_MATH_387 16841 && flag_unsafe_math_optimizations" 16842 "fyl2xp1" 16843 [(set_attr "type" "fpspc") 16844 (set_attr "mode" "XF")]) 16845 16846(define_expand "log1psf2" 16847 [(use (match_operand:SF 0 "register_operand" "")) 16848 (use (match_operand:SF 1 "register_operand" ""))] 16849 "TARGET_USE_FANCY_MATH_387 16850 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16851 && flag_unsafe_math_optimizations" 16852{ 16853 rtx op0 = gen_reg_rtx (XFmode); 16854 rtx op1 = gen_reg_rtx (XFmode); 16855 16856 emit_insn (gen_extendsfxf2 (op1, operands[1])); 16857 ix86_emit_i387_log1p (op0, op1); 16858 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 16859 DONE; 16860}) 16861 16862(define_expand "log1pdf2" 16863 [(use (match_operand:DF 0 "register_operand" "")) 16864 (use (match_operand:DF 1 "register_operand" ""))] 16865 "TARGET_USE_FANCY_MATH_387 16866 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16867 && flag_unsafe_math_optimizations" 16868{ 16869 rtx op0 = gen_reg_rtx (XFmode); 16870 rtx op1 = gen_reg_rtx (XFmode); 16871 16872 emit_insn (gen_extenddfxf2 (op1, operands[1])); 16873 ix86_emit_i387_log1p (op0, op1); 16874 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 16875 DONE; 16876}) 16877 16878(define_expand "log1pxf2" 16879 [(use (match_operand:XF 0 "register_operand" "")) 16880 (use (match_operand:XF 1 "register_operand" ""))] 16881 "TARGET_USE_FANCY_MATH_387 16882 && flag_unsafe_math_optimizations" 16883{ 16884 ix86_emit_i387_log1p (operands[0], operands[1]); 16885 DONE; 16886}) 16887 16888(define_insn "*fxtractxf3" 16889 [(set (match_operand:XF 0 "register_operand" "=f") 16890 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 16891 UNSPEC_XTRACT_FRACT)) 16892 (set (match_operand:XF 1 "register_operand" "=u") 16893 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))] 16894 "TARGET_USE_FANCY_MATH_387 16895 && flag_unsafe_math_optimizations" 16896 "fxtract" 16897 [(set_attr "type" "fpspc") 16898 (set_attr "mode" "XF")]) 16899 16900(define_expand "logbsf2" 16901 [(set (match_dup 2) 16902 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16903 (parallel [(set (match_dup 3) 16904 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT)) 16905 (set (match_dup 4) 16906 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]) 16907 (set (match_operand:SF 0 "register_operand" "") 16908 (float_truncate:SF (match_dup 4)))] 16909 "TARGET_USE_FANCY_MATH_387 16910 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16911 && flag_unsafe_math_optimizations" 16912{ 16913 operands[2] = gen_reg_rtx (XFmode); 16914 operands[3] = gen_reg_rtx (XFmode); 16915 operands[4] = gen_reg_rtx (XFmode); 16916}) 16917 16918(define_expand "logbdf2" 16919 [(set (match_dup 2) 16920 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16921 (parallel [(set (match_dup 3) 16922 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT)) 16923 (set (match_dup 4) 16924 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]) 16925 (set (match_operand:DF 0 "register_operand" "") 16926 (float_truncate:DF (match_dup 4)))] 16927 "TARGET_USE_FANCY_MATH_387 16928 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16929 && flag_unsafe_math_optimizations" 16930{ 16931 operands[2] = gen_reg_rtx (XFmode); 16932 operands[3] = gen_reg_rtx (XFmode); 16933 operands[4] = gen_reg_rtx (XFmode); 16934}) 16935 16936(define_expand "logbxf2" 16937 [(parallel [(set (match_dup 2) 16938 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 16939 UNSPEC_XTRACT_FRACT)) 16940 (set (match_operand:XF 0 "register_operand" "") 16941 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 16942 "TARGET_USE_FANCY_MATH_387 16943 && flag_unsafe_math_optimizations" 16944{ 16945 operands[2] = gen_reg_rtx (XFmode); 16946}) 16947 16948(define_expand "ilogbsi2" 16949 [(parallel [(set (match_dup 2) 16950 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 16951 UNSPEC_XTRACT_FRACT)) 16952 (set (match_operand:XF 3 "register_operand" "") 16953 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))]) 16954 (parallel [(set (match_operand:SI 0 "register_operand" "") 16955 (fix:SI (match_dup 3))) 16956 (clobber (reg:CC FLAGS_REG))])] 16957 "TARGET_USE_FANCY_MATH_387 16958 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16959 && flag_unsafe_math_optimizations" 16960{ 16961 operands[2] = gen_reg_rtx (XFmode); 16962 operands[3] = gen_reg_rtx (XFmode); 16963}) 16964 16965(define_insn "*f2xm1xf2" 16966 [(set (match_operand:XF 0 "register_operand" "=f") 16967 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16968 UNSPEC_F2XM1))] 16969 "TARGET_USE_FANCY_MATH_387 16970 && flag_unsafe_math_optimizations" 16971 "f2xm1" 16972 [(set_attr "type" "fpspc") 16973 (set_attr "mode" "XF")]) 16974 16975(define_insn "*fscalexf4" 16976 [(set (match_operand:XF 0 "register_operand" "=f") 16977 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16978 (match_operand:XF 3 "register_operand" "1")] 16979 UNSPEC_FSCALE_FRACT)) 16980 (set (match_operand:XF 1 "register_operand" "=u") 16981 (unspec:XF [(match_dup 2) (match_dup 3)] 16982 UNSPEC_FSCALE_EXP))] 16983 "TARGET_USE_FANCY_MATH_387 16984 && flag_unsafe_math_optimizations" 16985 "fscale" 16986 [(set_attr "type" "fpspc") 16987 (set_attr "mode" "XF")]) 16988 16989(define_expand "expsf2" 16990 [(set (match_dup 2) 16991 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16992 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16993 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16994 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16995 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16996 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 16997 (parallel [(set (match_dup 10) 16998 (unspec:XF [(match_dup 9) (match_dup 5)] 16999 UNSPEC_FSCALE_FRACT)) 17000 (set (match_dup 11) 17001 (unspec:XF [(match_dup 9) (match_dup 5)] 17002 UNSPEC_FSCALE_EXP))]) 17003 (set (match_operand:SF 0 "register_operand" "") 17004 (float_truncate:SF (match_dup 10)))] 17005 "TARGET_USE_FANCY_MATH_387 17006 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17007 && flag_unsafe_math_optimizations" 17008{ 17009 rtx temp; 17010 int i; 17011 17012 for (i=2; i<12; i++) 17013 operands[i] = gen_reg_rtx (XFmode); 17014 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17015 emit_move_insn (operands[3], temp); 17016 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 17017}) 17018 17019(define_expand "expdf2" 17020 [(set (match_dup 2) 17021 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 17022 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 17023 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 17024 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 17025 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 17026 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 17027 (parallel [(set (match_dup 10) 17028 (unspec:XF [(match_dup 9) (match_dup 5)] 17029 UNSPEC_FSCALE_FRACT)) 17030 (set (match_dup 11) 17031 (unspec:XF [(match_dup 9) (match_dup 5)] 17032 UNSPEC_FSCALE_EXP))]) 17033 (set (match_operand:DF 0 "register_operand" "") 17034 (float_truncate:DF (match_dup 10)))] 17035 "TARGET_USE_FANCY_MATH_387 17036 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17037 && flag_unsafe_math_optimizations" 17038{ 17039 rtx temp; 17040 int i; 17041 17042 for (i=2; i<12; i++) 17043 operands[i] = gen_reg_rtx (XFmode); 17044 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17045 emit_move_insn (operands[3], temp); 17046 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 17047}) 17048 17049(define_expand "expxf2" 17050 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 17051 (match_dup 2))) 17052 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 17053 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 17054 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 17055 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 17056 (parallel [(set (match_operand:XF 0 "register_operand" "") 17057 (unspec:XF [(match_dup 8) (match_dup 4)] 17058 UNSPEC_FSCALE_FRACT)) 17059 (set (match_dup 9) 17060 (unspec:XF [(match_dup 8) (match_dup 4)] 17061 UNSPEC_FSCALE_EXP))])] 17062 "TARGET_USE_FANCY_MATH_387 17063 && flag_unsafe_math_optimizations" 17064{ 17065 rtx temp; 17066 int i; 17067 17068 for (i=2; i<10; i++) 17069 operands[i] = gen_reg_rtx (XFmode); 17070 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17071 emit_move_insn (operands[2], temp); 17072 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ 17073}) 17074 17075(define_expand "exp10sf2" 17076 [(set (match_dup 2) 17077 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 17078 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 17079 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 17080 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 17081 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 17082 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 17083 (parallel [(set (match_dup 10) 17084 (unspec:XF [(match_dup 9) (match_dup 5)] 17085 UNSPEC_FSCALE_FRACT)) 17086 (set (match_dup 11) 17087 (unspec:XF [(match_dup 9) (match_dup 5)] 17088 UNSPEC_FSCALE_EXP))]) 17089 (set (match_operand:SF 0 "register_operand" "") 17090 (float_truncate:SF (match_dup 10)))] 17091 "TARGET_USE_FANCY_MATH_387 17092 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17093 && flag_unsafe_math_optimizations" 17094{ 17095 rtx temp; 17096 int i; 17097 17098 for (i=2; i<12; i++) 17099 operands[i] = gen_reg_rtx (XFmode); 17100 temp = standard_80387_constant_rtx (6); /* fldl2t */ 17101 emit_move_insn (operands[3], temp); 17102 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 17103}) 17104 17105(define_expand "exp10df2" 17106 [(set (match_dup 2) 17107 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 17108 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 17109 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 17110 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 17111 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 17112 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 17113 (parallel [(set (match_dup 10) 17114 (unspec:XF [(match_dup 9) (match_dup 5)] 17115 UNSPEC_FSCALE_FRACT)) 17116 (set (match_dup 11) 17117 (unspec:XF [(match_dup 9) (match_dup 5)] 17118 UNSPEC_FSCALE_EXP))]) 17119 (set (match_operand:DF 0 "register_operand" "") 17120 (float_truncate:DF (match_dup 10)))] 17121 "TARGET_USE_FANCY_MATH_387 17122 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17123 && flag_unsafe_math_optimizations" 17124{ 17125 rtx temp; 17126 int i; 17127 17128 for (i=2; i<12; i++) 17129 operands[i] = gen_reg_rtx (XFmode); 17130 temp = standard_80387_constant_rtx (6); /* fldl2t */ 17131 emit_move_insn (operands[3], temp); 17132 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 17133}) 17134 17135(define_expand "exp10xf2" 17136 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 17137 (match_dup 2))) 17138 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 17139 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 17140 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 17141 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 17142 (parallel [(set (match_operand:XF 0 "register_operand" "") 17143 (unspec:XF [(match_dup 8) (match_dup 4)] 17144 UNSPEC_FSCALE_FRACT)) 17145 (set (match_dup 9) 17146 (unspec:XF [(match_dup 8) (match_dup 4)] 17147 UNSPEC_FSCALE_EXP))])] 17148 "TARGET_USE_FANCY_MATH_387 17149 && flag_unsafe_math_optimizations" 17150{ 17151 rtx temp; 17152 int i; 17153 17154 for (i=2; i<10; i++) 17155 operands[i] = gen_reg_rtx (XFmode); 17156 temp = standard_80387_constant_rtx (6); /* fldl2t */ 17157 emit_move_insn (operands[2], temp); 17158 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ 17159}) 17160 17161(define_expand "exp2sf2" 17162 [(set (match_dup 2) 17163 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 17164 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT)) 17165 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3))) 17166 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1)) 17167 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6))) 17168 (parallel [(set (match_dup 8) 17169 (unspec:XF [(match_dup 7) (match_dup 3)] 17170 UNSPEC_FSCALE_FRACT)) 17171 (set (match_dup 9) 17172 (unspec:XF [(match_dup 7) (match_dup 3)] 17173 UNSPEC_FSCALE_EXP))]) 17174 (set (match_operand:SF 0 "register_operand" "") 17175 (float_truncate:SF (match_dup 8)))] 17176 "TARGET_USE_FANCY_MATH_387 17177 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17178 && flag_unsafe_math_optimizations" 17179{ 17180 int i; 17181 17182 for (i=2; i<10; i++) 17183 operands[i] = gen_reg_rtx (XFmode); 17184 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */ 17185}) 17186 17187(define_expand "exp2df2" 17188 [(set (match_dup 2) 17189 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 17190 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT)) 17191 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3))) 17192 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1)) 17193 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6))) 17194 (parallel [(set (match_dup 8) 17195 (unspec:XF [(match_dup 7) (match_dup 3)] 17196 UNSPEC_FSCALE_FRACT)) 17197 (set (match_dup 9) 17198 (unspec:XF [(match_dup 7) (match_dup 3)] 17199 UNSPEC_FSCALE_EXP))]) 17200 (set (match_operand:DF 0 "register_operand" "") 17201 (float_truncate:DF (match_dup 8)))] 17202 "TARGET_USE_FANCY_MATH_387 17203 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17204 && flag_unsafe_math_optimizations" 17205{ 17206 int i; 17207 17208 for (i=2; i<10; i++) 17209 operands[i] = gen_reg_rtx (XFmode); 17210 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */ 17211}) 17212 17213(define_expand "exp2xf2" 17214 [(set (match_dup 2) (match_operand:XF 1 "register_operand" "")) 17215 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT)) 17216 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3))) 17217 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1)) 17218 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6))) 17219 (parallel [(set (match_operand:XF 0 "register_operand" "") 17220 (unspec:XF [(match_dup 7) (match_dup 3)] 17221 UNSPEC_FSCALE_FRACT)) 17222 (set (match_dup 8) 17223 (unspec:XF [(match_dup 7) (match_dup 3)] 17224 UNSPEC_FSCALE_EXP))])] 17225 "TARGET_USE_FANCY_MATH_387 17226 && flag_unsafe_math_optimizations" 17227{ 17228 int i; 17229 17230 for (i=2; i<9; i++) 17231 operands[i] = gen_reg_rtx (XFmode); 17232 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */ 17233}) 17234 17235(define_expand "expm1df2" 17236 [(set (match_dup 2) 17237 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 17238 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 17239 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 17240 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 17241 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 17242 (parallel [(set (match_dup 8) 17243 (unspec:XF [(match_dup 7) (match_dup 5)] 17244 UNSPEC_FSCALE_FRACT)) 17245 (set (match_dup 9) 17246 (unspec:XF [(match_dup 7) (match_dup 5)] 17247 UNSPEC_FSCALE_EXP))]) 17248 (parallel [(set (match_dup 11) 17249 (unspec:XF [(match_dup 10) (match_dup 9)] 17250 UNSPEC_FSCALE_FRACT)) 17251 (set (match_dup 12) 17252 (unspec:XF [(match_dup 10) (match_dup 9)] 17253 UNSPEC_FSCALE_EXP))]) 17254 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10))) 17255 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8))) 17256 (set (match_operand:DF 0 "register_operand" "") 17257 (float_truncate:DF (match_dup 14)))] 17258 "TARGET_USE_FANCY_MATH_387 17259 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17260 && flag_unsafe_math_optimizations" 17261{ 17262 rtx temp; 17263 int i; 17264 17265 for (i=2; i<15; i++) 17266 operands[i] = gen_reg_rtx (XFmode); 17267 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17268 emit_move_insn (operands[3], temp); 17269 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */ 17270}) 17271 17272(define_expand "expm1sf2" 17273 [(set (match_dup 2) 17274 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 17275 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 17276 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 17277 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 17278 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 17279 (parallel [(set (match_dup 8) 17280 (unspec:XF [(match_dup 7) (match_dup 5)] 17281 UNSPEC_FSCALE_FRACT)) 17282 (set (match_dup 9) 17283 (unspec:XF [(match_dup 7) (match_dup 5)] 17284 UNSPEC_FSCALE_EXP))]) 17285 (parallel [(set (match_dup 11) 17286 (unspec:XF [(match_dup 10) (match_dup 9)] 17287 UNSPEC_FSCALE_FRACT)) 17288 (set (match_dup 12) 17289 (unspec:XF [(match_dup 10) (match_dup 9)] 17290 UNSPEC_FSCALE_EXP))]) 17291 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10))) 17292 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8))) 17293 (set (match_operand:SF 0 "register_operand" "") 17294 (float_truncate:SF (match_dup 14)))] 17295 "TARGET_USE_FANCY_MATH_387 17296 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17297 && flag_unsafe_math_optimizations" 17298{ 17299 rtx temp; 17300 int i; 17301 17302 for (i=2; i<15; i++) 17303 operands[i] = gen_reg_rtx (XFmode); 17304 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17305 emit_move_insn (operands[3], temp); 17306 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */ 17307}) 17308 17309(define_expand "expm1xf2" 17310 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 17311 (match_dup 2))) 17312 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 17313 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 17314 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 17315 (parallel [(set (match_dup 7) 17316 (unspec:XF [(match_dup 6) (match_dup 4)] 17317 UNSPEC_FSCALE_FRACT)) 17318 (set (match_dup 8) 17319 (unspec:XF [(match_dup 6) (match_dup 4)] 17320 UNSPEC_FSCALE_EXP))]) 17321 (parallel [(set (match_dup 10) 17322 (unspec:XF [(match_dup 9) (match_dup 8)] 17323 UNSPEC_FSCALE_FRACT)) 17324 (set (match_dup 11) 17325 (unspec:XF [(match_dup 9) (match_dup 8)] 17326 UNSPEC_FSCALE_EXP))]) 17327 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9))) 17328 (set (match_operand:XF 0 "register_operand" "") 17329 (plus:XF (match_dup 12) (match_dup 7)))] 17330 "TARGET_USE_FANCY_MATH_387 17331 && flag_unsafe_math_optimizations" 17332{ 17333 rtx temp; 17334 int i; 17335 17336 for (i=2; i<13; i++) 17337 operands[i] = gen_reg_rtx (XFmode); 17338 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17339 emit_move_insn (operands[2], temp); 17340 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */ 17341}) 17342 17343(define_expand "ldexpdf3" 17344 [(set (match_dup 3) 17345 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 17346 (set (match_dup 4) 17347 (float:XF (match_operand:SI 2 "register_operand" ""))) 17348 (parallel [(set (match_dup 5) 17349 (unspec:XF [(match_dup 3) (match_dup 4)] 17350 UNSPEC_FSCALE_FRACT)) 17351 (set (match_dup 6) 17352 (unspec:XF [(match_dup 3) (match_dup 4)] 17353 UNSPEC_FSCALE_EXP))]) 17354 (set (match_operand:DF 0 "register_operand" "") 17355 (float_truncate:DF (match_dup 5)))] 17356 "TARGET_USE_FANCY_MATH_387 17357 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17358 && flag_unsafe_math_optimizations" 17359{ 17360 int i; 17361 17362 for (i=3; i<7; i++) 17363 operands[i] = gen_reg_rtx (XFmode); 17364}) 17365 17366(define_expand "ldexpsf3" 17367 [(set (match_dup 3) 17368 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 17369 (set (match_dup 4) 17370 (float:XF (match_operand:SI 2 "register_operand" ""))) 17371 (parallel [(set (match_dup 5) 17372 (unspec:XF [(match_dup 3) (match_dup 4)] 17373 UNSPEC_FSCALE_FRACT)) 17374 (set (match_dup 6) 17375 (unspec:XF [(match_dup 3) (match_dup 4)] 17376 UNSPEC_FSCALE_EXP))]) 17377 (set (match_operand:SF 0 "register_operand" "") 17378 (float_truncate:SF (match_dup 5)))] 17379 "TARGET_USE_FANCY_MATH_387 17380 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17381 && flag_unsafe_math_optimizations" 17382{ 17383 int i; 17384 17385 for (i=3; i<7; i++) 17386 operands[i] = gen_reg_rtx (XFmode); 17387}) 17388 17389(define_expand "ldexpxf3" 17390 [(set (match_dup 3) 17391 (float:XF (match_operand:SI 2 "register_operand" ""))) 17392 (parallel [(set (match_operand:XF 0 " register_operand" "") 17393 (unspec:XF [(match_operand:XF 1 "register_operand" "") 17394 (match_dup 3)] 17395 UNSPEC_FSCALE_FRACT)) 17396 (set (match_dup 4) 17397 (unspec:XF [(match_dup 1) (match_dup 3)] 17398 UNSPEC_FSCALE_EXP))])] 17399 "TARGET_USE_FANCY_MATH_387 17400 && flag_unsafe_math_optimizations" 17401{ 17402 int i; 17403 17404 for (i=3; i<5; i++) 17405 operands[i] = gen_reg_rtx (XFmode); 17406}) 17407 17408 17409(define_insn "frndintxf2" 17410 [(set (match_operand:XF 0 "register_operand" "=f") 17411 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17412 UNSPEC_FRNDINT))] 17413 "TARGET_USE_FANCY_MATH_387 17414 && flag_unsafe_math_optimizations" 17415 "frndint" 17416 [(set_attr "type" "fpspc") 17417 (set_attr "mode" "XF")]) 17418 17419(define_expand "rintdf2" 17420 [(use (match_operand:DF 0 "register_operand" "")) 17421 (use (match_operand:DF 1 "register_operand" ""))] 17422 "TARGET_USE_FANCY_MATH_387 17423 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17424 && flag_unsafe_math_optimizations" 17425{ 17426 rtx op0 = gen_reg_rtx (XFmode); 17427 rtx op1 = gen_reg_rtx (XFmode); 17428 17429 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17430 emit_insn (gen_frndintxf2 (op0, op1)); 17431 17432 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17433 DONE; 17434}) 17435 17436(define_expand "rintsf2" 17437 [(use (match_operand:SF 0 "register_operand" "")) 17438 (use (match_operand:SF 1 "register_operand" ""))] 17439 "TARGET_USE_FANCY_MATH_387 17440 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17441 && flag_unsafe_math_optimizations" 17442{ 17443 rtx op0 = gen_reg_rtx (XFmode); 17444 rtx op1 = gen_reg_rtx (XFmode); 17445 17446 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17447 emit_insn (gen_frndintxf2 (op0, op1)); 17448 17449 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17450 DONE; 17451}) 17452 17453(define_expand "rintxf2" 17454 [(use (match_operand:XF 0 "register_operand" "")) 17455 (use (match_operand:XF 1 "register_operand" ""))] 17456 "TARGET_USE_FANCY_MATH_387 17457 && flag_unsafe_math_optimizations" 17458{ 17459 emit_insn (gen_frndintxf2 (operands[0], operands[1])); 17460 DONE; 17461}) 17462 17463(define_insn_and_split "*fistdi2_1" 17464 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17465 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17466 UNSPEC_FIST))] 17467 "TARGET_USE_FANCY_MATH_387 17468 && flag_unsafe_math_optimizations 17469 && !(reload_completed || reload_in_progress)" 17470 "#" 17471 "&& 1" 17472 [(const_int 0)] 17473{ 17474 if (memory_operand (operands[0], VOIDmode)) 17475 emit_insn (gen_fistdi2 (operands[0], operands[1])); 17476 else 17477 { 17478 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP); 17479 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1], 17480 operands[2])); 17481 } 17482 DONE; 17483} 17484 [(set_attr "type" "fpspc") 17485 (set_attr "mode" "DI")]) 17486 17487(define_insn "fistdi2" 17488 [(set (match_operand:DI 0 "memory_operand" "=m") 17489 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 17490 UNSPEC_FIST)) 17491 (clobber (match_scratch:XF 2 "=&1f"))] 17492 "TARGET_USE_FANCY_MATH_387 17493 && flag_unsafe_math_optimizations" 17494 "* return output_fix_trunc (insn, operands, 0);" 17495 [(set_attr "type" "fpspc") 17496 (set_attr "mode" "DI")]) 17497 17498(define_insn "fistdi2_with_temp" 17499 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17500 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17501 UNSPEC_FIST)) 17502 (clobber (match_operand:DI 2 "memory_operand" "=m,m")) 17503 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 17504 "TARGET_USE_FANCY_MATH_387 17505 && flag_unsafe_math_optimizations" 17506 "#" 17507 [(set_attr "type" "fpspc") 17508 (set_attr "mode" "DI")]) 17509 17510(define_split 17511 [(set (match_operand:DI 0 "register_operand" "") 17512 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17513 UNSPEC_FIST)) 17514 (clobber (match_operand:DI 2 "memory_operand" "")) 17515 (clobber (match_scratch 3 ""))] 17516 "reload_completed" 17517 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 17518 (clobber (match_dup 3))]) 17519 (set (match_dup 0) (match_dup 2))] 17520 "") 17521 17522(define_split 17523 [(set (match_operand:DI 0 "memory_operand" "") 17524 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17525 UNSPEC_FIST)) 17526 (clobber (match_operand:DI 2 "memory_operand" "")) 17527 (clobber (match_scratch 3 ""))] 17528 "reload_completed" 17529 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 17530 (clobber (match_dup 3))])] 17531 "") 17532 17533(define_insn_and_split "*fist<mode>2_1" 17534 [(set (match_operand:X87MODEI12 0 "register_operand" "=r") 17535 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17536 UNSPEC_FIST))] 17537 "TARGET_USE_FANCY_MATH_387 17538 && flag_unsafe_math_optimizations 17539 && !(reload_completed || reload_in_progress)" 17540 "#" 17541 "&& 1" 17542 [(const_int 0)] 17543{ 17544 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17545 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1], 17546 operands[2])); 17547 DONE; 17548} 17549 [(set_attr "type" "fpspc") 17550 (set_attr "mode" "<MODE>")]) 17551 17552(define_insn "fist<mode>2" 17553 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 17554 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17555 UNSPEC_FIST))] 17556 "TARGET_USE_FANCY_MATH_387 17557 && flag_unsafe_math_optimizations" 17558 "* return output_fix_trunc (insn, operands, 0);" 17559 [(set_attr "type" "fpspc") 17560 (set_attr "mode" "<MODE>")]) 17561 17562(define_insn "fist<mode>2_with_temp" 17563 [(set (match_operand:X87MODEI12 0 "register_operand" "=r") 17564 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17565 UNSPEC_FIST)) 17566 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))] 17567 "TARGET_USE_FANCY_MATH_387 17568 && flag_unsafe_math_optimizations" 17569 "#" 17570 [(set_attr "type" "fpspc") 17571 (set_attr "mode" "<MODE>")]) 17572 17573(define_split 17574 [(set (match_operand:X87MODEI12 0 "register_operand" "") 17575 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17576 UNSPEC_FIST)) 17577 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))] 17578 "reload_completed" 17579 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] 17580 UNSPEC_FIST)) 17581 (set (match_dup 0) (match_dup 2))] 17582 "") 17583 17584(define_split 17585 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 17586 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17587 UNSPEC_FIST)) 17588 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))] 17589 "reload_completed" 17590 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] 17591 UNSPEC_FIST))] 17592 "") 17593 17594(define_expand "lrint<mode>2" 17595 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") 17596 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] 17597 UNSPEC_FIST))] 17598 "TARGET_USE_FANCY_MATH_387 17599 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17600 && flag_unsafe_math_optimizations" 17601 "") 17602 17603;; Rounding mode control word calculation could clobber FLAGS_REG. 17604(define_insn_and_split "frndintxf2_floor" 17605 [(set (match_operand:XF 0 "register_operand" "=f") 17606 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17607 UNSPEC_FRNDINT_FLOOR)) 17608 (clobber (reg:CC FLAGS_REG))] 17609 "TARGET_USE_FANCY_MATH_387 17610 && flag_unsafe_math_optimizations 17611 && !(reload_completed || reload_in_progress)" 17612 "#" 17613 "&& 1" 17614 [(const_int 0)] 17615{ 17616 ix86_optimize_mode_switching[I387_FLOOR] = 1; 17617 17618 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17619 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); 17620 17621 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1], 17622 operands[2], operands[3])); 17623 DONE; 17624} 17625 [(set_attr "type" "frndint") 17626 (set_attr "i387_cw" "floor") 17627 (set_attr "mode" "XF")]) 17628 17629(define_insn "frndintxf2_floor_i387" 17630 [(set (match_operand:XF 0 "register_operand" "=f") 17631 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17632 UNSPEC_FRNDINT_FLOOR)) 17633 (use (match_operand:HI 2 "memory_operand" "m")) 17634 (use (match_operand:HI 3 "memory_operand" "m"))] 17635 "TARGET_USE_FANCY_MATH_387 17636 && flag_unsafe_math_optimizations" 17637 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 17638 [(set_attr "type" "frndint") 17639 (set_attr "i387_cw" "floor") 17640 (set_attr "mode" "XF")]) 17641 17642(define_expand "floorxf2" 17643 [(use (match_operand:XF 0 "register_operand" "")) 17644 (use (match_operand:XF 1 "register_operand" ""))] 17645 "TARGET_USE_FANCY_MATH_387 17646 && flag_unsafe_math_optimizations" 17647{ 17648 emit_insn (gen_frndintxf2_floor (operands[0], operands[1])); 17649 DONE; 17650}) 17651 17652(define_expand "floordf2" 17653 [(use (match_operand:DF 0 "register_operand" "")) 17654 (use (match_operand:DF 1 "register_operand" ""))] 17655 "TARGET_USE_FANCY_MATH_387 17656 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17657 && flag_unsafe_math_optimizations" 17658{ 17659 rtx op0 = gen_reg_rtx (XFmode); 17660 rtx op1 = gen_reg_rtx (XFmode); 17661 17662 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17663 emit_insn (gen_frndintxf2_floor (op0, op1)); 17664 17665 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17666 DONE; 17667}) 17668 17669(define_expand "floorsf2" 17670 [(use (match_operand:SF 0 "register_operand" "")) 17671 (use (match_operand:SF 1 "register_operand" ""))] 17672 "TARGET_USE_FANCY_MATH_387 17673 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17674 && flag_unsafe_math_optimizations" 17675{ 17676 rtx op0 = gen_reg_rtx (XFmode); 17677 rtx op1 = gen_reg_rtx (XFmode); 17678 17679 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17680 emit_insn (gen_frndintxf2_floor (op0, op1)); 17681 17682 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17683 DONE; 17684}) 17685 17686(define_insn_and_split "*fist<mode>2_floor_1" 17687 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 17688 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")] 17689 UNSPEC_FIST_FLOOR)) 17690 (clobber (reg:CC FLAGS_REG))] 17691 "TARGET_USE_FANCY_MATH_387 17692 && flag_unsafe_math_optimizations 17693 && !(reload_completed || reload_in_progress)" 17694 "#" 17695 "&& 1" 17696 [(const_int 0)] 17697{ 17698 ix86_optimize_mode_switching[I387_FLOOR] = 1; 17699 17700 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17701 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); 17702 if (memory_operand (operands[0], VOIDmode)) 17703 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1], 17704 operands[2], operands[3])); 17705 else 17706 { 17707 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17708 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1], 17709 operands[2], operands[3], 17710 operands[4])); 17711 } 17712 DONE; 17713} 17714 [(set_attr "type" "fistp") 17715 (set_attr "i387_cw" "floor") 17716 (set_attr "mode" "<MODE>")]) 17717 17718(define_insn "fistdi2_floor" 17719 [(set (match_operand:DI 0 "memory_operand" "=m") 17720 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 17721 UNSPEC_FIST_FLOOR)) 17722 (use (match_operand:HI 2 "memory_operand" "m")) 17723 (use (match_operand:HI 3 "memory_operand" "m")) 17724 (clobber (match_scratch:XF 4 "=&1f"))] 17725 "TARGET_USE_FANCY_MATH_387 17726 && flag_unsafe_math_optimizations" 17727 "* return output_fix_trunc (insn, operands, 0);" 17728 [(set_attr "type" "fistp") 17729 (set_attr "i387_cw" "floor") 17730 (set_attr "mode" "DI")]) 17731 17732(define_insn "fistdi2_floor_with_temp" 17733 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17734 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17735 UNSPEC_FIST_FLOOR)) 17736 (use (match_operand:HI 2 "memory_operand" "m,m")) 17737 (use (match_operand:HI 3 "memory_operand" "m,m")) 17738 (clobber (match_operand:DI 4 "memory_operand" "=m,m")) 17739 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 17740 "TARGET_USE_FANCY_MATH_387 17741 && flag_unsafe_math_optimizations" 17742 "#" 17743 [(set_attr "type" "fistp") 17744 (set_attr "i387_cw" "floor") 17745 (set_attr "mode" "DI")]) 17746 17747(define_split 17748 [(set (match_operand:DI 0 "register_operand" "") 17749 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17750 UNSPEC_FIST_FLOOR)) 17751 (use (match_operand:HI 2 "memory_operand" "")) 17752 (use (match_operand:HI 3 "memory_operand" "")) 17753 (clobber (match_operand:DI 4 "memory_operand" "")) 17754 (clobber (match_scratch 5 ""))] 17755 "reload_completed" 17756 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) 17757 (use (match_dup 2)) 17758 (use (match_dup 3)) 17759 (clobber (match_dup 5))]) 17760 (set (match_dup 0) (match_dup 4))] 17761 "") 17762 17763(define_split 17764 [(set (match_operand:DI 0 "memory_operand" "") 17765 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17766 UNSPEC_FIST_FLOOR)) 17767 (use (match_operand:HI 2 "memory_operand" "")) 17768 (use (match_operand:HI 3 "memory_operand" "")) 17769 (clobber (match_operand:DI 4 "memory_operand" "")) 17770 (clobber (match_scratch 5 ""))] 17771 "reload_completed" 17772 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) 17773 (use (match_dup 2)) 17774 (use (match_dup 3)) 17775 (clobber (match_dup 5))])] 17776 "") 17777 17778(define_insn "fist<mode>2_floor" 17779 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 17780 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17781 UNSPEC_FIST_FLOOR)) 17782 (use (match_operand:HI 2 "memory_operand" "m")) 17783 (use (match_operand:HI 3 "memory_operand" "m"))] 17784 "TARGET_USE_FANCY_MATH_387 17785 && flag_unsafe_math_optimizations" 17786 "* return output_fix_trunc (insn, operands, 0);" 17787 [(set_attr "type" "fistp") 17788 (set_attr "i387_cw" "floor") 17789 (set_attr "mode" "<MODE>")]) 17790 17791(define_insn "fist<mode>2_floor_with_temp" 17792 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") 17793 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")] 17794 UNSPEC_FIST_FLOOR)) 17795 (use (match_operand:HI 2 "memory_operand" "m,m")) 17796 (use (match_operand:HI 3 "memory_operand" "m,m")) 17797 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))] 17798 "TARGET_USE_FANCY_MATH_387 17799 && flag_unsafe_math_optimizations" 17800 "#" 17801 [(set_attr "type" "fistp") 17802 (set_attr "i387_cw" "floor") 17803 (set_attr "mode" "<MODE>")]) 17804 17805(define_split 17806 [(set (match_operand:X87MODEI12 0 "register_operand" "") 17807 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17808 UNSPEC_FIST_FLOOR)) 17809 (use (match_operand:HI 2 "memory_operand" "")) 17810 (use (match_operand:HI 3 "memory_operand" "")) 17811 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 17812 "reload_completed" 17813 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)] 17814 UNSPEC_FIST_FLOOR)) 17815 (use (match_dup 2)) 17816 (use (match_dup 3))]) 17817 (set (match_dup 0) (match_dup 4))] 17818 "") 17819 17820(define_split 17821 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 17822 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17823 UNSPEC_FIST_FLOOR)) 17824 (use (match_operand:HI 2 "memory_operand" "")) 17825 (use (match_operand:HI 3 "memory_operand" "")) 17826 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 17827 "reload_completed" 17828 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] 17829 UNSPEC_FIST_FLOOR)) 17830 (use (match_dup 2)) 17831 (use (match_dup 3))])] 17832 "") 17833 17834(define_expand "lfloor<mode>2" 17835 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") 17836 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] 17837 UNSPEC_FIST_FLOOR)) 17838 (clobber (reg:CC FLAGS_REG))])] 17839 "TARGET_USE_FANCY_MATH_387 17840 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17841 && flag_unsafe_math_optimizations" 17842 "") 17843 17844;; Rounding mode control word calculation could clobber FLAGS_REG. 17845(define_insn_and_split "frndintxf2_ceil" 17846 [(set (match_operand:XF 0 "register_operand" "=f") 17847 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17848 UNSPEC_FRNDINT_CEIL)) 17849 (clobber (reg:CC FLAGS_REG))] 17850 "TARGET_USE_FANCY_MATH_387 17851 && flag_unsafe_math_optimizations 17852 && !(reload_completed || reload_in_progress)" 17853 "#" 17854 "&& 1" 17855 [(const_int 0)] 17856{ 17857 ix86_optimize_mode_switching[I387_CEIL] = 1; 17858 17859 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17860 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); 17861 17862 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1], 17863 operands[2], operands[3])); 17864 DONE; 17865} 17866 [(set_attr "type" "frndint") 17867 (set_attr "i387_cw" "ceil") 17868 (set_attr "mode" "XF")]) 17869 17870(define_insn "frndintxf2_ceil_i387" 17871 [(set (match_operand:XF 0 "register_operand" "=f") 17872 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17873 UNSPEC_FRNDINT_CEIL)) 17874 (use (match_operand:HI 2 "memory_operand" "m")) 17875 (use (match_operand:HI 3 "memory_operand" "m"))] 17876 "TARGET_USE_FANCY_MATH_387 17877 && flag_unsafe_math_optimizations" 17878 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 17879 [(set_attr "type" "frndint") 17880 (set_attr "i387_cw" "ceil") 17881 (set_attr "mode" "XF")]) 17882 17883(define_expand "ceilxf2" 17884 [(use (match_operand:XF 0 "register_operand" "")) 17885 (use (match_operand:XF 1 "register_operand" ""))] 17886 "TARGET_USE_FANCY_MATH_387 17887 && flag_unsafe_math_optimizations" 17888{ 17889 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1])); 17890 DONE; 17891}) 17892 17893(define_expand "ceildf2" 17894 [(use (match_operand:DF 0 "register_operand" "")) 17895 (use (match_operand:DF 1 "register_operand" ""))] 17896 "TARGET_USE_FANCY_MATH_387 17897 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17898 && flag_unsafe_math_optimizations" 17899{ 17900 rtx op0 = gen_reg_rtx (XFmode); 17901 rtx op1 = gen_reg_rtx (XFmode); 17902 17903 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17904 emit_insn (gen_frndintxf2_ceil (op0, op1)); 17905 17906 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17907 DONE; 17908}) 17909 17910(define_expand "ceilsf2" 17911 [(use (match_operand:SF 0 "register_operand" "")) 17912 (use (match_operand:SF 1 "register_operand" ""))] 17913 "TARGET_USE_FANCY_MATH_387 17914 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17915 && flag_unsafe_math_optimizations" 17916{ 17917 rtx op0 = gen_reg_rtx (XFmode); 17918 rtx op1 = gen_reg_rtx (XFmode); 17919 17920 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17921 emit_insn (gen_frndintxf2_ceil (op0, op1)); 17922 17923 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17924 DONE; 17925}) 17926 17927(define_insn_and_split "*fist<mode>2_ceil_1" 17928 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 17929 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")] 17930 UNSPEC_FIST_CEIL)) 17931 (clobber (reg:CC FLAGS_REG))] 17932 "TARGET_USE_FANCY_MATH_387 17933 && flag_unsafe_math_optimizations 17934 && !(reload_completed || reload_in_progress)" 17935 "#" 17936 "&& 1" 17937 [(const_int 0)] 17938{ 17939 ix86_optimize_mode_switching[I387_CEIL] = 1; 17940 17941 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17942 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); 17943 if (memory_operand (operands[0], VOIDmode)) 17944 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1], 17945 operands[2], operands[3])); 17946 else 17947 { 17948 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17949 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1], 17950 operands[2], operands[3], 17951 operands[4])); 17952 } 17953 DONE; 17954} 17955 [(set_attr "type" "fistp") 17956 (set_attr "i387_cw" "ceil") 17957 (set_attr "mode" "<MODE>")]) 17958 17959(define_insn "fistdi2_ceil" 17960 [(set (match_operand:DI 0 "memory_operand" "=m") 17961 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 17962 UNSPEC_FIST_CEIL)) 17963 (use (match_operand:HI 2 "memory_operand" "m")) 17964 (use (match_operand:HI 3 "memory_operand" "m")) 17965 (clobber (match_scratch:XF 4 "=&1f"))] 17966 "TARGET_USE_FANCY_MATH_387 17967 && flag_unsafe_math_optimizations" 17968 "* return output_fix_trunc (insn, operands, 0);" 17969 [(set_attr "type" "fistp") 17970 (set_attr "i387_cw" "ceil") 17971 (set_attr "mode" "DI")]) 17972 17973(define_insn "fistdi2_ceil_with_temp" 17974 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17975 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17976 UNSPEC_FIST_CEIL)) 17977 (use (match_operand:HI 2 "memory_operand" "m,m")) 17978 (use (match_operand:HI 3 "memory_operand" "m,m")) 17979 (clobber (match_operand:DI 4 "memory_operand" "=m,m")) 17980 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 17981 "TARGET_USE_FANCY_MATH_387 17982 && flag_unsafe_math_optimizations" 17983 "#" 17984 [(set_attr "type" "fistp") 17985 (set_attr "i387_cw" "ceil") 17986 (set_attr "mode" "DI")]) 17987 17988(define_split 17989 [(set (match_operand:DI 0 "register_operand" "") 17990 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17991 UNSPEC_FIST_CEIL)) 17992 (use (match_operand:HI 2 "memory_operand" "")) 17993 (use (match_operand:HI 3 "memory_operand" "")) 17994 (clobber (match_operand:DI 4 "memory_operand" "")) 17995 (clobber (match_scratch 5 ""))] 17996 "reload_completed" 17997 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) 17998 (use (match_dup 2)) 17999 (use (match_dup 3)) 18000 (clobber (match_dup 5))]) 18001 (set (match_dup 0) (match_dup 4))] 18002 "") 18003 18004(define_split 18005 [(set (match_operand:DI 0 "memory_operand" "") 18006 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 18007 UNSPEC_FIST_CEIL)) 18008 (use (match_operand:HI 2 "memory_operand" "")) 18009 (use (match_operand:HI 3 "memory_operand" "")) 18010 (clobber (match_operand:DI 4 "memory_operand" "")) 18011 (clobber (match_scratch 5 ""))] 18012 "reload_completed" 18013 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) 18014 (use (match_dup 2)) 18015 (use (match_dup 3)) 18016 (clobber (match_dup 5))])] 18017 "") 18018 18019(define_insn "fist<mode>2_ceil" 18020 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 18021 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 18022 UNSPEC_FIST_CEIL)) 18023 (use (match_operand:HI 2 "memory_operand" "m")) 18024 (use (match_operand:HI 3 "memory_operand" "m"))] 18025 "TARGET_USE_FANCY_MATH_387 18026 && flag_unsafe_math_optimizations" 18027 "* return output_fix_trunc (insn, operands, 0);" 18028 [(set_attr "type" "fistp") 18029 (set_attr "i387_cw" "ceil") 18030 (set_attr "mode" "<MODE>")]) 18031 18032(define_insn "fist<mode>2_ceil_with_temp" 18033 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") 18034 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")] 18035 UNSPEC_FIST_CEIL)) 18036 (use (match_operand:HI 2 "memory_operand" "m,m")) 18037 (use (match_operand:HI 3 "memory_operand" "m,m")) 18038 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))] 18039 "TARGET_USE_FANCY_MATH_387 18040 && flag_unsafe_math_optimizations" 18041 "#" 18042 [(set_attr "type" "fistp") 18043 (set_attr "i387_cw" "ceil") 18044 (set_attr "mode" "<MODE>")]) 18045 18046(define_split 18047 [(set (match_operand:X87MODEI12 0 "register_operand" "") 18048 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 18049 UNSPEC_FIST_CEIL)) 18050 (use (match_operand:HI 2 "memory_operand" "")) 18051 (use (match_operand:HI 3 "memory_operand" "")) 18052 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 18053 "reload_completed" 18054 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)] 18055 UNSPEC_FIST_CEIL)) 18056 (use (match_dup 2)) 18057 (use (match_dup 3))]) 18058 (set (match_dup 0) (match_dup 4))] 18059 "") 18060 18061(define_split 18062 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 18063 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 18064 UNSPEC_FIST_CEIL)) 18065 (use (match_operand:HI 2 "memory_operand" "")) 18066 (use (match_operand:HI 3 "memory_operand" "")) 18067 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 18068 "reload_completed" 18069 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] 18070 UNSPEC_FIST_CEIL)) 18071 (use (match_dup 2)) 18072 (use (match_dup 3))])] 18073 "") 18074 18075(define_expand "lceil<mode>2" 18076 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") 18077 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] 18078 UNSPEC_FIST_CEIL)) 18079 (clobber (reg:CC FLAGS_REG))])] 18080 "TARGET_USE_FANCY_MATH_387 18081 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 18082 && flag_unsafe_math_optimizations" 18083 "") 18084 18085;; Rounding mode control word calculation could clobber FLAGS_REG. 18086(define_insn_and_split "frndintxf2_trunc" 18087 [(set (match_operand:XF 0 "register_operand" "=f") 18088 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 18089 UNSPEC_FRNDINT_TRUNC)) 18090 (clobber (reg:CC FLAGS_REG))] 18091 "TARGET_USE_FANCY_MATH_387 18092 && flag_unsafe_math_optimizations 18093 && !(reload_completed || reload_in_progress)" 18094 "#" 18095 "&& 1" 18096 [(const_int 0)] 18097{ 18098 ix86_optimize_mode_switching[I387_TRUNC] = 1; 18099 18100 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 18101 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 18102 18103 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1], 18104 operands[2], operands[3])); 18105 DONE; 18106} 18107 [(set_attr "type" "frndint") 18108 (set_attr "i387_cw" "trunc") 18109 (set_attr "mode" "XF")]) 18110 18111(define_insn "frndintxf2_trunc_i387" 18112 [(set (match_operand:XF 0 "register_operand" "=f") 18113 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 18114 UNSPEC_FRNDINT_TRUNC)) 18115 (use (match_operand:HI 2 "memory_operand" "m")) 18116 (use (match_operand:HI 3 "memory_operand" "m"))] 18117 "TARGET_USE_FANCY_MATH_387 18118 && flag_unsafe_math_optimizations" 18119 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 18120 [(set_attr "type" "frndint") 18121 (set_attr "i387_cw" "trunc") 18122 (set_attr "mode" "XF")]) 18123 18124(define_expand "btruncxf2" 18125 [(use (match_operand:XF 0 "register_operand" "")) 18126 (use (match_operand:XF 1 "register_operand" ""))] 18127 "TARGET_USE_FANCY_MATH_387 18128 && flag_unsafe_math_optimizations" 18129{ 18130 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1])); 18131 DONE; 18132}) 18133 18134(define_expand "btruncdf2" 18135 [(use (match_operand:DF 0 "register_operand" "")) 18136 (use (match_operand:DF 1 "register_operand" ""))] 18137 "TARGET_USE_FANCY_MATH_387 18138 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 18139 && flag_unsafe_math_optimizations" 18140{ 18141 rtx op0 = gen_reg_rtx (XFmode); 18142 rtx op1 = gen_reg_rtx (XFmode); 18143 18144 emit_insn (gen_extenddfxf2 (op1, operands[1])); 18145 emit_insn (gen_frndintxf2_trunc (op0, op1)); 18146 18147 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 18148 DONE; 18149}) 18150 18151(define_expand "btruncsf2" 18152 [(use (match_operand:SF 0 "register_operand" "")) 18153 (use (match_operand:SF 1 "register_operand" ""))] 18154 "TARGET_USE_FANCY_MATH_387 18155 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 18156 && flag_unsafe_math_optimizations" 18157{ 18158 rtx op0 = gen_reg_rtx (XFmode); 18159 rtx op1 = gen_reg_rtx (XFmode); 18160 18161 emit_insn (gen_extendsfxf2 (op1, operands[1])); 18162 emit_insn (gen_frndintxf2_trunc (op0, op1)); 18163 18164 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 18165 DONE; 18166}) 18167 18168;; Rounding mode control word calculation could clobber FLAGS_REG. 18169(define_insn_and_split "frndintxf2_mask_pm" 18170 [(set (match_operand:XF 0 "register_operand" "=f") 18171 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 18172 UNSPEC_FRNDINT_MASK_PM)) 18173 (clobber (reg:CC FLAGS_REG))] 18174 "TARGET_USE_FANCY_MATH_387 18175 && flag_unsafe_math_optimizations 18176 && !(reload_completed || reload_in_progress)" 18177 "#" 18178 "&& 1" 18179 [(const_int 0)] 18180{ 18181 ix86_optimize_mode_switching[I387_MASK_PM] = 1; 18182 18183 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 18184 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM); 18185 18186 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1], 18187 operands[2], operands[3])); 18188 DONE; 18189} 18190 [(set_attr "type" "frndint") 18191 (set_attr "i387_cw" "mask_pm") 18192 (set_attr "mode" "XF")]) 18193 18194(define_insn "frndintxf2_mask_pm_i387" 18195 [(set (match_operand:XF 0 "register_operand" "=f") 18196 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 18197 UNSPEC_FRNDINT_MASK_PM)) 18198 (use (match_operand:HI 2 "memory_operand" "m")) 18199 (use (match_operand:HI 3 "memory_operand" "m"))] 18200 "TARGET_USE_FANCY_MATH_387 18201 && flag_unsafe_math_optimizations" 18202 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2" 18203 [(set_attr "type" "frndint") 18204 (set_attr "i387_cw" "mask_pm") 18205 (set_attr "mode" "XF")]) 18206 18207(define_expand "nearbyintxf2" 18208 [(use (match_operand:XF 0 "register_operand" "")) 18209 (use (match_operand:XF 1 "register_operand" ""))] 18210 "TARGET_USE_FANCY_MATH_387 18211 && flag_unsafe_math_optimizations" 18212{ 18213 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1])); 18214 18215 DONE; 18216}) 18217 18218(define_expand "nearbyintdf2" 18219 [(use (match_operand:DF 0 "register_operand" "")) 18220 (use (match_operand:DF 1 "register_operand" ""))] 18221 "TARGET_USE_FANCY_MATH_387 18222 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 18223 && flag_unsafe_math_optimizations" 18224{ 18225 rtx op0 = gen_reg_rtx (XFmode); 18226 rtx op1 = gen_reg_rtx (XFmode); 18227 18228 emit_insn (gen_extenddfxf2 (op1, operands[1])); 18229 emit_insn (gen_frndintxf2_mask_pm (op0, op1)); 18230 18231 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 18232 DONE; 18233}) 18234 18235(define_expand "nearbyintsf2" 18236 [(use (match_operand:SF 0 "register_operand" "")) 18237 (use (match_operand:SF 1 "register_operand" ""))] 18238 "TARGET_USE_FANCY_MATH_387 18239 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 18240 && flag_unsafe_math_optimizations" 18241{ 18242 rtx op0 = gen_reg_rtx (XFmode); 18243 rtx op1 = gen_reg_rtx (XFmode); 18244 18245 emit_insn (gen_extendsfxf2 (op1, operands[1])); 18246 emit_insn (gen_frndintxf2_mask_pm (op0, op1)); 18247 18248 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 18249 DONE; 18250}) 18251 18252 18253;; Block operation instructions 18254 18255(define_insn "cld" 18256 [(set (reg:SI DIRFLAG_REG) (const_int 0))] 18257 "" 18258 "cld" 18259 [(set_attr "type" "cld")]) 18260 18261(define_expand "movmemsi" 18262 [(use (match_operand:BLK 0 "memory_operand" "")) 18263 (use (match_operand:BLK 1 "memory_operand" "")) 18264 (use (match_operand:SI 2 "nonmemory_operand" "")) 18265 (use (match_operand:SI 3 "const_int_operand" ""))] 18266 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS" 18267{ 18268 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3])) 18269 DONE; 18270 else 18271 FAIL; 18272}) 18273 18274(define_expand "movmemdi" 18275 [(use (match_operand:BLK 0 "memory_operand" "")) 18276 (use (match_operand:BLK 1 "memory_operand" "")) 18277 (use (match_operand:DI 2 "nonmemory_operand" "")) 18278 (use (match_operand:DI 3 "const_int_operand" ""))] 18279 "TARGET_64BIT" 18280{ 18281 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3])) 18282 DONE; 18283 else 18284 FAIL; 18285}) 18286 18287;; Most CPUs don't like single string operations 18288;; Handle this case here to simplify previous expander. 18289 18290(define_expand "strmov" 18291 [(set (match_dup 4) (match_operand 3 "memory_operand" "")) 18292 (set (match_operand 1 "memory_operand" "") (match_dup 4)) 18293 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5)) 18294 (clobber (reg:CC FLAGS_REG))]) 18295 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6)) 18296 (clobber (reg:CC FLAGS_REG))])] 18297 "" 18298{ 18299 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1]))); 18300 18301 /* If .md ever supports :P for Pmode, these can be directly 18302 in the pattern above. */ 18303 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust); 18304 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust); 18305 18306 if (TARGET_SINGLE_STRINGOP || optimize_size) 18307 { 18308 emit_insn (gen_strmov_singleop (operands[0], operands[1], 18309 operands[2], operands[3], 18310 operands[5], operands[6])); 18311 DONE; 18312 } 18313 18314 operands[4] = gen_reg_rtx (GET_MODE (operands[1])); 18315}) 18316 18317(define_expand "strmov_singleop" 18318 [(parallel [(set (match_operand 1 "memory_operand" "") 18319 (match_operand 3 "memory_operand" "")) 18320 (set (match_operand 0 "register_operand" "") 18321 (match_operand 4 "" "")) 18322 (set (match_operand 2 "register_operand" "") 18323 (match_operand 5 "" "")) 18324 (use (reg:SI DIRFLAG_REG))])] 18325 "TARGET_SINGLE_STRINGOP || optimize_size" 18326 "") 18327 18328(define_insn "*strmovdi_rex_1" 18329 [(set (mem:DI (match_operand:DI 2 "register_operand" "0")) 18330 (mem:DI (match_operand:DI 3 "register_operand" "1"))) 18331 (set (match_operand:DI 0 "register_operand" "=D") 18332 (plus:DI (match_dup 2) 18333 (const_int 8))) 18334 (set (match_operand:DI 1 "register_operand" "=S") 18335 (plus:DI (match_dup 3) 18336 (const_int 8))) 18337 (use (reg:SI DIRFLAG_REG))] 18338 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18339 "movsq" 18340 [(set_attr "type" "str") 18341 (set_attr "mode" "DI") 18342 (set_attr "memory" "both")]) 18343 18344(define_insn "*strmovsi_1" 18345 [(set (mem:SI (match_operand:SI 2 "register_operand" "0")) 18346 (mem:SI (match_operand:SI 3 "register_operand" "1"))) 18347 (set (match_operand:SI 0 "register_operand" "=D") 18348 (plus:SI (match_dup 2) 18349 (const_int 4))) 18350 (set (match_operand:SI 1 "register_operand" "=S") 18351 (plus:SI (match_dup 3) 18352 (const_int 4))) 18353 (use (reg:SI DIRFLAG_REG))] 18354 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18355 "{movsl|movsd}" 18356 [(set_attr "type" "str") 18357 (set_attr "mode" "SI") 18358 (set_attr "memory" "both")]) 18359 18360(define_insn "*strmovsi_rex_1" 18361 [(set (mem:SI (match_operand:DI 2 "register_operand" "0")) 18362 (mem:SI (match_operand:DI 3 "register_operand" "1"))) 18363 (set (match_operand:DI 0 "register_operand" "=D") 18364 (plus:DI (match_dup 2) 18365 (const_int 4))) 18366 (set (match_operand:DI 1 "register_operand" "=S") 18367 (plus:DI (match_dup 3) 18368 (const_int 4))) 18369 (use (reg:SI DIRFLAG_REG))] 18370 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18371 "{movsl|movsd}" 18372 [(set_attr "type" "str") 18373 (set_attr "mode" "SI") 18374 (set_attr "memory" "both")]) 18375 18376(define_insn "*strmovhi_1" 18377 [(set (mem:HI (match_operand:SI 2 "register_operand" "0")) 18378 (mem:HI (match_operand:SI 3 "register_operand" "1"))) 18379 (set (match_operand:SI 0 "register_operand" "=D") 18380 (plus:SI (match_dup 2) 18381 (const_int 2))) 18382 (set (match_operand:SI 1 "register_operand" "=S") 18383 (plus:SI (match_dup 3) 18384 (const_int 2))) 18385 (use (reg:SI DIRFLAG_REG))] 18386 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18387 "movsw" 18388 [(set_attr "type" "str") 18389 (set_attr "memory" "both") 18390 (set_attr "mode" "HI")]) 18391 18392(define_insn "*strmovhi_rex_1" 18393 [(set (mem:HI (match_operand:DI 2 "register_operand" "0")) 18394 (mem:HI (match_operand:DI 3 "register_operand" "1"))) 18395 (set (match_operand:DI 0 "register_operand" "=D") 18396 (plus:DI (match_dup 2) 18397 (const_int 2))) 18398 (set (match_operand:DI 1 "register_operand" "=S") 18399 (plus:DI (match_dup 3) 18400 (const_int 2))) 18401 (use (reg:SI DIRFLAG_REG))] 18402 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18403 "movsw" 18404 [(set_attr "type" "str") 18405 (set_attr "memory" "both") 18406 (set_attr "mode" "HI")]) 18407 18408(define_insn "*strmovqi_1" 18409 [(set (mem:QI (match_operand:SI 2 "register_operand" "0")) 18410 (mem:QI (match_operand:SI 3 "register_operand" "1"))) 18411 (set (match_operand:SI 0 "register_operand" "=D") 18412 (plus:SI (match_dup 2) 18413 (const_int 1))) 18414 (set (match_operand:SI 1 "register_operand" "=S") 18415 (plus:SI (match_dup 3) 18416 (const_int 1))) 18417 (use (reg:SI DIRFLAG_REG))] 18418 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18419 "movsb" 18420 [(set_attr "type" "str") 18421 (set_attr "memory" "both") 18422 (set_attr "mode" "QI")]) 18423 18424(define_insn "*strmovqi_rex_1" 18425 [(set (mem:QI (match_operand:DI 2 "register_operand" "0")) 18426 (mem:QI (match_operand:DI 3 "register_operand" "1"))) 18427 (set (match_operand:DI 0 "register_operand" "=D") 18428 (plus:DI (match_dup 2) 18429 (const_int 1))) 18430 (set (match_operand:DI 1 "register_operand" "=S") 18431 (plus:DI (match_dup 3) 18432 (const_int 1))) 18433 (use (reg:SI DIRFLAG_REG))] 18434 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18435 "movsb" 18436 [(set_attr "type" "str") 18437 (set_attr "memory" "both") 18438 (set_attr "mode" "QI")]) 18439 18440(define_expand "rep_mov" 18441 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0)) 18442 (set (match_operand 0 "register_operand" "") 18443 (match_operand 5 "" "")) 18444 (set (match_operand 2 "register_operand" "") 18445 (match_operand 6 "" "")) 18446 (set (match_operand 1 "memory_operand" "") 18447 (match_operand 3 "memory_operand" "")) 18448 (use (match_dup 4)) 18449 (use (reg:SI DIRFLAG_REG))])] 18450 "" 18451 "") 18452 18453(define_insn "*rep_movdi_rex64" 18454 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) 18455 (set (match_operand:DI 0 "register_operand" "=D") 18456 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2") 18457 (const_int 3)) 18458 (match_operand:DI 3 "register_operand" "0"))) 18459 (set (match_operand:DI 1 "register_operand" "=S") 18460 (plus:DI (ashift:DI (match_dup 5) (const_int 3)) 18461 (match_operand:DI 4 "register_operand" "1"))) 18462 (set (mem:BLK (match_dup 3)) 18463 (mem:BLK (match_dup 4))) 18464 (use (match_dup 5)) 18465 (use (reg:SI DIRFLAG_REG))] 18466 "TARGET_64BIT" 18467 "{rep\;movsq|rep movsq}" 18468 [(set_attr "type" "str") 18469 (set_attr "prefix_rep" "1") 18470 (set_attr "memory" "both") 18471 (set_attr "mode" "DI")]) 18472 18473(define_insn "*rep_movsi" 18474 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0)) 18475 (set (match_operand:SI 0 "register_operand" "=D") 18476 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2") 18477 (const_int 2)) 18478 (match_operand:SI 3 "register_operand" "0"))) 18479 (set (match_operand:SI 1 "register_operand" "=S") 18480 (plus:SI (ashift:SI (match_dup 5) (const_int 2)) 18481 (match_operand:SI 4 "register_operand" "1"))) 18482 (set (mem:BLK (match_dup 3)) 18483 (mem:BLK (match_dup 4))) 18484 (use (match_dup 5)) 18485 (use (reg:SI DIRFLAG_REG))] 18486 "!TARGET_64BIT" 18487 "{rep\;movsl|rep movsd}" 18488 [(set_attr "type" "str") 18489 (set_attr "prefix_rep" "1") 18490 (set_attr "memory" "both") 18491 (set_attr "mode" "SI")]) 18492 18493(define_insn "*rep_movsi_rex64" 18494 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) 18495 (set (match_operand:DI 0 "register_operand" "=D") 18496 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2") 18497 (const_int 2)) 18498 (match_operand:DI 3 "register_operand" "0"))) 18499 (set (match_operand:DI 1 "register_operand" "=S") 18500 (plus:DI (ashift:DI (match_dup 5) (const_int 2)) 18501 (match_operand:DI 4 "register_operand" "1"))) 18502 (set (mem:BLK (match_dup 3)) 18503 (mem:BLK (match_dup 4))) 18504 (use (match_dup 5)) 18505 (use (reg:SI DIRFLAG_REG))] 18506 "TARGET_64BIT" 18507 "{rep\;movsl|rep movsd}" 18508 [(set_attr "type" "str") 18509 (set_attr "prefix_rep" "1") 18510 (set_attr "memory" "both") 18511 (set_attr "mode" "SI")]) 18512 18513(define_insn "*rep_movqi" 18514 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0)) 18515 (set (match_operand:SI 0 "register_operand" "=D") 18516 (plus:SI (match_operand:SI 3 "register_operand" "0") 18517 (match_operand:SI 5 "register_operand" "2"))) 18518 (set (match_operand:SI 1 "register_operand" "=S") 18519 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5))) 18520 (set (mem:BLK (match_dup 3)) 18521 (mem:BLK (match_dup 4))) 18522 (use (match_dup 5)) 18523 (use (reg:SI DIRFLAG_REG))] 18524 "!TARGET_64BIT" 18525 "{rep\;movsb|rep movsb}" 18526 [(set_attr "type" "str") 18527 (set_attr "prefix_rep" "1") 18528 (set_attr "memory" "both") 18529 (set_attr "mode" "SI")]) 18530 18531(define_insn "*rep_movqi_rex64" 18532 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) 18533 (set (match_operand:DI 0 "register_operand" "=D") 18534 (plus:DI (match_operand:DI 3 "register_operand" "0") 18535 (match_operand:DI 5 "register_operand" "2"))) 18536 (set (match_operand:DI 1 "register_operand" "=S") 18537 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5))) 18538 (set (mem:BLK (match_dup 3)) 18539 (mem:BLK (match_dup 4))) 18540 (use (match_dup 5)) 18541 (use (reg:SI DIRFLAG_REG))] 18542 "TARGET_64BIT" 18543 "{rep\;movsb|rep movsb}" 18544 [(set_attr "type" "str") 18545 (set_attr "prefix_rep" "1") 18546 (set_attr "memory" "both") 18547 (set_attr "mode" "SI")]) 18548 18549(define_expand "setmemsi" 18550 [(use (match_operand:BLK 0 "memory_operand" "")) 18551 (use (match_operand:SI 1 "nonmemory_operand" "")) 18552 (use (match_operand 2 "const_int_operand" "")) 18553 (use (match_operand 3 "const_int_operand" ""))] 18554 "" 18555{ 18556 /* If value to set is not zero, use the library routine. */ 18557 if (operands[2] != const0_rtx) 18558 FAIL; 18559 18560 if (ix86_expand_clrmem (operands[0], operands[1], operands[3])) 18561 DONE; 18562 else 18563 FAIL; 18564}) 18565 18566(define_expand "setmemdi" 18567 [(use (match_operand:BLK 0 "memory_operand" "")) 18568 (use (match_operand:DI 1 "nonmemory_operand" "")) 18569 (use (match_operand 2 "const_int_operand" "")) 18570 (use (match_operand 3 "const_int_operand" ""))] 18571 "TARGET_64BIT" 18572{ 18573 /* If value to set is not zero, use the library routine. */ 18574 if (operands[2] != const0_rtx) 18575 FAIL; 18576 18577 if (ix86_expand_clrmem (operands[0], operands[1], operands[3])) 18578 DONE; 18579 else 18580 FAIL; 18581}) 18582 18583;; Most CPUs don't like single string operations 18584;; Handle this case here to simplify previous expander. 18585 18586(define_expand "strset" 18587 [(set (match_operand 1 "memory_operand" "") 18588 (match_operand 2 "register_operand" "")) 18589 (parallel [(set (match_operand 0 "register_operand" "") 18590 (match_dup 3)) 18591 (clobber (reg:CC FLAGS_REG))])] 18592 "" 18593{ 18594 if (GET_MODE (operands[1]) != GET_MODE (operands[2])) 18595 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0); 18596 18597 /* If .md ever supports :P for Pmode, this can be directly 18598 in the pattern above. */ 18599 operands[3] = gen_rtx_PLUS (Pmode, operands[0], 18600 GEN_INT (GET_MODE_SIZE (GET_MODE 18601 (operands[2])))); 18602 if (TARGET_SINGLE_STRINGOP || optimize_size) 18603 { 18604 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2], 18605 operands[3])); 18606 DONE; 18607 } 18608}) 18609 18610(define_expand "strset_singleop" 18611 [(parallel [(set (match_operand 1 "memory_operand" "") 18612 (match_operand 2 "register_operand" "")) 18613 (set (match_operand 0 "register_operand" "") 18614 (match_operand 3 "" "")) 18615 (use (reg:SI DIRFLAG_REG))])] 18616 "TARGET_SINGLE_STRINGOP || optimize_size" 18617 "") 18618 18619(define_insn "*strsetdi_rex_1" 18620 [(set (mem:DI (match_operand:DI 1 "register_operand" "0")) 18621 (match_operand:DI 2 "register_operand" "a")) 18622 (set (match_operand:DI 0 "register_operand" "=D") 18623 (plus:DI (match_dup 1) 18624 (const_int 8))) 18625 (use (reg:SI DIRFLAG_REG))] 18626 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18627 "stosq" 18628 [(set_attr "type" "str") 18629 (set_attr "memory" "store") 18630 (set_attr "mode" "DI")]) 18631 18632(define_insn "*strsetsi_1" 18633 [(set (mem:SI (match_operand:SI 1 "register_operand" "0")) 18634 (match_operand:SI 2 "register_operand" "a")) 18635 (set (match_operand:SI 0 "register_operand" "=D") 18636 (plus:SI (match_dup 1) 18637 (const_int 4))) 18638 (use (reg:SI DIRFLAG_REG))] 18639 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18640 "{stosl|stosd}" 18641 [(set_attr "type" "str") 18642 (set_attr "memory" "store") 18643 (set_attr "mode" "SI")]) 18644 18645(define_insn "*strsetsi_rex_1" 18646 [(set (mem:SI (match_operand:DI 1 "register_operand" "0")) 18647 (match_operand:SI 2 "register_operand" "a")) 18648 (set (match_operand:DI 0 "register_operand" "=D") 18649 (plus:DI (match_dup 1) 18650 (const_int 4))) 18651 (use (reg:SI DIRFLAG_REG))] 18652 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18653 "{stosl|stosd}" 18654 [(set_attr "type" "str") 18655 (set_attr "memory" "store") 18656 (set_attr "mode" "SI")]) 18657 18658(define_insn "*strsethi_1" 18659 [(set (mem:HI (match_operand:SI 1 "register_operand" "0")) 18660 (match_operand:HI 2 "register_operand" "a")) 18661 (set (match_operand:SI 0 "register_operand" "=D") 18662 (plus:SI (match_dup 1) 18663 (const_int 2))) 18664 (use (reg:SI DIRFLAG_REG))] 18665 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18666 "stosw" 18667 [(set_attr "type" "str") 18668 (set_attr "memory" "store") 18669 (set_attr "mode" "HI")]) 18670 18671(define_insn "*strsethi_rex_1" 18672 [(set (mem:HI (match_operand:DI 1 "register_operand" "0")) 18673 (match_operand:HI 2 "register_operand" "a")) 18674 (set (match_operand:DI 0 "register_operand" "=D") 18675 (plus:DI (match_dup 1) 18676 (const_int 2))) 18677 (use (reg:SI DIRFLAG_REG))] 18678 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18679 "stosw" 18680 [(set_attr "type" "str") 18681 (set_attr "memory" "store") 18682 (set_attr "mode" "HI")]) 18683 18684(define_insn "*strsetqi_1" 18685 [(set (mem:QI (match_operand:SI 1 "register_operand" "0")) 18686 (match_operand:QI 2 "register_operand" "a")) 18687 (set (match_operand:SI 0 "register_operand" "=D") 18688 (plus:SI (match_dup 1) 18689 (const_int 1))) 18690 (use (reg:SI DIRFLAG_REG))] 18691 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18692 "stosb" 18693 [(set_attr "type" "str") 18694 (set_attr "memory" "store") 18695 (set_attr "mode" "QI")]) 18696 18697(define_insn "*strsetqi_rex_1" 18698 [(set (mem:QI (match_operand:DI 1 "register_operand" "0")) 18699 (match_operand:QI 2 "register_operand" "a")) 18700 (set (match_operand:DI 0 "register_operand" "=D") 18701 (plus:DI (match_dup 1) 18702 (const_int 1))) 18703 (use (reg:SI DIRFLAG_REG))] 18704 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18705 "stosb" 18706 [(set_attr "type" "str") 18707 (set_attr "memory" "store") 18708 (set_attr "mode" "QI")]) 18709 18710(define_expand "rep_stos" 18711 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0)) 18712 (set (match_operand 0 "register_operand" "") 18713 (match_operand 4 "" "")) 18714 (set (match_operand 2 "memory_operand" "") (const_int 0)) 18715 (use (match_operand 3 "register_operand" "")) 18716 (use (match_dup 1)) 18717 (use (reg:SI DIRFLAG_REG))])] 18718 "" 18719 "") 18720 18721(define_insn "*rep_stosdi_rex64" 18722 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) 18723 (set (match_operand:DI 0 "register_operand" "=D") 18724 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1") 18725 (const_int 3)) 18726 (match_operand:DI 3 "register_operand" "0"))) 18727 (set (mem:BLK (match_dup 3)) 18728 (const_int 0)) 18729 (use (match_operand:DI 2 "register_operand" "a")) 18730 (use (match_dup 4)) 18731 (use (reg:SI DIRFLAG_REG))] 18732 "TARGET_64BIT" 18733 "{rep\;stosq|rep stosq}" 18734 [(set_attr "type" "str") 18735 (set_attr "prefix_rep" "1") 18736 (set_attr "memory" "store") 18737 (set_attr "mode" "DI")]) 18738 18739(define_insn "*rep_stossi" 18740 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0)) 18741 (set (match_operand:SI 0 "register_operand" "=D") 18742 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1") 18743 (const_int 2)) 18744 (match_operand:SI 3 "register_operand" "0"))) 18745 (set (mem:BLK (match_dup 3)) 18746 (const_int 0)) 18747 (use (match_operand:SI 2 "register_operand" "a")) 18748 (use (match_dup 4)) 18749 (use (reg:SI DIRFLAG_REG))] 18750 "!TARGET_64BIT" 18751 "{rep\;stosl|rep stosd}" 18752 [(set_attr "type" "str") 18753 (set_attr "prefix_rep" "1") 18754 (set_attr "memory" "store") 18755 (set_attr "mode" "SI")]) 18756 18757(define_insn "*rep_stossi_rex64" 18758 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) 18759 (set (match_operand:DI 0 "register_operand" "=D") 18760 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1") 18761 (const_int 2)) 18762 (match_operand:DI 3 "register_operand" "0"))) 18763 (set (mem:BLK (match_dup 3)) 18764 (const_int 0)) 18765 (use (match_operand:SI 2 "register_operand" "a")) 18766 (use (match_dup 4)) 18767 (use (reg:SI DIRFLAG_REG))] 18768 "TARGET_64BIT" 18769 "{rep\;stosl|rep stosd}" 18770 [(set_attr "type" "str") 18771 (set_attr "prefix_rep" "1") 18772 (set_attr "memory" "store") 18773 (set_attr "mode" "SI")]) 18774 18775(define_insn "*rep_stosqi" 18776 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0)) 18777 (set (match_operand:SI 0 "register_operand" "=D") 18778 (plus:SI (match_operand:SI 3 "register_operand" "0") 18779 (match_operand:SI 4 "register_operand" "1"))) 18780 (set (mem:BLK (match_dup 3)) 18781 (const_int 0)) 18782 (use (match_operand:QI 2 "register_operand" "a")) 18783 (use (match_dup 4)) 18784 (use (reg:SI DIRFLAG_REG))] 18785 "!TARGET_64BIT" 18786 "{rep\;stosb|rep stosb}" 18787 [(set_attr "type" "str") 18788 (set_attr "prefix_rep" "1") 18789 (set_attr "memory" "store") 18790 (set_attr "mode" "QI")]) 18791 18792(define_insn "*rep_stosqi_rex64" 18793 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) 18794 (set (match_operand:DI 0 "register_operand" "=D") 18795 (plus:DI (match_operand:DI 3 "register_operand" "0") 18796 (match_operand:DI 4 "register_operand" "1"))) 18797 (set (mem:BLK (match_dup 3)) 18798 (const_int 0)) 18799 (use (match_operand:QI 2 "register_operand" "a")) 18800 (use (match_dup 4)) 18801 (use (reg:SI DIRFLAG_REG))] 18802 "TARGET_64BIT" 18803 "{rep\;stosb|rep stosb}" 18804 [(set_attr "type" "str") 18805 (set_attr "prefix_rep" "1") 18806 (set_attr "memory" "store") 18807 (set_attr "mode" "QI")]) 18808 18809(define_expand "cmpstrnsi" 18810 [(set (match_operand:SI 0 "register_operand" "") 18811 (compare:SI (match_operand:BLK 1 "general_operand" "") 18812 (match_operand:BLK 2 "general_operand" ""))) 18813 (use (match_operand 3 "general_operand" "")) 18814 (use (match_operand 4 "immediate_operand" ""))] 18815 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS" 18816{ 18817 rtx addr1, addr2, out, outlow, count, countreg, align; 18818 18819 /* Can't use this if the user has appropriated esi or edi. */ 18820 if (global_regs[4] || global_regs[5]) 18821 FAIL; 18822 18823 out = operands[0]; 18824 if (GET_CODE (out) != REG) 18825 out = gen_reg_rtx (SImode); 18826 18827 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); 18828 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0)); 18829 if (addr1 != XEXP (operands[1], 0)) 18830 operands[1] = replace_equiv_address_nv (operands[1], addr1); 18831 if (addr2 != XEXP (operands[2], 0)) 18832 operands[2] = replace_equiv_address_nv (operands[2], addr2); 18833 18834 count = operands[3]; 18835 countreg = ix86_zero_extend_to_Pmode (count); 18836 18837 /* %%% Iff we are testing strict equality, we can use known alignment 18838 to good advantage. This may be possible with combine, particularly 18839 once cc0 is dead. */ 18840 align = operands[4]; 18841 18842 emit_insn (gen_cld ()); 18843 if (GET_CODE (count) == CONST_INT) 18844 { 18845 if (INTVAL (count) == 0) 18846 { 18847 emit_move_insn (operands[0], const0_rtx); 18848 DONE; 18849 } 18850 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align, 18851 operands[1], operands[2])); 18852 } 18853 else 18854 { 18855 if (TARGET_64BIT) 18856 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg)); 18857 else 18858 emit_insn (gen_cmpsi_1 (countreg, countreg)); 18859 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align, 18860 operands[1], operands[2])); 18861 } 18862 18863 outlow = gen_lowpart (QImode, out); 18864 emit_insn (gen_cmpintqi (outlow)); 18865 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow)); 18866 18867 if (operands[0] != out) 18868 emit_move_insn (operands[0], out); 18869 18870 DONE; 18871}) 18872 18873;; Produce a tri-state integer (-1, 0, 1) from condition codes. 18874 18875(define_expand "cmpintqi" 18876 [(set (match_dup 1) 18877 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 18878 (set (match_dup 2) 18879 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 18880 (parallel [(set (match_operand:QI 0 "register_operand" "") 18881 (minus:QI (match_dup 1) 18882 (match_dup 2))) 18883 (clobber (reg:CC FLAGS_REG))])] 18884 "" 18885 "operands[1] = gen_reg_rtx (QImode); 18886 operands[2] = gen_reg_rtx (QImode);") 18887 18888;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is 18889;; zero. Emit extra code to make sure that a zero-length compare is EQ. 18890 18891(define_expand "cmpstrnqi_nz_1" 18892 [(parallel [(set (reg:CC FLAGS_REG) 18893 (compare:CC (match_operand 4 "memory_operand" "") 18894 (match_operand 5 "memory_operand" ""))) 18895 (use (match_operand 2 "register_operand" "")) 18896 (use (match_operand:SI 3 "immediate_operand" "")) 18897 (use (reg:SI DIRFLAG_REG)) 18898 (clobber (match_operand 0 "register_operand" "")) 18899 (clobber (match_operand 1 "register_operand" "")) 18900 (clobber (match_dup 2))])] 18901 "" 18902 "") 18903 18904(define_insn "*cmpstrnqi_nz_1" 18905 [(set (reg:CC FLAGS_REG) 18906 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0")) 18907 (mem:BLK (match_operand:SI 5 "register_operand" "1")))) 18908 (use (match_operand:SI 6 "register_operand" "2")) 18909 (use (match_operand:SI 3 "immediate_operand" "i")) 18910 (use (reg:SI DIRFLAG_REG)) 18911 (clobber (match_operand:SI 0 "register_operand" "=S")) 18912 (clobber (match_operand:SI 1 "register_operand" "=D")) 18913 (clobber (match_operand:SI 2 "register_operand" "=c"))] 18914 "!TARGET_64BIT" 18915 "repz{\;| }cmpsb" 18916 [(set_attr "type" "str") 18917 (set_attr "mode" "QI") 18918 (set_attr "prefix_rep" "1")]) 18919 18920(define_insn "*cmpstrnqi_nz_rex_1" 18921 [(set (reg:CC FLAGS_REG) 18922 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0")) 18923 (mem:BLK (match_operand:DI 5 "register_operand" "1")))) 18924 (use (match_operand:DI 6 "register_operand" "2")) 18925 (use (match_operand:SI 3 "immediate_operand" "i")) 18926 (use (reg:SI DIRFLAG_REG)) 18927 (clobber (match_operand:DI 0 "register_operand" "=S")) 18928 (clobber (match_operand:DI 1 "register_operand" "=D")) 18929 (clobber (match_operand:DI 2 "register_operand" "=c"))] 18930 "TARGET_64BIT" 18931 "repz{\;| }cmpsb" 18932 [(set_attr "type" "str") 18933 (set_attr "mode" "QI") 18934 (set_attr "prefix_rep" "1")]) 18935 18936;; The same, but the count is not known to not be zero. 18937 18938(define_expand "cmpstrnqi_1" 18939 [(parallel [(set (reg:CC FLAGS_REG) 18940 (if_then_else:CC (ne (match_operand 2 "register_operand" "") 18941 (const_int 0)) 18942 (compare:CC (match_operand 4 "memory_operand" "") 18943 (match_operand 5 "memory_operand" "")) 18944 (const_int 0))) 18945 (use (match_operand:SI 3 "immediate_operand" "")) 18946 (use (reg:CC FLAGS_REG)) 18947 (use (reg:SI DIRFLAG_REG)) 18948 (clobber (match_operand 0 "register_operand" "")) 18949 (clobber (match_operand 1 "register_operand" "")) 18950 (clobber (match_dup 2))])] 18951 "" 18952 "") 18953 18954(define_insn "*cmpstrnqi_1" 18955 [(set (reg:CC FLAGS_REG) 18956 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2") 18957 (const_int 0)) 18958 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0")) 18959 (mem:BLK (match_operand:SI 5 "register_operand" "1"))) 18960 (const_int 0))) 18961 (use (match_operand:SI 3 "immediate_operand" "i")) 18962 (use (reg:CC FLAGS_REG)) 18963 (use (reg:SI DIRFLAG_REG)) 18964 (clobber (match_operand:SI 0 "register_operand" "=S")) 18965 (clobber (match_operand:SI 1 "register_operand" "=D")) 18966 (clobber (match_operand:SI 2 "register_operand" "=c"))] 18967 "!TARGET_64BIT" 18968 "repz{\;| }cmpsb" 18969 [(set_attr "type" "str") 18970 (set_attr "mode" "QI") 18971 (set_attr "prefix_rep" "1")]) 18972 18973(define_insn "*cmpstrnqi_rex_1" 18974 [(set (reg:CC FLAGS_REG) 18975 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2") 18976 (const_int 0)) 18977 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0")) 18978 (mem:BLK (match_operand:DI 5 "register_operand" "1"))) 18979 (const_int 0))) 18980 (use (match_operand:SI 3 "immediate_operand" "i")) 18981 (use (reg:CC FLAGS_REG)) 18982 (use (reg:SI DIRFLAG_REG)) 18983 (clobber (match_operand:DI 0 "register_operand" "=S")) 18984 (clobber (match_operand:DI 1 "register_operand" "=D")) 18985 (clobber (match_operand:DI 2 "register_operand" "=c"))] 18986 "TARGET_64BIT" 18987 "repz{\;| }cmpsb" 18988 [(set_attr "type" "str") 18989 (set_attr "mode" "QI") 18990 (set_attr "prefix_rep" "1")]) 18991 18992(define_expand "strlensi" 18993 [(set (match_operand:SI 0 "register_operand" "") 18994 (unspec:SI [(match_operand:BLK 1 "general_operand" "") 18995 (match_operand:QI 2 "immediate_operand" "") 18996 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))] 18997 "" 18998{ 18999 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) 19000 DONE; 19001 else 19002 FAIL; 19003}) 19004 19005(define_expand "strlendi" 19006 [(set (match_operand:DI 0 "register_operand" "") 19007 (unspec:DI [(match_operand:BLK 1 "general_operand" "") 19008 (match_operand:QI 2 "immediate_operand" "") 19009 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))] 19010 "" 19011{ 19012 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) 19013 DONE; 19014 else 19015 FAIL; 19016}) 19017 19018(define_expand "strlenqi_1" 19019 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" "")) 19020 (use (reg:SI DIRFLAG_REG)) 19021 (clobber (match_operand 1 "register_operand" "")) 19022 (clobber (reg:CC FLAGS_REG))])] 19023 "" 19024 "") 19025 19026(define_insn "*strlenqi_1" 19027 [(set (match_operand:SI 0 "register_operand" "=&c") 19028 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1")) 19029 (match_operand:QI 2 "register_operand" "a") 19030 (match_operand:SI 3 "immediate_operand" "i") 19031 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS)) 19032 (use (reg:SI DIRFLAG_REG)) 19033 (clobber (match_operand:SI 1 "register_operand" "=D")) 19034 (clobber (reg:CC FLAGS_REG))] 19035 "!TARGET_64BIT" 19036 "repnz{\;| }scasb" 19037 [(set_attr "type" "str") 19038 (set_attr "mode" "QI") 19039 (set_attr "prefix_rep" "1")]) 19040 19041(define_insn "*strlenqi_rex_1" 19042 [(set (match_operand:DI 0 "register_operand" "=&c") 19043 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1")) 19044 (match_operand:QI 2 "register_operand" "a") 19045 (match_operand:DI 3 "immediate_operand" "i") 19046 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS)) 19047 (use (reg:SI DIRFLAG_REG)) 19048 (clobber (match_operand:DI 1 "register_operand" "=D")) 19049 (clobber (reg:CC FLAGS_REG))] 19050 "TARGET_64BIT" 19051 "repnz{\;| }scasb" 19052 [(set_attr "type" "str") 19053 (set_attr "mode" "QI") 19054 (set_attr "prefix_rep" "1")]) 19055 19056;; Peephole optimizations to clean up after cmpstrn*. This should be 19057;; handled in combine, but it is not currently up to the task. 19058;; When used for their truth value, the cmpstrn* expanders generate 19059;; code like this: 19060;; 19061;; repz cmpsb 19062;; seta %al 19063;; setb %dl 19064;; cmpb %al, %dl 19065;; jcc label 19066;; 19067;; The intermediate three instructions are unnecessary. 19068 19069;; This one handles cmpstrn*_nz_1... 19070(define_peephole2 19071 [(parallel[ 19072 (set (reg:CC FLAGS_REG) 19073 (compare:CC (mem:BLK (match_operand 4 "register_operand" "")) 19074 (mem:BLK (match_operand 5 "register_operand" "")))) 19075 (use (match_operand 6 "register_operand" "")) 19076 (use (match_operand:SI 3 "immediate_operand" "")) 19077 (use (reg:SI DIRFLAG_REG)) 19078 (clobber (match_operand 0 "register_operand" "")) 19079 (clobber (match_operand 1 "register_operand" "")) 19080 (clobber (match_operand 2 "register_operand" ""))]) 19081 (set (match_operand:QI 7 "register_operand" "") 19082 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 19083 (set (match_operand:QI 8 "register_operand" "") 19084 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 19085 (set (reg FLAGS_REG) 19086 (compare (match_dup 7) (match_dup 8))) 19087 ] 19088 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 19089 [(parallel[ 19090 (set (reg:CC FLAGS_REG) 19091 (compare:CC (mem:BLK (match_dup 4)) 19092 (mem:BLK (match_dup 5)))) 19093 (use (match_dup 6)) 19094 (use (match_dup 3)) 19095 (use (reg:SI DIRFLAG_REG)) 19096 (clobber (match_dup 0)) 19097 (clobber (match_dup 1)) 19098 (clobber (match_dup 2))])] 19099 "") 19100 19101;; ...and this one handles cmpstrn*_1. 19102(define_peephole2 19103 [(parallel[ 19104 (set (reg:CC FLAGS_REG) 19105 (if_then_else:CC (ne (match_operand 6 "register_operand" "") 19106 (const_int 0)) 19107 (compare:CC (mem:BLK (match_operand 4 "register_operand" "")) 19108 (mem:BLK (match_operand 5 "register_operand" ""))) 19109 (const_int 0))) 19110 (use (match_operand:SI 3 "immediate_operand" "")) 19111 (use (reg:CC FLAGS_REG)) 19112 (use (reg:SI DIRFLAG_REG)) 19113 (clobber (match_operand 0 "register_operand" "")) 19114 (clobber (match_operand 1 "register_operand" "")) 19115 (clobber (match_operand 2 "register_operand" ""))]) 19116 (set (match_operand:QI 7 "register_operand" "") 19117 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 19118 (set (match_operand:QI 8 "register_operand" "") 19119 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 19120 (set (reg FLAGS_REG) 19121 (compare (match_dup 7) (match_dup 8))) 19122 ] 19123 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 19124 [(parallel[ 19125 (set (reg:CC FLAGS_REG) 19126 (if_then_else:CC (ne (match_dup 6) 19127 (const_int 0)) 19128 (compare:CC (mem:BLK (match_dup 4)) 19129 (mem:BLK (match_dup 5))) 19130 (const_int 0))) 19131 (use (match_dup 3)) 19132 (use (reg:CC FLAGS_REG)) 19133 (use (reg:SI DIRFLAG_REG)) 19134 (clobber (match_dup 0)) 19135 (clobber (match_dup 1)) 19136 (clobber (match_dup 2))])] 19137 "") 19138 19139 19140 19141;; Conditional move instructions. 19142 19143(define_expand "movdicc" 19144 [(set (match_operand:DI 0 "register_operand" "") 19145 (if_then_else:DI (match_operand 1 "comparison_operator" "") 19146 (match_operand:DI 2 "general_operand" "") 19147 (match_operand:DI 3 "general_operand" "")))] 19148 "TARGET_64BIT" 19149 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 19150 19151(define_insn "x86_movdicc_0_m1_rex64" 19152 [(set (match_operand:DI 0 "register_operand" "=r") 19153 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "") 19154 (const_int -1) 19155 (const_int 0))) 19156 (clobber (reg:CC FLAGS_REG))] 19157 "TARGET_64BIT" 19158 "sbb{q}\t%0, %0" 19159 ; Since we don't have the proper number of operands for an alu insn, 19160 ; fill in all the blanks. 19161 [(set_attr "type" "alu") 19162 (set_attr "pent_pair" "pu") 19163 (set_attr "memory" "none") 19164 (set_attr "imm_disp" "false") 19165 (set_attr "mode" "DI") 19166 (set_attr "length_immediate" "0")]) 19167 19168(define_insn "*movdicc_c_rex64" 19169 [(set (match_operand:DI 0 "register_operand" "=r,r") 19170 (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 19171 [(reg FLAGS_REG) (const_int 0)]) 19172 (match_operand:DI 2 "nonimmediate_operand" "rm,0") 19173 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))] 19174 "TARGET_64BIT && TARGET_CMOVE 19175 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19176 "@ 19177 cmov%O2%C1\t{%2, %0|%0, %2} 19178 cmov%O2%c1\t{%3, %0|%0, %3}" 19179 [(set_attr "type" "icmov") 19180 (set_attr "mode" "DI")]) 19181 19182(define_expand "movsicc" 19183 [(set (match_operand:SI 0 "register_operand" "") 19184 (if_then_else:SI (match_operand 1 "comparison_operator" "") 19185 (match_operand:SI 2 "general_operand" "") 19186 (match_operand:SI 3 "general_operand" "")))] 19187 "" 19188 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 19189 19190;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing 19191;; the register first winds up with `sbbl $0,reg', which is also weird. 19192;; So just document what we're doing explicitly. 19193 19194(define_insn "x86_movsicc_0_m1" 19195 [(set (match_operand:SI 0 "register_operand" "=r") 19196 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "") 19197 (const_int -1) 19198 (const_int 0))) 19199 (clobber (reg:CC FLAGS_REG))] 19200 "" 19201 "sbb{l}\t%0, %0" 19202 ; Since we don't have the proper number of operands for an alu insn, 19203 ; fill in all the blanks. 19204 [(set_attr "type" "alu") 19205 (set_attr "pent_pair" "pu") 19206 (set_attr "memory" "none") 19207 (set_attr "imm_disp" "false") 19208 (set_attr "mode" "SI") 19209 (set_attr "length_immediate" "0")]) 19210 19211(define_insn "*movsicc_noc" 19212 [(set (match_operand:SI 0 "register_operand" "=r,r") 19213 (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 19214 [(reg FLAGS_REG) (const_int 0)]) 19215 (match_operand:SI 2 "nonimmediate_operand" "rm,0") 19216 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))] 19217 "TARGET_CMOVE 19218 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19219 "@ 19220 cmov%O2%C1\t{%2, %0|%0, %2} 19221 cmov%O2%c1\t{%3, %0|%0, %3}" 19222 [(set_attr "type" "icmov") 19223 (set_attr "mode" "SI")]) 19224 19225(define_expand "movhicc" 19226 [(set (match_operand:HI 0 "register_operand" "") 19227 (if_then_else:HI (match_operand 1 "comparison_operator" "") 19228 (match_operand:HI 2 "general_operand" "") 19229 (match_operand:HI 3 "general_operand" "")))] 19230 "TARGET_HIMODE_MATH" 19231 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 19232 19233(define_insn "*movhicc_noc" 19234 [(set (match_operand:HI 0 "register_operand" "=r,r") 19235 (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 19236 [(reg FLAGS_REG) (const_int 0)]) 19237 (match_operand:HI 2 "nonimmediate_operand" "rm,0") 19238 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))] 19239 "TARGET_CMOVE 19240 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19241 "@ 19242 cmov%O2%C1\t{%2, %0|%0, %2} 19243 cmov%O2%c1\t{%3, %0|%0, %3}" 19244 [(set_attr "type" "icmov") 19245 (set_attr "mode" "HI")]) 19246 19247(define_expand "movqicc" 19248 [(set (match_operand:QI 0 "register_operand" "") 19249 (if_then_else:QI (match_operand 1 "comparison_operator" "") 19250 (match_operand:QI 2 "general_operand" "") 19251 (match_operand:QI 3 "general_operand" "")))] 19252 "TARGET_QIMODE_MATH" 19253 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 19254 19255(define_insn_and_split "*movqicc_noc" 19256 [(set (match_operand:QI 0 "register_operand" "=r,r") 19257 (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 19258 [(match_operand 4 "flags_reg_operand" "") 19259 (const_int 0)]) 19260 (match_operand:QI 2 "register_operand" "r,0") 19261 (match_operand:QI 3 "register_operand" "0,r")))] 19262 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL" 19263 "#" 19264 "&& reload_completed" 19265 [(set (match_dup 0) 19266 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) 19267 (match_dup 2) 19268 (match_dup 3)))] 19269 "operands[0] = gen_lowpart (SImode, operands[0]); 19270 operands[2] = gen_lowpart (SImode, operands[2]); 19271 operands[3] = gen_lowpart (SImode, operands[3]);" 19272 [(set_attr "type" "icmov") 19273 (set_attr "mode" "SI")]) 19274 19275(define_expand "movsfcc" 19276 [(set (match_operand:SF 0 "register_operand" "") 19277 (if_then_else:SF (match_operand 1 "comparison_operator" "") 19278 (match_operand:SF 2 "register_operand" "") 19279 (match_operand:SF 3 "register_operand" "")))] 19280 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH" 19281 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") 19282 19283(define_insn "*movsfcc_1_387" 19284 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r") 19285 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 19286 [(reg FLAGS_REG) (const_int 0)]) 19287 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0") 19288 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))] 19289 "TARGET_80387 && TARGET_CMOVE 19290 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19291 "@ 19292 fcmov%F1\t{%2, %0|%0, %2} 19293 fcmov%f1\t{%3, %0|%0, %3} 19294 cmov%O2%C1\t{%2, %0|%0, %2} 19295 cmov%O2%c1\t{%3, %0|%0, %3}" 19296 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 19297 (set_attr "mode" "SF,SF,SI,SI")]) 19298 19299(define_expand "movdfcc" 19300 [(set (match_operand:DF 0 "register_operand" "") 19301 (if_then_else:DF (match_operand 1 "comparison_operator" "") 19302 (match_operand:DF 2 "register_operand" "") 19303 (match_operand:DF 3 "register_operand" "")))] 19304 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)" 19305 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") 19306 19307(define_insn "*movdfcc_1" 19308 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r") 19309 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 19310 [(reg FLAGS_REG) (const_int 0)]) 19311 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") 19312 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] 19313 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 19314 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19315 "@ 19316 fcmov%F1\t{%2, %0|%0, %2} 19317 fcmov%f1\t{%3, %0|%0, %3} 19318 # 19319 #" 19320 [(set_attr "type" "fcmov,fcmov,multi,multi") 19321 (set_attr "mode" "DF")]) 19322 19323(define_insn "*movdfcc_1_rex64" 19324 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r") 19325 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 19326 [(reg FLAGS_REG) (const_int 0)]) 19327 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") 19328 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] 19329 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 19330 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19331 "@ 19332 fcmov%F1\t{%2, %0|%0, %2} 19333 fcmov%f1\t{%3, %0|%0, %3} 19334 cmov%O2%C1\t{%2, %0|%0, %2} 19335 cmov%O2%c1\t{%3, %0|%0, %3}" 19336 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 19337 (set_attr "mode" "DF")]) 19338 19339(define_split 19340 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "") 19341 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 19342 [(match_operand 4 "flags_reg_operand" "") 19343 (const_int 0)]) 19344 (match_operand:DF 2 "nonimmediate_operand" "") 19345 (match_operand:DF 3 "nonimmediate_operand" "")))] 19346 "!TARGET_64BIT && reload_completed" 19347 [(set (match_dup 2) 19348 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) 19349 (match_dup 5) 19350 (match_dup 7))) 19351 (set (match_dup 3) 19352 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) 19353 (match_dup 6) 19354 (match_dup 8)))] 19355 "split_di (operands+2, 1, operands+5, operands+6); 19356 split_di (operands+3, 1, operands+7, operands+8); 19357 split_di (operands, 1, operands+2, operands+3);") 19358 19359(define_expand "movxfcc" 19360 [(set (match_operand:XF 0 "register_operand" "") 19361 (if_then_else:XF (match_operand 1 "comparison_operator" "") 19362 (match_operand:XF 2 "register_operand" "") 19363 (match_operand:XF 3 "register_operand" "")))] 19364 "TARGET_80387 && TARGET_CMOVE" 19365 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") 19366 19367(define_insn "*movxfcc_1" 19368 [(set (match_operand:XF 0 "register_operand" "=f,f") 19369 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 19370 [(reg FLAGS_REG) (const_int 0)]) 19371 (match_operand:XF 2 "register_operand" "f,0") 19372 (match_operand:XF 3 "register_operand" "0,f")))] 19373 "TARGET_80387 && TARGET_CMOVE" 19374 "@ 19375 fcmov%F1\t{%2, %0|%0, %2} 19376 fcmov%f1\t{%3, %0|%0, %3}" 19377 [(set_attr "type" "fcmov") 19378 (set_attr "mode" "XF")]) 19379 19380;; These versions of the min/max patterns are intentionally ignorant of 19381;; their behavior wrt -0.0 and NaN (via the commutative operand mark). 19382;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator 19383;; are undefined in this condition, we're certain this is correct. 19384 19385(define_insn "sminsf3" 19386 [(set (match_operand:SF 0 "register_operand" "=x") 19387 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0") 19388 (match_operand:SF 2 "nonimmediate_operand" "xm")))] 19389 "TARGET_SSE_MATH" 19390 "minss\t{%2, %0|%0, %2}" 19391 [(set_attr "type" "sseadd") 19392 (set_attr "mode" "SF")]) 19393 19394(define_insn "smaxsf3" 19395 [(set (match_operand:SF 0 "register_operand" "=x") 19396 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0") 19397 (match_operand:SF 2 "nonimmediate_operand" "xm")))] 19398 "TARGET_SSE_MATH" 19399 "maxss\t{%2, %0|%0, %2}" 19400 [(set_attr "type" "sseadd") 19401 (set_attr "mode" "SF")]) 19402 19403(define_insn "smindf3" 19404 [(set (match_operand:DF 0 "register_operand" "=x") 19405 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0") 19406 (match_operand:DF 2 "nonimmediate_operand" "xm")))] 19407 "TARGET_SSE2 && TARGET_SSE_MATH" 19408 "minsd\t{%2, %0|%0, %2}" 19409 [(set_attr "type" "sseadd") 19410 (set_attr "mode" "DF")]) 19411 19412(define_insn "smaxdf3" 19413 [(set (match_operand:DF 0 "register_operand" "=x") 19414 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0") 19415 (match_operand:DF 2 "nonimmediate_operand" "xm")))] 19416 "TARGET_SSE2 && TARGET_SSE_MATH" 19417 "maxsd\t{%2, %0|%0, %2}" 19418 [(set_attr "type" "sseadd") 19419 (set_attr "mode" "DF")]) 19420 19421;; These versions of the min/max patterns implement exactly the operations 19422;; min = (op1 < op2 ? op1 : op2) 19423;; max = (!(op1 < op2) ? op1 : op2) 19424;; Their operands are not commutative, and thus they may be used in the 19425;; presence of -0.0 and NaN. 19426 19427(define_insn "*ieee_sminsf3" 19428 [(set (match_operand:SF 0 "register_operand" "=x") 19429 (unspec:SF [(match_operand:SF 1 "register_operand" "0") 19430 (match_operand:SF 2 "nonimmediate_operand" "xm")] 19431 UNSPEC_IEEE_MIN))] 19432 "TARGET_SSE_MATH" 19433 "minss\t{%2, %0|%0, %2}" 19434 [(set_attr "type" "sseadd") 19435 (set_attr "mode" "SF")]) 19436 19437(define_insn "*ieee_smaxsf3" 19438 [(set (match_operand:SF 0 "register_operand" "=x") 19439 (unspec:SF [(match_operand:SF 1 "register_operand" "0") 19440 (match_operand:SF 2 "nonimmediate_operand" "xm")] 19441 UNSPEC_IEEE_MAX))] 19442 "TARGET_SSE_MATH" 19443 "maxss\t{%2, %0|%0, %2}" 19444 [(set_attr "type" "sseadd") 19445 (set_attr "mode" "SF")]) 19446 19447(define_insn "*ieee_smindf3" 19448 [(set (match_operand:DF 0 "register_operand" "=x") 19449 (unspec:DF [(match_operand:DF 1 "register_operand" "0") 19450 (match_operand:DF 2 "nonimmediate_operand" "xm")] 19451 UNSPEC_IEEE_MIN))] 19452 "TARGET_SSE2 && TARGET_SSE_MATH" 19453 "minsd\t{%2, %0|%0, %2}" 19454 [(set_attr "type" "sseadd") 19455 (set_attr "mode" "DF")]) 19456 19457(define_insn "*ieee_smaxdf3" 19458 [(set (match_operand:DF 0 "register_operand" "=x") 19459 (unspec:DF [(match_operand:DF 1 "register_operand" "0") 19460 (match_operand:DF 2 "nonimmediate_operand" "xm")] 19461 UNSPEC_IEEE_MAX))] 19462 "TARGET_SSE2 && TARGET_SSE_MATH" 19463 "maxsd\t{%2, %0|%0, %2}" 19464 [(set_attr "type" "sseadd") 19465 (set_attr "mode" "DF")]) 19466 19467;; Make two stack loads independent: 19468;; fld aa fld aa 19469;; fld %st(0) -> fld bb 19470;; fmul bb fmul %st(1), %st 19471;; 19472;; Actually we only match the last two instructions for simplicity. 19473(define_peephole2 19474 [(set (match_operand 0 "fp_register_operand" "") 19475 (match_operand 1 "fp_register_operand" "")) 19476 (set (match_dup 0) 19477 (match_operator 2 "binary_fp_operator" 19478 [(match_dup 0) 19479 (match_operand 3 "memory_operand" "")]))] 19480 "REGNO (operands[0]) != REGNO (operands[1])" 19481 [(set (match_dup 0) (match_dup 3)) 19482 (set (match_dup 0) (match_dup 4))] 19483 19484 ;; The % modifier is not operational anymore in peephole2's, so we have to 19485 ;; swap the operands manually in the case of addition and multiplication. 19486 "if (COMMUTATIVE_ARITH_P (operands[2])) 19487 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), 19488 operands[0], operands[1]); 19489 else 19490 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), 19491 operands[1], operands[0]);") 19492 19493;; Conditional addition patterns 19494(define_expand "addqicc" 19495 [(match_operand:QI 0 "register_operand" "") 19496 (match_operand 1 "comparison_operator" "") 19497 (match_operand:QI 2 "register_operand" "") 19498 (match_operand:QI 3 "const_int_operand" "")] 19499 "" 19500 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 19501 19502(define_expand "addhicc" 19503 [(match_operand:HI 0 "register_operand" "") 19504 (match_operand 1 "comparison_operator" "") 19505 (match_operand:HI 2 "register_operand" "") 19506 (match_operand:HI 3 "const_int_operand" "")] 19507 "" 19508 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 19509 19510(define_expand "addsicc" 19511 [(match_operand:SI 0 "register_operand" "") 19512 (match_operand 1 "comparison_operator" "") 19513 (match_operand:SI 2 "register_operand" "") 19514 (match_operand:SI 3 "const_int_operand" "")] 19515 "" 19516 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 19517 19518(define_expand "adddicc" 19519 [(match_operand:DI 0 "register_operand" "") 19520 (match_operand 1 "comparison_operator" "") 19521 (match_operand:DI 2 "register_operand" "") 19522 (match_operand:DI 3 "const_int_operand" "")] 19523 "TARGET_64BIT" 19524 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 19525 19526 19527;; Misc patterns (?) 19528 19529;; This pattern exists to put a dependency on all ebp-based memory accesses. 19530;; Otherwise there will be nothing to keep 19531;; 19532;; [(set (reg ebp) (reg esp))] 19533;; [(set (reg esp) (plus (reg esp) (const_int -160000))) 19534;; (clobber (eflags)] 19535;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))] 19536;; 19537;; in proper program order. 19538(define_insn "pro_epilogue_adjust_stack_1" 19539 [(set (match_operand:SI 0 "register_operand" "=r,r") 19540 (plus:SI (match_operand:SI 1 "register_operand" "0,r") 19541 (match_operand:SI 2 "immediate_operand" "i,i"))) 19542 (clobber (reg:CC FLAGS_REG)) 19543 (clobber (mem:BLK (scratch)))] 19544 "!TARGET_64BIT" 19545{ 19546 switch (get_attr_type (insn)) 19547 { 19548 case TYPE_IMOV: 19549 return "mov{l}\t{%1, %0|%0, %1}"; 19550 19551 case TYPE_ALU: 19552 if (GET_CODE (operands[2]) == CONST_INT 19553 && (INTVAL (operands[2]) == 128 19554 || (INTVAL (operands[2]) < 0 19555 && INTVAL (operands[2]) != -128))) 19556 { 19557 operands[2] = GEN_INT (-INTVAL (operands[2])); 19558 return "sub{l}\t{%2, %0|%0, %2}"; 19559 } 19560 return "add{l}\t{%2, %0|%0, %2}"; 19561 19562 case TYPE_LEA: 19563 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 19564 return "lea{l}\t{%a2, %0|%0, %a2}"; 19565 19566 default: 19567 gcc_unreachable (); 19568 } 19569} 19570 [(set (attr "type") 19571 (cond [(eq_attr "alternative" "0") 19572 (const_string "alu") 19573 (match_operand:SI 2 "const0_operand" "") 19574 (const_string "imov") 19575 ] 19576 (const_string "lea"))) 19577 (set_attr "mode" "SI")]) 19578 19579(define_insn "pro_epilogue_adjust_stack_rex64" 19580 [(set (match_operand:DI 0 "register_operand" "=r,r") 19581 (plus:DI (match_operand:DI 1 "register_operand" "0,r") 19582 (match_operand:DI 2 "x86_64_immediate_operand" "e,e"))) 19583 (clobber (reg:CC FLAGS_REG)) 19584 (clobber (mem:BLK (scratch)))] 19585 "TARGET_64BIT" 19586{ 19587 switch (get_attr_type (insn)) 19588 { 19589 case TYPE_IMOV: 19590 return "mov{q}\t{%1, %0|%0, %1}"; 19591 19592 case TYPE_ALU: 19593 if (GET_CODE (operands[2]) == CONST_INT 19594 /* Avoid overflows. */ 19595 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 19596 && (INTVAL (operands[2]) == 128 19597 || (INTVAL (operands[2]) < 0 19598 && INTVAL (operands[2]) != -128))) 19599 { 19600 operands[2] = GEN_INT (-INTVAL (operands[2])); 19601 return "sub{q}\t{%2, %0|%0, %2}"; 19602 } 19603 return "add{q}\t{%2, %0|%0, %2}"; 19604 19605 case TYPE_LEA: 19606 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 19607 return "lea{q}\t{%a2, %0|%0, %a2}"; 19608 19609 default: 19610 gcc_unreachable (); 19611 } 19612} 19613 [(set (attr "type") 19614 (cond [(eq_attr "alternative" "0") 19615 (const_string "alu") 19616 (match_operand:DI 2 "const0_operand" "") 19617 (const_string "imov") 19618 ] 19619 (const_string "lea"))) 19620 (set_attr "mode" "DI")]) 19621 19622(define_insn "pro_epilogue_adjust_stack_rex64_2" 19623 [(set (match_operand:DI 0 "register_operand" "=r,r") 19624 (plus:DI (match_operand:DI 1 "register_operand" "0,r") 19625 (match_operand:DI 3 "immediate_operand" "i,i"))) 19626 (use (match_operand:DI 2 "register_operand" "r,r")) 19627 (clobber (reg:CC FLAGS_REG)) 19628 (clobber (mem:BLK (scratch)))] 19629 "TARGET_64BIT" 19630{ 19631 switch (get_attr_type (insn)) 19632 { 19633 case TYPE_ALU: 19634 return "add{q}\t{%2, %0|%0, %2}"; 19635 19636 case TYPE_LEA: 19637 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]); 19638 return "lea{q}\t{%a2, %0|%0, %a2}"; 19639 19640 default: 19641 gcc_unreachable (); 19642 } 19643} 19644 [(set_attr "type" "alu,lea") 19645 (set_attr "mode" "DI")]) 19646 19647(define_expand "allocate_stack_worker" 19648 [(match_operand:SI 0 "register_operand" "")] 19649 "TARGET_STACK_PROBE" 19650{ 19651 if (reload_completed) 19652 { 19653 if (TARGET_64BIT) 19654 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0])); 19655 else 19656 emit_insn (gen_allocate_stack_worker_postreload (operands[0])); 19657 } 19658 else 19659 { 19660 if (TARGET_64BIT) 19661 emit_insn (gen_allocate_stack_worker_rex64 (operands[0])); 19662 else 19663 emit_insn (gen_allocate_stack_worker_1 (operands[0])); 19664 } 19665 DONE; 19666}) 19667 19668(define_insn "allocate_stack_worker_1" 19669 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")] 19670 UNSPECV_STACK_PROBE) 19671 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0))) 19672 (clobber (match_scratch:SI 1 "=0")) 19673 (clobber (reg:CC FLAGS_REG))] 19674 "!TARGET_64BIT && TARGET_STACK_PROBE" 19675 "call\t__alloca" 19676 [(set_attr "type" "multi") 19677 (set_attr "length" "5")]) 19678 19679(define_expand "allocate_stack_worker_postreload" 19680 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")] 19681 UNSPECV_STACK_PROBE) 19682 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0))) 19683 (clobber (match_dup 0)) 19684 (clobber (reg:CC FLAGS_REG))])] 19685 "" 19686 "") 19687 19688(define_insn "allocate_stack_worker_rex64" 19689 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")] 19690 UNSPECV_STACK_PROBE) 19691 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0))) 19692 (clobber (match_scratch:DI 1 "=0")) 19693 (clobber (reg:CC FLAGS_REG))] 19694 "TARGET_64BIT && TARGET_STACK_PROBE" 19695 "call\t__alloca" 19696 [(set_attr "type" "multi") 19697 (set_attr "length" "5")]) 19698 19699(define_expand "allocate_stack_worker_rex64_postreload" 19700 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")] 19701 UNSPECV_STACK_PROBE) 19702 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0))) 19703 (clobber (match_dup 0)) 19704 (clobber (reg:CC FLAGS_REG))])] 19705 "" 19706 "") 19707 19708(define_expand "allocate_stack" 19709 [(parallel [(set (match_operand:SI 0 "register_operand" "=r") 19710 (minus:SI (reg:SI SP_REG) 19711 (match_operand:SI 1 "general_operand" ""))) 19712 (clobber (reg:CC FLAGS_REG))]) 19713 (parallel [(set (reg:SI SP_REG) 19714 (minus:SI (reg:SI SP_REG) (match_dup 1))) 19715 (clobber (reg:CC FLAGS_REG))])] 19716 "TARGET_STACK_PROBE" 19717{ 19718#ifdef CHECK_STACK_LIMIT 19719 if (GET_CODE (operands[1]) == CONST_INT 19720 && INTVAL (operands[1]) < CHECK_STACK_LIMIT) 19721 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, 19722 operands[1])); 19723 else 19724#endif 19725 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode, 19726 operands[1]))); 19727 19728 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 19729 DONE; 19730}) 19731 19732(define_expand "builtin_setjmp_receiver" 19733 [(label_ref (match_operand 0 "" ""))] 19734 "!TARGET_64BIT && flag_pic" 19735{ 19736 if (TARGET_MACHO) 19737 { 19738 rtx xops[3]; 19739 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM); 19740 rtx label_rtx = gen_label_rtx (); 19741 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx)); 19742 xops[0] = xops[1] = picreg; 19743 xops[2] = gen_rtx_CONST (SImode, 19744 gen_rtx_MINUS (SImode, 19745 gen_rtx_LABEL_REF (SImode, label_rtx), 19746 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME))); 19747 ix86_expand_binary_operator (MINUS, SImode, xops); 19748 } 19749 else 19750 emit_insn (gen_set_got (pic_offset_table_rtx)); 19751 DONE; 19752}) 19753 19754;; Avoid redundant prefixes by splitting HImode arithmetic to SImode. 19755 19756(define_split 19757 [(set (match_operand 0 "register_operand" "") 19758 (match_operator 3 "promotable_binary_operator" 19759 [(match_operand 1 "register_operand" "") 19760 (match_operand 2 "aligned_operand" "")])) 19761 (clobber (reg:CC FLAGS_REG))] 19762 "! TARGET_PARTIAL_REG_STALL && reload_completed 19763 && ((GET_MODE (operands[0]) == HImode 19764 && ((!optimize_size && !TARGET_FAST_PREFIX) 19765 /* ??? next two lines just !satisfies_constraint_K (...) */ 19766 || GET_CODE (operands[2]) != CONST_INT 19767 || satisfies_constraint_K (operands[2]))) 19768 || (GET_MODE (operands[0]) == QImode 19769 && (TARGET_PROMOTE_QImode || optimize_size)))" 19770 [(parallel [(set (match_dup 0) 19771 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 19772 (clobber (reg:CC FLAGS_REG))])] 19773 "operands[0] = gen_lowpart (SImode, operands[0]); 19774 operands[1] = gen_lowpart (SImode, operands[1]); 19775 if (GET_CODE (operands[3]) != ASHIFT) 19776 operands[2] = gen_lowpart (SImode, operands[2]); 19777 PUT_MODE (operands[3], SImode);") 19778 19779; Promote the QImode tests, as i386 has encoding of the AND 19780; instruction with 32-bit sign-extended immediate and thus the 19781; instruction size is unchanged, except in the %eax case for 19782; which it is increased by one byte, hence the ! optimize_size. 19783(define_split 19784 [(set (match_operand 0 "flags_reg_operand" "") 19785 (match_operator 2 "compare_operator" 19786 [(and (match_operand 3 "aligned_operand" "") 19787 (match_operand 4 "const_int_operand" "")) 19788 (const_int 0)])) 19789 (set (match_operand 1 "register_operand" "") 19790 (and (match_dup 3) (match_dup 4)))] 19791 "! TARGET_PARTIAL_REG_STALL && reload_completed 19792 /* Ensure that the operand will remain sign-extended immediate. */ 19793 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode) 19794 && ! optimize_size 19795 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX) 19796 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))" 19797 [(parallel [(set (match_dup 0) 19798 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4)) 19799 (const_int 0)])) 19800 (set (match_dup 1) 19801 (and:SI (match_dup 3) (match_dup 4)))])] 19802{ 19803 operands[4] 19804 = gen_int_mode (INTVAL (operands[4]) 19805 & GET_MODE_MASK (GET_MODE (operands[1])), SImode); 19806 operands[1] = gen_lowpart (SImode, operands[1]); 19807 operands[3] = gen_lowpart (SImode, operands[3]); 19808}) 19809 19810; Don't promote the QImode tests, as i386 doesn't have encoding of 19811; the TEST instruction with 32-bit sign-extended immediate and thus 19812; the instruction size would at least double, which is not what we 19813; want even with ! optimize_size. 19814(define_split 19815 [(set (match_operand 0 "flags_reg_operand" "") 19816 (match_operator 1 "compare_operator" 19817 [(and (match_operand:HI 2 "aligned_operand" "") 19818 (match_operand:HI 3 "const_int_operand" "")) 19819 (const_int 0)]))] 19820 "! TARGET_PARTIAL_REG_STALL && reload_completed 19821 /* Ensure that the operand will remain sign-extended immediate. */ 19822 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode) 19823 && ! TARGET_FAST_PREFIX 19824 && ! optimize_size" 19825 [(set (match_dup 0) 19826 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 19827 (const_int 0)]))] 19828{ 19829 operands[3] 19830 = gen_int_mode (INTVAL (operands[3]) 19831 & GET_MODE_MASK (GET_MODE (operands[2])), SImode); 19832 operands[2] = gen_lowpart (SImode, operands[2]); 19833}) 19834 19835(define_split 19836 [(set (match_operand 0 "register_operand" "") 19837 (neg (match_operand 1 "register_operand" ""))) 19838 (clobber (reg:CC FLAGS_REG))] 19839 "! TARGET_PARTIAL_REG_STALL && reload_completed 19840 && (GET_MODE (operands[0]) == HImode 19841 || (GET_MODE (operands[0]) == QImode 19842 && (TARGET_PROMOTE_QImode || optimize_size)))" 19843 [(parallel [(set (match_dup 0) 19844 (neg:SI (match_dup 1))) 19845 (clobber (reg:CC FLAGS_REG))])] 19846 "operands[0] = gen_lowpart (SImode, operands[0]); 19847 operands[1] = gen_lowpart (SImode, operands[1]);") 19848 19849(define_split 19850 [(set (match_operand 0 "register_operand" "") 19851 (not (match_operand 1 "register_operand" "")))] 19852 "! TARGET_PARTIAL_REG_STALL && reload_completed 19853 && (GET_MODE (operands[0]) == HImode 19854 || (GET_MODE (operands[0]) == QImode 19855 && (TARGET_PROMOTE_QImode || optimize_size)))" 19856 [(set (match_dup 0) 19857 (not:SI (match_dup 1)))] 19858 "operands[0] = gen_lowpart (SImode, operands[0]); 19859 operands[1] = gen_lowpart (SImode, operands[1]);") 19860 19861(define_split 19862 [(set (match_operand 0 "register_operand" "") 19863 (if_then_else (match_operator 1 "comparison_operator" 19864 [(reg FLAGS_REG) (const_int 0)]) 19865 (match_operand 2 "register_operand" "") 19866 (match_operand 3 "register_operand" "")))] 19867 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE 19868 && (GET_MODE (operands[0]) == HImode 19869 || (GET_MODE (operands[0]) == QImode 19870 && (TARGET_PROMOTE_QImode || optimize_size)))" 19871 [(set (match_dup 0) 19872 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))] 19873 "operands[0] = gen_lowpart (SImode, operands[0]); 19874 operands[2] = gen_lowpart (SImode, operands[2]); 19875 operands[3] = gen_lowpart (SImode, operands[3]);") 19876 19877 19878;; RTL Peephole optimizations, run before sched2. These primarily look to 19879;; transform a complex memory operation into two memory to register operations. 19880 19881;; Don't push memory operands 19882(define_peephole2 19883 [(set (match_operand:SI 0 "push_operand" "") 19884 (match_operand:SI 1 "memory_operand" "")) 19885 (match_scratch:SI 2 "r")] 19886 "!optimize_size && !TARGET_PUSH_MEMORY 19887 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19888 [(set (match_dup 2) (match_dup 1)) 19889 (set (match_dup 0) (match_dup 2))] 19890 "") 19891 19892(define_peephole2 19893 [(set (match_operand:DI 0 "push_operand" "") 19894 (match_operand:DI 1 "memory_operand" "")) 19895 (match_scratch:DI 2 "r")] 19896 "!optimize_size && !TARGET_PUSH_MEMORY 19897 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19898 [(set (match_dup 2) (match_dup 1)) 19899 (set (match_dup 0) (match_dup 2))] 19900 "") 19901 19902;; We need to handle SFmode only, because DFmode and XFmode is split to 19903;; SImode pushes. 19904(define_peephole2 19905 [(set (match_operand:SF 0 "push_operand" "") 19906 (match_operand:SF 1 "memory_operand" "")) 19907 (match_scratch:SF 2 "r")] 19908 "!optimize_size && !TARGET_PUSH_MEMORY 19909 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19910 [(set (match_dup 2) (match_dup 1)) 19911 (set (match_dup 0) (match_dup 2))] 19912 "") 19913 19914(define_peephole2 19915 [(set (match_operand:HI 0 "push_operand" "") 19916 (match_operand:HI 1 "memory_operand" "")) 19917 (match_scratch:HI 2 "r")] 19918 "!optimize_size && !TARGET_PUSH_MEMORY 19919 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19920 [(set (match_dup 2) (match_dup 1)) 19921 (set (match_dup 0) (match_dup 2))] 19922 "") 19923 19924(define_peephole2 19925 [(set (match_operand:QI 0 "push_operand" "") 19926 (match_operand:QI 1 "memory_operand" "")) 19927 (match_scratch:QI 2 "q")] 19928 "!optimize_size && !TARGET_PUSH_MEMORY 19929 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19930 [(set (match_dup 2) (match_dup 1)) 19931 (set (match_dup 0) (match_dup 2))] 19932 "") 19933 19934;; Don't move an immediate directly to memory when the instruction 19935;; gets too big. 19936(define_peephole2 19937 [(match_scratch:SI 1 "r") 19938 (set (match_operand:SI 0 "memory_operand" "") 19939 (const_int 0))] 19940 "! optimize_size 19941 && ! TARGET_USE_MOV0 19942 && TARGET_SPLIT_LONG_MOVES 19943 && get_attr_length (insn) >= ix86_cost->large_insn 19944 && peep2_regno_dead_p (0, FLAGS_REG)" 19945 [(parallel [(set (match_dup 1) (const_int 0)) 19946 (clobber (reg:CC FLAGS_REG))]) 19947 (set (match_dup 0) (match_dup 1))] 19948 "") 19949 19950(define_peephole2 19951 [(match_scratch:HI 1 "r") 19952 (set (match_operand:HI 0 "memory_operand" "") 19953 (const_int 0))] 19954 "! optimize_size 19955 && ! TARGET_USE_MOV0 19956 && TARGET_SPLIT_LONG_MOVES 19957 && get_attr_length (insn) >= ix86_cost->large_insn 19958 && peep2_regno_dead_p (0, FLAGS_REG)" 19959 [(parallel [(set (match_dup 2) (const_int 0)) 19960 (clobber (reg:CC FLAGS_REG))]) 19961 (set (match_dup 0) (match_dup 1))] 19962 "operands[2] = gen_lowpart (SImode, operands[1]);") 19963 19964(define_peephole2 19965 [(match_scratch:QI 1 "q") 19966 (set (match_operand:QI 0 "memory_operand" "") 19967 (const_int 0))] 19968 "! optimize_size 19969 && ! TARGET_USE_MOV0 19970 && TARGET_SPLIT_LONG_MOVES 19971 && get_attr_length (insn) >= ix86_cost->large_insn 19972 && peep2_regno_dead_p (0, FLAGS_REG)" 19973 [(parallel [(set (match_dup 2) (const_int 0)) 19974 (clobber (reg:CC FLAGS_REG))]) 19975 (set (match_dup 0) (match_dup 1))] 19976 "operands[2] = gen_lowpart (SImode, operands[1]);") 19977 19978(define_peephole2 19979 [(match_scratch:SI 2 "r") 19980 (set (match_operand:SI 0 "memory_operand" "") 19981 (match_operand:SI 1 "immediate_operand" ""))] 19982 "! optimize_size 19983 && get_attr_length (insn) >= ix86_cost->large_insn 19984 && TARGET_SPLIT_LONG_MOVES" 19985 [(set (match_dup 2) (match_dup 1)) 19986 (set (match_dup 0) (match_dup 2))] 19987 "") 19988 19989(define_peephole2 19990 [(match_scratch:HI 2 "r") 19991 (set (match_operand:HI 0 "memory_operand" "") 19992 (match_operand:HI 1 "immediate_operand" ""))] 19993 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn 19994 && TARGET_SPLIT_LONG_MOVES" 19995 [(set (match_dup 2) (match_dup 1)) 19996 (set (match_dup 0) (match_dup 2))] 19997 "") 19998 19999(define_peephole2 20000 [(match_scratch:QI 2 "q") 20001 (set (match_operand:QI 0 "memory_operand" "") 20002 (match_operand:QI 1 "immediate_operand" ""))] 20003 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn 20004 && TARGET_SPLIT_LONG_MOVES" 20005 [(set (match_dup 2) (match_dup 1)) 20006 (set (match_dup 0) (match_dup 2))] 20007 "") 20008 20009;; Don't compare memory with zero, load and use a test instead. 20010(define_peephole2 20011 [(set (match_operand 0 "flags_reg_operand" "") 20012 (match_operator 1 "compare_operator" 20013 [(match_operand:SI 2 "memory_operand" "") 20014 (const_int 0)])) 20015 (match_scratch:SI 3 "r")] 20016 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size" 20017 [(set (match_dup 3) (match_dup 2)) 20018 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))] 20019 "") 20020 20021;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 20022;; Don't split NOTs with a displacement operand, because resulting XOR 20023;; will not be pairable anyway. 20024;; 20025;; On AMD K6, NOT is vector decoded with memory operand that cannot be 20026;; represented using a modRM byte. The XOR replacement is long decoded, 20027;; so this split helps here as well. 20028;; 20029;; Note: Can't do this as a regular split because we can't get proper 20030;; lifetime information then. 20031 20032(define_peephole2 20033 [(set (match_operand:SI 0 "nonimmediate_operand" "") 20034 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))] 20035 "!optimize_size 20036 && peep2_regno_dead_p (0, FLAGS_REG) 20037 && ((TARGET_PENTIUM 20038 && (GET_CODE (operands[0]) != MEM 20039 || !memory_displacement_operand (operands[0], SImode))) 20040 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))" 20041 [(parallel [(set (match_dup 0) 20042 (xor:SI (match_dup 1) (const_int -1))) 20043 (clobber (reg:CC FLAGS_REG))])] 20044 "") 20045 20046(define_peephole2 20047 [(set (match_operand:HI 0 "nonimmediate_operand" "") 20048 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))] 20049 "!optimize_size 20050 && peep2_regno_dead_p (0, FLAGS_REG) 20051 && ((TARGET_PENTIUM 20052 && (GET_CODE (operands[0]) != MEM 20053 || !memory_displacement_operand (operands[0], HImode))) 20054 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))" 20055 [(parallel [(set (match_dup 0) 20056 (xor:HI (match_dup 1) (const_int -1))) 20057 (clobber (reg:CC FLAGS_REG))])] 20058 "") 20059 20060(define_peephole2 20061 [(set (match_operand:QI 0 "nonimmediate_operand" "") 20062 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))] 20063 "!optimize_size 20064 && peep2_regno_dead_p (0, FLAGS_REG) 20065 && ((TARGET_PENTIUM 20066 && (GET_CODE (operands[0]) != MEM 20067 || !memory_displacement_operand (operands[0], QImode))) 20068 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))" 20069 [(parallel [(set (match_dup 0) 20070 (xor:QI (match_dup 1) (const_int -1))) 20071 (clobber (reg:CC FLAGS_REG))])] 20072 "") 20073 20074;; Non pairable "test imm, reg" instructions can be translated to 20075;; "and imm, reg" if reg dies. The "and" form is also shorter (one 20076;; byte opcode instead of two, have a short form for byte operands), 20077;; so do it for other CPUs as well. Given that the value was dead, 20078;; this should not create any new dependencies. Pass on the sub-word 20079;; versions if we're concerned about partial register stalls. 20080 20081(define_peephole2 20082 [(set (match_operand 0 "flags_reg_operand" "") 20083 (match_operator 1 "compare_operator" 20084 [(and:SI (match_operand:SI 2 "register_operand" "") 20085 (match_operand:SI 3 "immediate_operand" "")) 20086 (const_int 0)]))] 20087 "ix86_match_ccmode (insn, CCNOmode) 20088 && (true_regnum (operands[2]) != 0 20089 || satisfies_constraint_K (operands[3])) 20090 && peep2_reg_dead_p (1, operands[2])" 20091 [(parallel 20092 [(set (match_dup 0) 20093 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 20094 (const_int 0)])) 20095 (set (match_dup 2) 20096 (and:SI (match_dup 2) (match_dup 3)))])] 20097 "") 20098 20099;; We don't need to handle HImode case, because it will be promoted to SImode 20100;; on ! TARGET_PARTIAL_REG_STALL 20101 20102(define_peephole2 20103 [(set (match_operand 0 "flags_reg_operand" "") 20104 (match_operator 1 "compare_operator" 20105 [(and:QI (match_operand:QI 2 "register_operand" "") 20106 (match_operand:QI 3 "immediate_operand" "")) 20107 (const_int 0)]))] 20108 "! TARGET_PARTIAL_REG_STALL 20109 && ix86_match_ccmode (insn, CCNOmode) 20110 && true_regnum (operands[2]) != 0 20111 && peep2_reg_dead_p (1, operands[2])" 20112 [(parallel 20113 [(set (match_dup 0) 20114 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 20115 (const_int 0)])) 20116 (set (match_dup 2) 20117 (and:QI (match_dup 2) (match_dup 3)))])] 20118 "") 20119 20120(define_peephole2 20121 [(set (match_operand 0 "flags_reg_operand" "") 20122 (match_operator 1 "compare_operator" 20123 [(and:SI 20124 (zero_extract:SI 20125 (match_operand 2 "ext_register_operand" "") 20126 (const_int 8) 20127 (const_int 8)) 20128 (match_operand 3 "const_int_operand" "")) 20129 (const_int 0)]))] 20130 "! TARGET_PARTIAL_REG_STALL 20131 && ix86_match_ccmode (insn, CCNOmode) 20132 && true_regnum (operands[2]) != 0 20133 && peep2_reg_dead_p (1, operands[2])" 20134 [(parallel [(set (match_dup 0) 20135 (match_op_dup 1 20136 [(and:SI 20137 (zero_extract:SI 20138 (match_dup 2) 20139 (const_int 8) 20140 (const_int 8)) 20141 (match_dup 3)) 20142 (const_int 0)])) 20143 (set (zero_extract:SI (match_dup 2) 20144 (const_int 8) 20145 (const_int 8)) 20146 (and:SI 20147 (zero_extract:SI 20148 (match_dup 2) 20149 (const_int 8) 20150 (const_int 8)) 20151 (match_dup 3)))])] 20152 "") 20153 20154;; Don't do logical operations with memory inputs. 20155(define_peephole2 20156 [(match_scratch:SI 2 "r") 20157 (parallel [(set (match_operand:SI 0 "register_operand" "") 20158 (match_operator:SI 3 "arith_or_logical_operator" 20159 [(match_dup 0) 20160 (match_operand:SI 1 "memory_operand" "")])) 20161 (clobber (reg:CC FLAGS_REG))])] 20162 "! optimize_size && ! TARGET_READ_MODIFY" 20163 [(set (match_dup 2) (match_dup 1)) 20164 (parallel [(set (match_dup 0) 20165 (match_op_dup 3 [(match_dup 0) (match_dup 2)])) 20166 (clobber (reg:CC FLAGS_REG))])] 20167 "") 20168 20169(define_peephole2 20170 [(match_scratch:SI 2 "r") 20171 (parallel [(set (match_operand:SI 0 "register_operand" "") 20172 (match_operator:SI 3 "arith_or_logical_operator" 20173 [(match_operand:SI 1 "memory_operand" "") 20174 (match_dup 0)])) 20175 (clobber (reg:CC FLAGS_REG))])] 20176 "! optimize_size && ! TARGET_READ_MODIFY" 20177 [(set (match_dup 2) (match_dup 1)) 20178 (parallel [(set (match_dup 0) 20179 (match_op_dup 3 [(match_dup 2) (match_dup 0)])) 20180 (clobber (reg:CC FLAGS_REG))])] 20181 "") 20182 20183; Don't do logical operations with memory outputs 20184; 20185; These two don't make sense for PPro/PII -- we're expanding a 4-uop 20186; instruction into two 1-uop insns plus a 2-uop insn. That last has 20187; the same decoder scheduling characteristics as the original. 20188 20189(define_peephole2 20190 [(match_scratch:SI 2 "r") 20191 (parallel [(set (match_operand:SI 0 "memory_operand" "") 20192 (match_operator:SI 3 "arith_or_logical_operator" 20193 [(match_dup 0) 20194 (match_operand:SI 1 "nonmemory_operand" "")])) 20195 (clobber (reg:CC FLAGS_REG))])] 20196 "! optimize_size && ! TARGET_READ_MODIFY_WRITE" 20197 [(set (match_dup 2) (match_dup 0)) 20198 (parallel [(set (match_dup 2) 20199 (match_op_dup 3 [(match_dup 2) (match_dup 1)])) 20200 (clobber (reg:CC FLAGS_REG))]) 20201 (set (match_dup 0) (match_dup 2))] 20202 "") 20203 20204(define_peephole2 20205 [(match_scratch:SI 2 "r") 20206 (parallel [(set (match_operand:SI 0 "memory_operand" "") 20207 (match_operator:SI 3 "arith_or_logical_operator" 20208 [(match_operand:SI 1 "nonmemory_operand" "") 20209 (match_dup 0)])) 20210 (clobber (reg:CC FLAGS_REG))])] 20211 "! optimize_size && ! TARGET_READ_MODIFY_WRITE" 20212 [(set (match_dup 2) (match_dup 0)) 20213 (parallel [(set (match_dup 2) 20214 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 20215 (clobber (reg:CC FLAGS_REG))]) 20216 (set (match_dup 0) (match_dup 2))] 20217 "") 20218 20219;; Attempt to always use XOR for zeroing registers. 20220(define_peephole2 20221 [(set (match_operand 0 "register_operand" "") 20222 (match_operand 1 "const0_operand" ""))] 20223 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD 20224 && (! TARGET_USE_MOV0 || optimize_size) 20225 && GENERAL_REG_P (operands[0]) 20226 && peep2_regno_dead_p (0, FLAGS_REG)" 20227 [(parallel [(set (match_dup 0) (const_int 0)) 20228 (clobber (reg:CC FLAGS_REG))])] 20229{ 20230 operands[0] = gen_lowpart (word_mode, operands[0]); 20231}) 20232 20233(define_peephole2 20234 [(set (strict_low_part (match_operand 0 "register_operand" "")) 20235 (const_int 0))] 20236 "(GET_MODE (operands[0]) == QImode 20237 || GET_MODE (operands[0]) == HImode) 20238 && (! TARGET_USE_MOV0 || optimize_size) 20239 && peep2_regno_dead_p (0, FLAGS_REG)" 20240 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0)) 20241 (clobber (reg:CC FLAGS_REG))])]) 20242 20243;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg. 20244(define_peephole2 20245 [(set (match_operand 0 "register_operand" "") 20246 (const_int -1))] 20247 "(GET_MODE (operands[0]) == HImode 20248 || GET_MODE (operands[0]) == SImode 20249 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT)) 20250 && (optimize_size || TARGET_PENTIUM) 20251 && peep2_regno_dead_p (0, FLAGS_REG)" 20252 [(parallel [(set (match_dup 0) (const_int -1)) 20253 (clobber (reg:CC FLAGS_REG))])] 20254 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode, 20255 operands[0]);") 20256 20257;; Attempt to convert simple leas to adds. These can be created by 20258;; move expanders. 20259(define_peephole2 20260 [(set (match_operand:SI 0 "register_operand" "") 20261 (plus:SI (match_dup 0) 20262 (match_operand:SI 1 "nonmemory_operand" "")))] 20263 "peep2_regno_dead_p (0, FLAGS_REG)" 20264 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) 20265 (clobber (reg:CC FLAGS_REG))])] 20266 "") 20267 20268(define_peephole2 20269 [(set (match_operand:SI 0 "register_operand" "") 20270 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "") 20271 (match_operand:DI 2 "nonmemory_operand" "")) 0))] 20272 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])" 20273 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2))) 20274 (clobber (reg:CC FLAGS_REG))])] 20275 "operands[2] = gen_lowpart (SImode, operands[2]);") 20276 20277(define_peephole2 20278 [(set (match_operand:DI 0 "register_operand" "") 20279 (plus:DI (match_dup 0) 20280 (match_operand:DI 1 "x86_64_general_operand" "")))] 20281 "peep2_regno_dead_p (0, FLAGS_REG)" 20282 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1))) 20283 (clobber (reg:CC FLAGS_REG))])] 20284 "") 20285 20286(define_peephole2 20287 [(set (match_operand:SI 0 "register_operand" "") 20288 (mult:SI (match_dup 0) 20289 (match_operand:SI 1 "const_int_operand" "")))] 20290 "exact_log2 (INTVAL (operands[1])) >= 0 20291 && peep2_regno_dead_p (0, FLAGS_REG)" 20292 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) 20293 (clobber (reg:CC FLAGS_REG))])] 20294 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));") 20295 20296(define_peephole2 20297 [(set (match_operand:DI 0 "register_operand" "") 20298 (mult:DI (match_dup 0) 20299 (match_operand:DI 1 "const_int_operand" "")))] 20300 "exact_log2 (INTVAL (operands[1])) >= 0 20301 && peep2_regno_dead_p (0, FLAGS_REG)" 20302 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2))) 20303 (clobber (reg:CC FLAGS_REG))])] 20304 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));") 20305 20306(define_peephole2 20307 [(set (match_operand:SI 0 "register_operand" "") 20308 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "") 20309 (match_operand:DI 2 "const_int_operand" "")) 0))] 20310 "exact_log2 (INTVAL (operands[2])) >= 0 20311 && REGNO (operands[0]) == REGNO (operands[1]) 20312 && peep2_regno_dead_p (0, FLAGS_REG)" 20313 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) 20314 (clobber (reg:CC FLAGS_REG))])] 20315 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));") 20316 20317;; The ESP adjustments can be done by the push and pop instructions. Resulting 20318;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On 20319;; many CPUs it is also faster, since special hardware to avoid esp 20320;; dependencies is present. 20321 20322;; While some of these conversions may be done using splitters, we use peepholes 20323;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL. 20324 20325;; Convert prologue esp subtractions to push. 20326;; We need register to push. In order to keep verify_flow_info happy we have 20327;; two choices 20328;; - use scratch and clobber it in order to avoid dependencies 20329;; - use already live register 20330;; We can't use the second way right now, since there is no reliable way how to 20331;; verify that given register is live. First choice will also most likely in 20332;; fewer dependencies. On the place of esp adjustments it is very likely that 20333;; call clobbered registers are dead. We may want to use base pointer as an 20334;; alternative when no register is available later. 20335 20336(define_peephole2 20337 [(match_scratch:SI 0 "r") 20338 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) 20339 (clobber (reg:CC FLAGS_REG)) 20340 (clobber (mem:BLK (scratch)))])] 20341 "optimize_size || !TARGET_SUB_ESP_4" 20342 [(clobber (match_dup 0)) 20343 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 20344 (clobber (mem:BLK (scratch)))])]) 20345 20346(define_peephole2 20347 [(match_scratch:SI 0 "r") 20348 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 20349 (clobber (reg:CC FLAGS_REG)) 20350 (clobber (mem:BLK (scratch)))])] 20351 "optimize_size || !TARGET_SUB_ESP_8" 20352 [(clobber (match_dup 0)) 20353 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 20354 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 20355 (clobber (mem:BLK (scratch)))])]) 20356 20357;; Convert esp subtractions to push. 20358(define_peephole2 20359 [(match_scratch:SI 0 "r") 20360 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) 20361 (clobber (reg:CC FLAGS_REG))])] 20362 "optimize_size || !TARGET_SUB_ESP_4" 20363 [(clobber (match_dup 0)) 20364 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))]) 20365 20366(define_peephole2 20367 [(match_scratch:SI 0 "r") 20368 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 20369 (clobber (reg:CC FLAGS_REG))])] 20370 "optimize_size || !TARGET_SUB_ESP_8" 20371 [(clobber (match_dup 0)) 20372 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 20373 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))]) 20374 20375;; Convert epilogue deallocator to pop. 20376(define_peephole2 20377 [(match_scratch:SI 0 "r") 20378 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20379 (clobber (reg:CC FLAGS_REG)) 20380 (clobber (mem:BLK (scratch)))])] 20381 "optimize_size || !TARGET_ADD_ESP_4" 20382 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20383 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20384 (clobber (mem:BLK (scratch)))])] 20385 "") 20386 20387;; Two pops case is tricky, since pop causes dependency on destination register. 20388;; We use two registers if available. 20389(define_peephole2 20390 [(match_scratch:SI 0 "r") 20391 (match_scratch:SI 1 "r") 20392 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 20393 (clobber (reg:CC FLAGS_REG)) 20394 (clobber (mem:BLK (scratch)))])] 20395 "optimize_size || !TARGET_ADD_ESP_8" 20396 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20397 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20398 (clobber (mem:BLK (scratch)))]) 20399 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG))) 20400 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20401 "") 20402 20403(define_peephole2 20404 [(match_scratch:SI 0 "r") 20405 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 20406 (clobber (reg:CC FLAGS_REG)) 20407 (clobber (mem:BLK (scratch)))])] 20408 "optimize_size" 20409 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20410 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20411 (clobber (mem:BLK (scratch)))]) 20412 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20413 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20414 "") 20415 20416;; Convert esp additions to pop. 20417(define_peephole2 20418 [(match_scratch:SI 0 "r") 20419 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20420 (clobber (reg:CC FLAGS_REG))])] 20421 "" 20422 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20423 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20424 "") 20425 20426;; Two pops case is tricky, since pop causes dependency on destination register. 20427;; We use two registers if available. 20428(define_peephole2 20429 [(match_scratch:SI 0 "r") 20430 (match_scratch:SI 1 "r") 20431 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 20432 (clobber (reg:CC FLAGS_REG))])] 20433 "" 20434 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20435 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))]) 20436 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG))) 20437 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20438 "") 20439 20440(define_peephole2 20441 [(match_scratch:SI 0 "r") 20442 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 20443 (clobber (reg:CC FLAGS_REG))])] 20444 "optimize_size" 20445 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20446 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))]) 20447 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20448 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20449 "") 20450 20451;; Convert compares with 1 to shorter inc/dec operations when CF is not 20452;; required and register dies. Similarly for 128 to plus -128. 20453(define_peephole2 20454 [(set (match_operand 0 "flags_reg_operand" "") 20455 (match_operator 1 "compare_operator" 20456 [(match_operand 2 "register_operand" "") 20457 (match_operand 3 "const_int_operand" "")]))] 20458 "(INTVAL (operands[3]) == -1 20459 || INTVAL (operands[3]) == 1 20460 || INTVAL (operands[3]) == 128) 20461 && ix86_match_ccmode (insn, CCGCmode) 20462 && peep2_reg_dead_p (1, operands[2])" 20463 [(parallel [(set (match_dup 0) 20464 (match_op_dup 1 [(match_dup 2) (match_dup 3)])) 20465 (clobber (match_dup 2))])] 20466 "") 20467 20468(define_peephole2 20469 [(match_scratch:DI 0 "r") 20470 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 20471 (clobber (reg:CC FLAGS_REG)) 20472 (clobber (mem:BLK (scratch)))])] 20473 "optimize_size || !TARGET_SUB_ESP_4" 20474 [(clobber (match_dup 0)) 20475 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 20476 (clobber (mem:BLK (scratch)))])]) 20477 20478(define_peephole2 20479 [(match_scratch:DI 0 "r") 20480 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16))) 20481 (clobber (reg:CC FLAGS_REG)) 20482 (clobber (mem:BLK (scratch)))])] 20483 "optimize_size || !TARGET_SUB_ESP_8" 20484 [(clobber (match_dup 0)) 20485 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 20486 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 20487 (clobber (mem:BLK (scratch)))])]) 20488 20489;; Convert esp subtractions to push. 20490(define_peephole2 20491 [(match_scratch:DI 0 "r") 20492 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 20493 (clobber (reg:CC FLAGS_REG))])] 20494 "optimize_size || !TARGET_SUB_ESP_4" 20495 [(clobber (match_dup 0)) 20496 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))]) 20497 20498(define_peephole2 20499 [(match_scratch:DI 0 "r") 20500 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16))) 20501 (clobber (reg:CC FLAGS_REG))])] 20502 "optimize_size || !TARGET_SUB_ESP_8" 20503 [(clobber (match_dup 0)) 20504 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 20505 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))]) 20506 20507;; Convert epilogue deallocator to pop. 20508(define_peephole2 20509 [(match_scratch:DI 0 "r") 20510 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20511 (clobber (reg:CC FLAGS_REG)) 20512 (clobber (mem:BLK (scratch)))])] 20513 "optimize_size || !TARGET_ADD_ESP_4" 20514 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20515 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20516 (clobber (mem:BLK (scratch)))])] 20517 "") 20518 20519;; Two pops case is tricky, since pop causes dependency on destination register. 20520;; We use two registers if available. 20521(define_peephole2 20522 [(match_scratch:DI 0 "r") 20523 (match_scratch:DI 1 "r") 20524 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20525 (clobber (reg:CC FLAGS_REG)) 20526 (clobber (mem:BLK (scratch)))])] 20527 "optimize_size || !TARGET_ADD_ESP_8" 20528 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20529 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20530 (clobber (mem:BLK (scratch)))]) 20531 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG))) 20532 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20533 "") 20534 20535(define_peephole2 20536 [(match_scratch:DI 0 "r") 20537 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20538 (clobber (reg:CC FLAGS_REG)) 20539 (clobber (mem:BLK (scratch)))])] 20540 "optimize_size" 20541 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20542 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20543 (clobber (mem:BLK (scratch)))]) 20544 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20545 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20546 "") 20547 20548;; Convert esp additions to pop. 20549(define_peephole2 20550 [(match_scratch:DI 0 "r") 20551 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20552 (clobber (reg:CC FLAGS_REG))])] 20553 "" 20554 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20555 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20556 "") 20557 20558;; Two pops case is tricky, since pop causes dependency on destination register. 20559;; We use two registers if available. 20560(define_peephole2 20561 [(match_scratch:DI 0 "r") 20562 (match_scratch:DI 1 "r") 20563 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20564 (clobber (reg:CC FLAGS_REG))])] 20565 "" 20566 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20567 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))]) 20568 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG))) 20569 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20570 "") 20571 20572(define_peephole2 20573 [(match_scratch:DI 0 "r") 20574 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20575 (clobber (reg:CC FLAGS_REG))])] 20576 "optimize_size" 20577 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20578 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))]) 20579 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20580 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20581 "") 20582 20583;; Convert imul by three, five and nine into lea 20584(define_peephole2 20585 [(parallel 20586 [(set (match_operand:SI 0 "register_operand" "") 20587 (mult:SI (match_operand:SI 1 "register_operand" "") 20588 (match_operand:SI 2 "const_int_operand" ""))) 20589 (clobber (reg:CC FLAGS_REG))])] 20590 "INTVAL (operands[2]) == 3 20591 || INTVAL (operands[2]) == 5 20592 || INTVAL (operands[2]) == 9" 20593 [(set (match_dup 0) 20594 (plus:SI (mult:SI (match_dup 1) (match_dup 2)) 20595 (match_dup 1)))] 20596 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20597 20598(define_peephole2 20599 [(parallel 20600 [(set (match_operand:SI 0 "register_operand" "") 20601 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "") 20602 (match_operand:SI 2 "const_int_operand" ""))) 20603 (clobber (reg:CC FLAGS_REG))])] 20604 "!optimize_size 20605 && (INTVAL (operands[2]) == 3 20606 || INTVAL (operands[2]) == 5 20607 || INTVAL (operands[2]) == 9)" 20608 [(set (match_dup 0) (match_dup 1)) 20609 (set (match_dup 0) 20610 (plus:SI (mult:SI (match_dup 0) (match_dup 2)) 20611 (match_dup 0)))] 20612 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20613 20614(define_peephole2 20615 [(parallel 20616 [(set (match_operand:DI 0 "register_operand" "") 20617 (mult:DI (match_operand:DI 1 "register_operand" "") 20618 (match_operand:DI 2 "const_int_operand" ""))) 20619 (clobber (reg:CC FLAGS_REG))])] 20620 "TARGET_64BIT 20621 && (INTVAL (operands[2]) == 3 20622 || INTVAL (operands[2]) == 5 20623 || INTVAL (operands[2]) == 9)" 20624 [(set (match_dup 0) 20625 (plus:DI (mult:DI (match_dup 1) (match_dup 2)) 20626 (match_dup 1)))] 20627 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20628 20629(define_peephole2 20630 [(parallel 20631 [(set (match_operand:DI 0 "register_operand" "") 20632 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "") 20633 (match_operand:DI 2 "const_int_operand" ""))) 20634 (clobber (reg:CC FLAGS_REG))])] 20635 "TARGET_64BIT 20636 && !optimize_size 20637 && (INTVAL (operands[2]) == 3 20638 || INTVAL (operands[2]) == 5 20639 || INTVAL (operands[2]) == 9)" 20640 [(set (match_dup 0) (match_dup 1)) 20641 (set (match_dup 0) 20642 (plus:DI (mult:DI (match_dup 0) (match_dup 2)) 20643 (match_dup 0)))] 20644 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20645 20646;; Imul $32bit_imm, mem, reg is vector decoded, while 20647;; imul $32bit_imm, reg, reg is direct decoded. 20648(define_peephole2 20649 [(match_scratch:DI 3 "r") 20650 (parallel [(set (match_operand:DI 0 "register_operand" "") 20651 (mult:DI (match_operand:DI 1 "memory_operand" "") 20652 (match_operand:DI 2 "immediate_operand" ""))) 20653 (clobber (reg:CC FLAGS_REG))])] 20654 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size 20655 && !satisfies_constraint_K (operands[2])" 20656 [(set (match_dup 3) (match_dup 1)) 20657 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2))) 20658 (clobber (reg:CC FLAGS_REG))])] 20659"") 20660 20661(define_peephole2 20662 [(match_scratch:SI 3 "r") 20663 (parallel [(set (match_operand:SI 0 "register_operand" "") 20664 (mult:SI (match_operand:SI 1 "memory_operand" "") 20665 (match_operand:SI 2 "immediate_operand" ""))) 20666 (clobber (reg:CC FLAGS_REG))])] 20667 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size 20668 && !satisfies_constraint_K (operands[2])" 20669 [(set (match_dup 3) (match_dup 1)) 20670 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2))) 20671 (clobber (reg:CC FLAGS_REG))])] 20672"") 20673 20674(define_peephole2 20675 [(match_scratch:SI 3 "r") 20676 (parallel [(set (match_operand:DI 0 "register_operand" "") 20677 (zero_extend:DI 20678 (mult:SI (match_operand:SI 1 "memory_operand" "") 20679 (match_operand:SI 2 "immediate_operand" "")))) 20680 (clobber (reg:CC FLAGS_REG))])] 20681 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size 20682 && !satisfies_constraint_K (operands[2])" 20683 [(set (match_dup 3) (match_dup 1)) 20684 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2)))) 20685 (clobber (reg:CC FLAGS_REG))])] 20686"") 20687 20688;; imul $8/16bit_imm, regmem, reg is vector decoded. 20689;; Convert it into imul reg, reg 20690;; It would be better to force assembler to encode instruction using long 20691;; immediate, but there is apparently no way to do so. 20692(define_peephole2 20693 [(parallel [(set (match_operand:DI 0 "register_operand" "") 20694 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "") 20695 (match_operand:DI 2 "const_int_operand" ""))) 20696 (clobber (reg:CC FLAGS_REG))]) 20697 (match_scratch:DI 3 "r")] 20698 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size 20699 && satisfies_constraint_K (operands[2])" 20700 [(set (match_dup 3) (match_dup 2)) 20701 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3))) 20702 (clobber (reg:CC FLAGS_REG))])] 20703{ 20704 if (!rtx_equal_p (operands[0], operands[1])) 20705 emit_move_insn (operands[0], operands[1]); 20706}) 20707 20708(define_peephole2 20709 [(parallel [(set (match_operand:SI 0 "register_operand" "") 20710 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "") 20711 (match_operand:SI 2 "const_int_operand" ""))) 20712 (clobber (reg:CC FLAGS_REG))]) 20713 (match_scratch:SI 3 "r")] 20714 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size 20715 && satisfies_constraint_K (operands[2])" 20716 [(set (match_dup 3) (match_dup 2)) 20717 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3))) 20718 (clobber (reg:CC FLAGS_REG))])] 20719{ 20720 if (!rtx_equal_p (operands[0], operands[1])) 20721 emit_move_insn (operands[0], operands[1]); 20722}) 20723 20724(define_peephole2 20725 [(parallel [(set (match_operand:HI 0 "register_operand" "") 20726 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "") 20727 (match_operand:HI 2 "immediate_operand" ""))) 20728 (clobber (reg:CC FLAGS_REG))]) 20729 (match_scratch:HI 3 "r")] 20730 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size" 20731 [(set (match_dup 3) (match_dup 2)) 20732 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3))) 20733 (clobber (reg:CC FLAGS_REG))])] 20734{ 20735 if (!rtx_equal_p (operands[0], operands[1])) 20736 emit_move_insn (operands[0], operands[1]); 20737}) 20738 20739;; After splitting up read-modify operations, array accesses with memory 20740;; operands might end up in form: 20741;; sall $2, %eax 20742;; movl 4(%esp), %edx 20743;; addl %edx, %eax 20744;; instead of pre-splitting: 20745;; sall $2, %eax 20746;; addl 4(%esp), %eax 20747;; Turn it into: 20748;; movl 4(%esp), %edx 20749;; leal (%edx,%eax,4), %eax 20750 20751(define_peephole2 20752 [(parallel [(set (match_operand 0 "register_operand" "") 20753 (ashift (match_operand 1 "register_operand" "") 20754 (match_operand 2 "const_int_operand" ""))) 20755 (clobber (reg:CC FLAGS_REG))]) 20756 (set (match_operand 3 "register_operand") 20757 (match_operand 4 "x86_64_general_operand" "")) 20758 (parallel [(set (match_operand 5 "register_operand" "") 20759 (plus (match_operand 6 "register_operand" "") 20760 (match_operand 7 "register_operand" ""))) 20761 (clobber (reg:CC FLAGS_REG))])] 20762 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3 20763 /* Validate MODE for lea. */ 20764 && ((!TARGET_PARTIAL_REG_STALL 20765 && (GET_MODE (operands[0]) == QImode 20766 || GET_MODE (operands[0]) == HImode)) 20767 || GET_MODE (operands[0]) == SImode 20768 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) 20769 /* We reorder load and the shift. */ 20770 && !rtx_equal_p (operands[1], operands[3]) 20771 && !reg_overlap_mentioned_p (operands[0], operands[4]) 20772 /* Last PLUS must consist of operand 0 and 3. */ 20773 && !rtx_equal_p (operands[0], operands[3]) 20774 && (rtx_equal_p (operands[3], operands[6]) 20775 || rtx_equal_p (operands[3], operands[7])) 20776 && (rtx_equal_p (operands[0], operands[6]) 20777 || rtx_equal_p (operands[0], operands[7])) 20778 /* The intermediate operand 0 must die or be same as output. */ 20779 && (rtx_equal_p (operands[0], operands[5]) 20780 || peep2_reg_dead_p (3, operands[0]))" 20781 [(set (match_dup 3) (match_dup 4)) 20782 (set (match_dup 0) (match_dup 1))] 20783{ 20784 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode; 20785 int scale = 1 << INTVAL (operands[2]); 20786 rtx index = gen_lowpart (Pmode, operands[1]); 20787 rtx base = gen_lowpart (Pmode, operands[3]); 20788 rtx dest = gen_lowpart (mode, operands[5]); 20789 20790 operands[1] = gen_rtx_PLUS (Pmode, base, 20791 gen_rtx_MULT (Pmode, index, GEN_INT (scale))); 20792 if (mode != Pmode) 20793 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); 20794 operands[0] = dest; 20795}) 20796 20797;; Call-value patterns last so that the wildcard operand does not 20798;; disrupt insn-recog's switch tables. 20799 20800(define_insn "*call_value_pop_0" 20801 [(set (match_operand 0 "" "") 20802 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) 20803 (match_operand:SI 2 "" ""))) 20804 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 20805 (match_operand:SI 3 "immediate_operand" "")))] 20806 "!TARGET_64BIT" 20807{ 20808 if (SIBLING_CALL_P (insn)) 20809 return "jmp\t%P1"; 20810 else 20811 return "call\t%P1"; 20812} 20813 [(set_attr "type" "callv")]) 20814 20815(define_insn "*call_value_pop_1" 20816 [(set (match_operand 0 "" "") 20817 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm")) 20818 (match_operand:SI 2 "" ""))) 20819 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 20820 (match_operand:SI 3 "immediate_operand" "i")))] 20821 "!TARGET_64BIT" 20822{ 20823 if (constant_call_address_operand (operands[1], Pmode)) 20824 { 20825 if (SIBLING_CALL_P (insn)) 20826 return "jmp\t%P1"; 20827 else 20828 return "call\t%P1"; 20829 } 20830 if (SIBLING_CALL_P (insn)) 20831 return "jmp\t%A1"; 20832 else 20833 return "call\t%A1"; 20834} 20835 [(set_attr "type" "callv")]) 20836 20837(define_insn "*call_value_0" 20838 [(set (match_operand 0 "" "") 20839 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) 20840 (match_operand:SI 2 "" "")))] 20841 "!TARGET_64BIT" 20842{ 20843 if (SIBLING_CALL_P (insn)) 20844 return "jmp\t%P1"; 20845 else 20846 return "call\t%P1"; 20847} 20848 [(set_attr "type" "callv")]) 20849 20850(define_insn "*call_value_0_rex64" 20851 [(set (match_operand 0 "" "") 20852 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) 20853 (match_operand:DI 2 "const_int_operand" "")))] 20854 "TARGET_64BIT" 20855{ 20856 if (SIBLING_CALL_P (insn)) 20857 return "jmp\t%P1"; 20858 else 20859 return "call\t%P1"; 20860} 20861 [(set_attr "type" "callv")]) 20862 20863(define_insn "*call_value_1" 20864 [(set (match_operand 0 "" "") 20865 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm")) 20866 (match_operand:SI 2 "" "")))] 20867 "!SIBLING_CALL_P (insn) && !TARGET_64BIT" 20868{ 20869 if (constant_call_address_operand (operands[1], Pmode)) 20870 return "call\t%P1"; 20871 return "call\t%A1"; 20872} 20873 [(set_attr "type" "callv")]) 20874 20875(define_insn "*sibcall_value_1" 20876 [(set (match_operand 0 "" "") 20877 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a")) 20878 (match_operand:SI 2 "" "")))] 20879 "SIBLING_CALL_P (insn) && !TARGET_64BIT" 20880{ 20881 if (constant_call_address_operand (operands[1], Pmode)) 20882 return "jmp\t%P1"; 20883 return "jmp\t%A1"; 20884} 20885 [(set_attr "type" "callv")]) 20886 20887(define_insn "*call_value_1_rex64" 20888 [(set (match_operand 0 "" "") 20889 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm")) 20890 (match_operand:DI 2 "" "")))] 20891 "!SIBLING_CALL_P (insn) && TARGET_64BIT" 20892{ 20893 if (constant_call_address_operand (operands[1], Pmode)) 20894 return "call\t%P1"; 20895 return "call\t%A1"; 20896} 20897 [(set_attr "type" "callv")]) 20898 20899(define_insn "*sibcall_value_1_rex64" 20900 [(set (match_operand 0 "" "") 20901 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) 20902 (match_operand:DI 2 "" "")))] 20903 "SIBLING_CALL_P (insn) && TARGET_64BIT" 20904 "jmp\t%P1" 20905 [(set_attr "type" "callv")]) 20906 20907(define_insn "*sibcall_value_1_rex64_v" 20908 [(set (match_operand 0 "" "") 20909 (call (mem:QI (reg:DI 40)) 20910 (match_operand:DI 1 "" "")))] 20911 "SIBLING_CALL_P (insn) && TARGET_64BIT" 20912 "jmp\t*%%r11" 20913 [(set_attr "type" "callv")]) 20914 20915;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5. 20916;; That, however, is usually mapped by the OS to SIGSEGV, which is often 20917;; caught for use by garbage collectors and the like. Using an insn that 20918;; maps to SIGILL makes it more likely the program will rightfully die. 20919;; Keeping with tradition, "6" is in honor of #UD. 20920(define_insn "trap" 20921 [(trap_if (const_int 1) (const_int 6))] 20922 "" 20923 { return ASM_SHORT "0x0b0f"; } 20924 [(set_attr "length" "2")]) 20925 20926(define_expand "sse_prologue_save" 20927 [(parallel [(set (match_operand:BLK 0 "" "") 20928 (unspec:BLK [(reg:DI 21) 20929 (reg:DI 22) 20930 (reg:DI 23) 20931 (reg:DI 24) 20932 (reg:DI 25) 20933 (reg:DI 26) 20934 (reg:DI 27) 20935 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE)) 20936 (use (match_operand:DI 1 "register_operand" "")) 20937 (use (match_operand:DI 2 "immediate_operand" "")) 20938 (use (label_ref:DI (match_operand 3 "" "")))])] 20939 "TARGET_64BIT" 20940 "") 20941 20942(define_insn "*sse_prologue_save_insn" 20943 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R") 20944 (match_operand:DI 4 "const_int_operand" "n"))) 20945 (unspec:BLK [(reg:DI 21) 20946 (reg:DI 22) 20947 (reg:DI 23) 20948 (reg:DI 24) 20949 (reg:DI 25) 20950 (reg:DI 26) 20951 (reg:DI 27) 20952 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE)) 20953 (use (match_operand:DI 1 "register_operand" "r")) 20954 (use (match_operand:DI 2 "const_int_operand" "i")) 20955 (use (label_ref:DI (match_operand 3 "" "X")))] 20956 "TARGET_64BIT 20957 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128 20958 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128" 20959 "* 20960{ 20961 int i; 20962 operands[0] = gen_rtx_MEM (Pmode, 20963 gen_rtx_PLUS (Pmode, operands[0], operands[4])); 20964 output_asm_insn (\"jmp\\t%A1\", operands); 20965 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--) 20966 { 20967 operands[4] = adjust_address (operands[0], DImode, i*16); 20968 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i)); 20969 PUT_MODE (operands[4], TImode); 20970 if (GET_CODE (XEXP (operands[0], 0)) != PLUS) 20971 output_asm_insn (\"rex\", operands); 20972 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands); 20973 } 20974 (*targetm.asm_out.internal_label) (asm_out_file, \"L\", 20975 CODE_LABEL_NUMBER (operands[3])); 20976 RET; 20977} 20978 " 20979 [(set_attr "type" "other") 20980 (set_attr "length_immediate" "0") 20981 (set_attr "length_address" "0") 20982 (set_attr "length" "135") 20983 (set_attr "memory" "store") 20984 (set_attr "modrm" "0") 20985 (set_attr "mode" "DI")]) 20986 20987(define_expand "prefetch" 20988 [(prefetch (match_operand 0 "address_operand" "") 20989 (match_operand:SI 1 "const_int_operand" "") 20990 (match_operand:SI 2 "const_int_operand" ""))] 20991 "TARGET_PREFETCH_SSE || TARGET_3DNOW" 20992{ 20993 int rw = INTVAL (operands[1]); 20994 int locality = INTVAL (operands[2]); 20995 20996 gcc_assert (rw == 0 || rw == 1); 20997 gcc_assert (locality >= 0 && locality <= 3); 20998 gcc_assert (GET_MODE (operands[0]) == Pmode 20999 || GET_MODE (operands[0]) == VOIDmode); 21000 21001 /* Use 3dNOW prefetch in case we are asking for write prefetch not 21002 supported by SSE counterpart or the SSE prefetch is not available 21003 (K6 machines). Otherwise use SSE prefetch as it allows specifying 21004 of locality. */ 21005 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw)) 21006 operands[2] = GEN_INT (3); 21007 else 21008 operands[1] = const0_rtx; 21009}) 21010 21011(define_insn "*prefetch_sse" 21012 [(prefetch (match_operand:SI 0 "address_operand" "p") 21013 (const_int 0) 21014 (match_operand:SI 1 "const_int_operand" ""))] 21015 "TARGET_PREFETCH_SSE && !TARGET_64BIT" 21016{ 21017 static const char * const patterns[4] = { 21018 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" 21019 }; 21020 21021 int locality = INTVAL (operands[1]); 21022 gcc_assert (locality >= 0 && locality <= 3); 21023 21024 return patterns[locality]; 21025} 21026 [(set_attr "type" "sse") 21027 (set_attr "memory" "none")]) 21028 21029(define_insn "*prefetch_sse_rex" 21030 [(prefetch (match_operand:DI 0 "address_operand" "p") 21031 (const_int 0) 21032 (match_operand:SI 1 "const_int_operand" ""))] 21033 "TARGET_PREFETCH_SSE && TARGET_64BIT" 21034{ 21035 static const char * const patterns[4] = { 21036 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" 21037 }; 21038 21039 int locality = INTVAL (operands[1]); 21040 gcc_assert (locality >= 0 && locality <= 3); 21041 21042 return patterns[locality]; 21043} 21044 [(set_attr "type" "sse") 21045 (set_attr "memory" "none")]) 21046 21047(define_insn "*prefetch_3dnow" 21048 [(prefetch (match_operand:SI 0 "address_operand" "p") 21049 (match_operand:SI 1 "const_int_operand" "n") 21050 (const_int 3))] 21051 "TARGET_3DNOW && !TARGET_64BIT" 21052{ 21053 if (INTVAL (operands[1]) == 0) 21054 return "prefetch\t%a0"; 21055 else 21056 return "prefetchw\t%a0"; 21057} 21058 [(set_attr "type" "mmx") 21059 (set_attr "memory" "none")]) 21060 21061(define_insn "*prefetch_3dnow_rex" 21062 [(prefetch (match_operand:DI 0 "address_operand" "p") 21063 (match_operand:SI 1 "const_int_operand" "n") 21064 (const_int 3))] 21065 "TARGET_3DNOW && TARGET_64BIT" 21066{ 21067 if (INTVAL (operands[1]) == 0) 21068 return "prefetch\t%a0"; 21069 else 21070 return "prefetchw\t%a0"; 21071} 21072 [(set_attr "type" "mmx") 21073 (set_attr "memory" "none")]) 21074 21075(define_expand "stack_protect_set" 21076 [(match_operand 0 "memory_operand" "") 21077 (match_operand 1 "memory_operand" "")] 21078 "" 21079{ 21080#ifdef TARGET_THREAD_SSP_OFFSET 21081 if (TARGET_64BIT) 21082 emit_insn (gen_stack_tls_protect_set_di (operands[0], 21083 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 21084 else 21085 emit_insn (gen_stack_tls_protect_set_si (operands[0], 21086 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 21087#else 21088 if (TARGET_64BIT) 21089 emit_insn (gen_stack_protect_set_di (operands[0], operands[1])); 21090 else 21091 emit_insn (gen_stack_protect_set_si (operands[0], operands[1])); 21092#endif 21093 DONE; 21094}) 21095 21096(define_insn "stack_protect_set_si" 21097 [(set (match_operand:SI 0 "memory_operand" "=m") 21098 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 21099 (set (match_scratch:SI 2 "=&r") (const_int 0)) 21100 (clobber (reg:CC FLAGS_REG))] 21101 "" 21102 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2" 21103 [(set_attr "type" "multi")]) 21104 21105(define_insn "stack_protect_set_di" 21106 [(set (match_operand:DI 0 "memory_operand" "=m") 21107 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 21108 (set (match_scratch:DI 2 "=&r") (const_int 0)) 21109 (clobber (reg:CC FLAGS_REG))] 21110 "TARGET_64BIT" 21111 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" 21112 [(set_attr "type" "multi")]) 21113 21114(define_insn "stack_tls_protect_set_si" 21115 [(set (match_operand:SI 0 "memory_operand" "=m") 21116 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET)) 21117 (set (match_scratch:SI 2 "=&r") (const_int 0)) 21118 (clobber (reg:CC FLAGS_REG))] 21119 "" 21120 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2" 21121 [(set_attr "type" "multi")]) 21122 21123(define_insn "stack_tls_protect_set_di" 21124 [(set (match_operand:DI 0 "memory_operand" "=m") 21125 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET)) 21126 (set (match_scratch:DI 2 "=&r") (const_int 0)) 21127 (clobber (reg:CC FLAGS_REG))] 21128 "TARGET_64BIT" 21129 { 21130 /* The kernel uses a different segment register for performance reasons; a 21131 system call would not have to trash the userspace segment register, 21132 which would be expensive */ 21133 if (ix86_cmodel != CM_KERNEL) 21134 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"; 21135 else 21136 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"; 21137 } 21138 [(set_attr "type" "multi")]) 21139 21140(define_expand "stack_protect_test" 21141 [(match_operand 0 "memory_operand" "") 21142 (match_operand 1 "memory_operand" "") 21143 (match_operand 2 "" "")] 21144 "" 21145{ 21146 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG); 21147 ix86_compare_op0 = operands[0]; 21148 ix86_compare_op1 = operands[1]; 21149 ix86_compare_emitted = flags; 21150 21151#ifdef TARGET_THREAD_SSP_OFFSET 21152 if (TARGET_64BIT) 21153 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0], 21154 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 21155 else 21156 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0], 21157 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 21158#else 21159 if (TARGET_64BIT) 21160 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1])); 21161 else 21162 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1])); 21163#endif 21164 emit_jump_insn (gen_beq (operands[2])); 21165 DONE; 21166}) 21167 21168(define_insn "stack_protect_test_si" 21169 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 21170 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m") 21171 (match_operand:SI 2 "memory_operand" "m")] 21172 UNSPEC_SP_TEST)) 21173 (clobber (match_scratch:SI 3 "=&r"))] 21174 "" 21175 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}" 21176 [(set_attr "type" "multi")]) 21177 21178(define_insn "stack_protect_test_di" 21179 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 21180 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m") 21181 (match_operand:DI 2 "memory_operand" "m")] 21182 UNSPEC_SP_TEST)) 21183 (clobber (match_scratch:DI 3 "=&r"))] 21184 "TARGET_64BIT" 21185 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}" 21186 [(set_attr "type" "multi")]) 21187 21188(define_insn "stack_tls_protect_test_si" 21189 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 21190 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m") 21191 (match_operand:SI 2 "const_int_operand" "i")] 21192 UNSPEC_SP_TLS_TEST)) 21193 (clobber (match_scratch:SI 3 "=r"))] 21194 "" 21195 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}" 21196 [(set_attr "type" "multi")]) 21197 21198(define_insn "stack_tls_protect_test_di" 21199 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 21200 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m") 21201 (match_operand:DI 2 "const_int_operand" "i")] 21202 UNSPEC_SP_TLS_TEST)) 21203 (clobber (match_scratch:DI 3 "=r"))] 21204 "TARGET_64BIT" 21205 { 21206 /* The kernel uses a different segment register for performance reasons; a 21207 system call would not have to trash the userspace segment register, 21208 which would be expensive */ 21209 if (ix86_cmodel != CM_KERNEL) 21210 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"; 21211 else 21212 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}"; 21213 } 21214 [(set_attr "type" "multi")]) 21215 21216(include "mmx.md") 21217(include "sse.md") 21218(include "sync.md") 21219