i386.md revision 171835
1170231Sgrog;; GCC machine description for IA-32 and x86-64. 2170231Sgrog;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 3298107Sgjb;; 2001, 2002, 2003, 2004, 2005, 2006 4298107Sgjb;; Free Software Foundation, Inc. 5298107Sgjb;; Mostly by William Schelter. 6263227Sjmmv;; x86_64 support added by Jan Hubicka 7263227Sjmmv;; 8263227Sjmmv;; This file is part of GCC. 9263227Sjmmv;; 10263227Sjmmv;; GCC is free software; you can redistribute it and/or modify 11263227Sjmmv;; it under the terms of the GNU General Public License as published by 12263227Sjmmv;; the Free Software Foundation; either version 2, or (at your option) 13263227Sjmmv;; any later version. 14263227Sjmmv;; 15263227Sjmmv;; GCC is distributed in the hope that it will be useful, 16263227Sjmmv;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17263227Sjmmv;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18263227Sjmmv;; GNU General Public License for more details. 19263227Sjmmv;; 20263227Sjmmv;; You should have received a copy of the GNU General Public License 21263227Sjmmv;; along with GCC; see the file COPYING. If not, write to 22263227Sjmmv;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, 23263227Sjmmv;; Boston, MA 02110-1301, USA. */ 24263227Sjmmv;; 25263227Sjmmv;; The original PO technology requires these to be ordered by speed, 26263227Sjmmv;; so that assigner will pick the fastest. 27263227Sjmmv;; 28263227Sjmmv;; See file "rtl.def" for documentation on define_insn, match_*, et. al. 29263227Sjmmv;; 30263227Sjmmv;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register 31263227Sjmmv;; constraint letters. 32263227Sjmmv;; 33263227Sjmmv;; The special asm out single letter directives following a '%' are: 34263227Sjmmv;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of 35263227Sjmmv;; operands[1]. 36263227Sjmmv;; 'L' Print the opcode suffix for a 32-bit integer opcode. 37263227Sjmmv;; 'W' Print the opcode suffix for a 16-bit integer opcode. 38263227Sjmmv;; 'B' Print the opcode suffix for an 8-bit integer opcode. 39263227Sjmmv;; 'Q' Print the opcode suffix for a 64-bit float opcode. 40263227Sjmmv;; 'S' Print the opcode suffix for a 32-bit float opcode. 41;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode. 42;; 'J' Print the appropriate jump operand. 43;; 44;; 'b' Print the QImode name of the register for the indicated operand. 45;; %b0 would print %al if operands[0] is reg 0. 46;; 'w' Likewise, print the HImode name of the register. 47;; 'k' Likewise, print the SImode name of the register. 48;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh. 49;; 'y' Print "st(0)" instead of "st" as a register. 50 51;; UNSPEC usage: 52 53(define_constants 54 [; Relocation specifiers 55 (UNSPEC_GOT 0) 56 (UNSPEC_GOTOFF 1) 57 (UNSPEC_GOTPCREL 2) 58 (UNSPEC_GOTTPOFF 3) 59 (UNSPEC_TPOFF 4) 60 (UNSPEC_NTPOFF 5) 61 (UNSPEC_DTPOFF 6) 62 (UNSPEC_GOTNTPOFF 7) 63 (UNSPEC_INDNTPOFF 8) 64 65 ; Prologue support 66 (UNSPEC_STACK_ALLOC 11) 67 (UNSPEC_SET_GOT 12) 68 (UNSPEC_SSE_PROLOGUE_SAVE 13) 69 (UNSPEC_REG_SAVE 14) 70 (UNSPEC_DEF_CFA 15) 71 72 ; TLS support 73 (UNSPEC_TP 16) 74 (UNSPEC_TLS_GD 17) 75 (UNSPEC_TLS_LD_BASE 18) 76 (UNSPEC_TLSDESC 19) 77 78 ; Other random patterns 79 (UNSPEC_SCAS 20) 80 (UNSPEC_FNSTSW 21) 81 (UNSPEC_SAHF 22) 82 (UNSPEC_FSTCW 23) 83 (UNSPEC_ADD_CARRY 24) 84 (UNSPEC_FLDCW 25) 85 (UNSPEC_REP 26) 86 (UNSPEC_EH_RETURN 27) 87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase 88 89 ; For SSE/MMX support: 90 (UNSPEC_FIX_NOTRUNC 30) 91 (UNSPEC_MASKMOV 31) 92 (UNSPEC_MOVMSK 32) 93 (UNSPEC_MOVNT 33) 94 (UNSPEC_MOVU 34) 95 (UNSPEC_RCP 35) 96 (UNSPEC_RSQRT 36) 97 (UNSPEC_SFENCE 37) 98 (UNSPEC_NOP 38) ; prevents combiner cleverness 99 (UNSPEC_PFRCP 39) 100 (UNSPEC_PFRCPIT1 40) 101 (UNSPEC_PFRCPIT2 41) 102 (UNSPEC_PFRSQRT 42) 103 (UNSPEC_PFRSQIT1 43) 104 (UNSPEC_MFENCE 44) 105 (UNSPEC_LFENCE 45) 106 (UNSPEC_PSADBW 46) 107 (UNSPEC_LDQQU 47) 108 109 ; Generic math support 110 (UNSPEC_COPYSIGN 50) 111 (UNSPEC_IEEE_MIN 51) ; not commutative 112 (UNSPEC_IEEE_MAX 52) ; not commutative 113 114 ; x87 Floating point 115 (UNSPEC_SIN 60) 116 (UNSPEC_COS 61) 117 (UNSPEC_FPATAN 62) 118 (UNSPEC_FYL2X 63) 119 (UNSPEC_FYL2XP1 64) 120 (UNSPEC_FRNDINT 65) 121 (UNSPEC_FIST 66) 122 (UNSPEC_F2XM1 67) 123 124 ; x87 Rounding 125 (UNSPEC_FRNDINT_FLOOR 70) 126 (UNSPEC_FRNDINT_CEIL 71) 127 (UNSPEC_FRNDINT_TRUNC 72) 128 (UNSPEC_FRNDINT_MASK_PM 73) 129 (UNSPEC_FIST_FLOOR 74) 130 (UNSPEC_FIST_CEIL 75) 131 132 ; x87 Double output FP 133 (UNSPEC_SINCOS_COS 80) 134 (UNSPEC_SINCOS_SIN 81) 135 (UNSPEC_TAN_ONE 82) 136 (UNSPEC_TAN_TAN 83) 137 (UNSPEC_XTRACT_FRACT 84) 138 (UNSPEC_XTRACT_EXP 85) 139 (UNSPEC_FSCALE_FRACT 86) 140 (UNSPEC_FSCALE_EXP 87) 141 (UNSPEC_FPREM_F 88) 142 (UNSPEC_FPREM_U 89) 143 (UNSPEC_FPREM1_F 90) 144 (UNSPEC_FPREM1_U 91) 145 146 ; SSP patterns 147 (UNSPEC_SP_SET 100) 148 (UNSPEC_SP_TEST 101) 149 (UNSPEC_SP_TLS_SET 102) 150 (UNSPEC_SP_TLS_TEST 103) 151 ]) 152 153(define_constants 154 [(UNSPECV_BLOCKAGE 0) 155 (UNSPECV_STACK_PROBE 1) 156 (UNSPECV_EMMS 2) 157 (UNSPECV_LDMXCSR 3) 158 (UNSPECV_STMXCSR 4) 159 (UNSPECV_FEMMS 5) 160 (UNSPECV_CLFLUSH 6) 161 (UNSPECV_ALIGN 7) 162 (UNSPECV_MONITOR 8) 163 (UNSPECV_MWAIT 9) 164 (UNSPECV_CMPXCHG_1 10) 165 (UNSPECV_CMPXCHG_2 11) 166 (UNSPECV_XCHG 12) 167 (UNSPECV_LOCK 13) 168 ]) 169 170;; Registers by name. 171(define_constants 172 [(BP_REG 6) 173 (SP_REG 7) 174 (FLAGS_REG 17) 175 (FPSR_REG 18) 176 (DIRFLAG_REG 19) 177 ]) 178 179;; Insns whose names begin with "x86_" are emitted by gen_FOO calls 180;; from i386.c. 181 182;; In C guard expressions, put expressions which may be compile-time 183;; constants first. This allows for better optimization. For 184;; example, write "TARGET_64BIT && reload_completed", not 185;; "reload_completed && TARGET_64BIT". 186 187 188;; Processor type. This attribute must exactly match the processor_type 189;; enumeration in i386.h. 190(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona,generic32,generic64" 191 (const (symbol_ref "ix86_tune"))) 192 193;; A basic instruction type. Refinements due to arguments to be 194;; provided in other attributes. 195(define_attr "type" 196 "other,multi, 197 alu,alu1,negnot,imov,imovx,lea, 198 incdec,ishift,ishift1,rotate,rotate1,imul,idiv, 199 icmp,test,ibr,setcc,icmov, 200 push,pop,call,callv,leave, 201 str,cld, 202 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint, 203 sselog,sselog1,sseiadd,sseishft,sseimul, 204 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv, 205 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft" 206 (const_string "other")) 207 208;; Main data type used by the insn 209(define_attr "mode" 210 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF" 211 (const_string "unknown")) 212 213;; The CPU unit operations uses. 214(define_attr "unit" "integer,i387,sse,mmx,unknown" 215 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint") 216 (const_string "i387") 217 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul, 218 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv") 219 (const_string "sse") 220 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft") 221 (const_string "mmx") 222 (eq_attr "type" "other") 223 (const_string "unknown")] 224 (const_string "integer"))) 225 226;; The (bounding maximum) length of an instruction immediate. 227(define_attr "length_immediate" "" 228 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave") 229 (const_int 0) 230 (eq_attr "unit" "i387,sse,mmx") 231 (const_int 0) 232 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1, 233 imul,icmp,push,pop") 234 (symbol_ref "ix86_attr_length_immediate_default(insn,1)") 235 (eq_attr "type" "imov,test") 236 (symbol_ref "ix86_attr_length_immediate_default(insn,0)") 237 (eq_attr "type" "call") 238 (if_then_else (match_operand 0 "constant_call_address_operand" "") 239 (const_int 4) 240 (const_int 0)) 241 (eq_attr "type" "callv") 242 (if_then_else (match_operand 1 "constant_call_address_operand" "") 243 (const_int 4) 244 (const_int 0)) 245 ;; We don't know the size before shorten_branches. Expect 246 ;; the instruction to fit for better scheduling. 247 (eq_attr "type" "ibr") 248 (const_int 1) 249 ] 250 (symbol_ref "/* Update immediate_length and other attributes! */ 251 gcc_unreachable (),1"))) 252 253;; The (bounding maximum) length of an instruction address. 254(define_attr "length_address" "" 255 (cond [(eq_attr "type" "str,cld,other,multi,fxch") 256 (const_int 0) 257 (and (eq_attr "type" "call") 258 (match_operand 0 "constant_call_address_operand" "")) 259 (const_int 0) 260 (and (eq_attr "type" "callv") 261 (match_operand 1 "constant_call_address_operand" "")) 262 (const_int 0) 263 ] 264 (symbol_ref "ix86_attr_length_address_default (insn)"))) 265 266;; Set when length prefix is used. 267(define_attr "prefix_data16" "" 268 (if_then_else (ior (eq_attr "mode" "HI") 269 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF"))) 270 (const_int 1) 271 (const_int 0))) 272 273;; Set when string REP prefix is used. 274(define_attr "prefix_rep" "" 275 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF")) 276 (const_int 1) 277 (const_int 0))) 278 279;; Set when 0f opcode prefix is used. 280(define_attr "prefix_0f" "" 281 (if_then_else 282 (ior (eq_attr "type" "imovx,setcc,icmov") 283 (eq_attr "unit" "sse,mmx")) 284 (const_int 1) 285 (const_int 0))) 286 287;; Set when REX opcode prefix is used. 288(define_attr "prefix_rex" "" 289 (cond [(and (eq_attr "mode" "DI") 290 (eq_attr "type" "!push,pop,call,callv,leave,ibr")) 291 (const_int 1) 292 (and (eq_attr "mode" "QI") 293 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)") 294 (const_int 0))) 295 (const_int 1) 296 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)") 297 (const_int 0)) 298 (const_int 1) 299 ] 300 (const_int 0))) 301 302;; Set when modrm byte is used. 303(define_attr "modrm" "" 304 (cond [(eq_attr "type" "str,cld,leave") 305 (const_int 0) 306 (eq_attr "unit" "i387") 307 (const_int 0) 308 (and (eq_attr "type" "incdec") 309 (ior (match_operand:SI 1 "register_operand" "") 310 (match_operand:HI 1 "register_operand" ""))) 311 (const_int 0) 312 (and (eq_attr "type" "push") 313 (not (match_operand 1 "memory_operand" ""))) 314 (const_int 0) 315 (and (eq_attr "type" "pop") 316 (not (match_operand 0 "memory_operand" ""))) 317 (const_int 0) 318 (and (eq_attr "type" "imov") 319 (ior (and (match_operand 0 "register_operand" "") 320 (match_operand 1 "immediate_operand" "")) 321 (ior (and (match_operand 0 "ax_reg_operand" "") 322 (match_operand 1 "memory_displacement_only_operand" "")) 323 (and (match_operand 0 "memory_displacement_only_operand" "") 324 (match_operand 1 "ax_reg_operand" ""))))) 325 (const_int 0) 326 (and (eq_attr "type" "call") 327 (match_operand 0 "constant_call_address_operand" "")) 328 (const_int 0) 329 (and (eq_attr "type" "callv") 330 (match_operand 1 "constant_call_address_operand" "")) 331 (const_int 0) 332 ] 333 (const_int 1))) 334 335;; The (bounding maximum) length of an instruction in bytes. 336;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences. 337;; Later we may want to split them and compute proper length as for 338;; other insns. 339(define_attr "length" "" 340 (cond [(eq_attr "type" "other,multi,fistp,frndint") 341 (const_int 16) 342 (eq_attr "type" "fcmp") 343 (const_int 4) 344 (eq_attr "unit" "i387") 345 (plus (const_int 2) 346 (plus (attr "prefix_data16") 347 (attr "length_address")))] 348 (plus (plus (attr "modrm") 349 (plus (attr "prefix_0f") 350 (plus (attr "prefix_rex") 351 (const_int 1)))) 352 (plus (attr "prefix_rep") 353 (plus (attr "prefix_data16") 354 (plus (attr "length_immediate") 355 (attr "length_address"))))))) 356 357;; The `memory' attribute is `none' if no memory is referenced, `load' or 358;; `store' if there is a simple memory reference therein, or `unknown' 359;; if the instruction is complex. 360 361(define_attr "memory" "none,load,store,both,unknown" 362 (cond [(eq_attr "type" "other,multi,str") 363 (const_string "unknown") 364 (eq_attr "type" "lea,fcmov,fpspc,cld") 365 (const_string "none") 366 (eq_attr "type" "fistp,leave") 367 (const_string "both") 368 (eq_attr "type" "frndint") 369 (const_string "load") 370 (eq_attr "type" "push") 371 (if_then_else (match_operand 1 "memory_operand" "") 372 (const_string "both") 373 (const_string "store")) 374 (eq_attr "type" "pop") 375 (if_then_else (match_operand 0 "memory_operand" "") 376 (const_string "both") 377 (const_string "load")) 378 (eq_attr "type" "setcc") 379 (if_then_else (match_operand 0 "memory_operand" "") 380 (const_string "store") 381 (const_string "none")) 382 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp") 383 (if_then_else (ior (match_operand 0 "memory_operand" "") 384 (match_operand 1 "memory_operand" "")) 385 (const_string "load") 386 (const_string "none")) 387 (eq_attr "type" "ibr") 388 (if_then_else (match_operand 0 "memory_operand" "") 389 (const_string "load") 390 (const_string "none")) 391 (eq_attr "type" "call") 392 (if_then_else (match_operand 0 "constant_call_address_operand" "") 393 (const_string "none") 394 (const_string "load")) 395 (eq_attr "type" "callv") 396 (if_then_else (match_operand 1 "constant_call_address_operand" "") 397 (const_string "none") 398 (const_string "load")) 399 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1") 400 (match_operand 1 "memory_operand" "")) 401 (const_string "both") 402 (and (match_operand 0 "memory_operand" "") 403 (match_operand 1 "memory_operand" "")) 404 (const_string "both") 405 (match_operand 0 "memory_operand" "") 406 (const_string "store") 407 (match_operand 1 "memory_operand" "") 408 (const_string "load") 409 (and (eq_attr "type" 410 "!alu1,negnot,ishift1, 411 imov,imovx,icmp,test, 412 fmov,fcmp,fsgn, 413 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1, 414 mmx,mmxmov,mmxcmp,mmxcvt") 415 (match_operand 2 "memory_operand" "")) 416 (const_string "load") 417 (and (eq_attr "type" "icmov") 418 (match_operand 3 "memory_operand" "")) 419 (const_string "load") 420 ] 421 (const_string "none"))) 422 423;; Indicates if an instruction has both an immediate and a displacement. 424 425(define_attr "imm_disp" "false,true,unknown" 426 (cond [(eq_attr "type" "other,multi") 427 (const_string "unknown") 428 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1") 429 (and (match_operand 0 "memory_displacement_operand" "") 430 (match_operand 1 "immediate_operand" ""))) 431 (const_string "true") 432 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv") 433 (and (match_operand 0 "memory_displacement_operand" "") 434 (match_operand 2 "immediate_operand" ""))) 435 (const_string "true") 436 ] 437 (const_string "false"))) 438 439;; Indicates if an FP operation has an integer source. 440 441(define_attr "fp_int_src" "false,true" 442 (const_string "false")) 443 444;; Defines rounding mode of an FP operation. 445 446(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any" 447 (const_string "any")) 448 449;; Describe a user's asm statement. 450(define_asm_attributes 451 [(set_attr "length" "128") 452 (set_attr "type" "multi")]) 453 454;; All x87 floating point modes 455(define_mode_macro X87MODEF [SF DF XF]) 456 457;; All integer modes handled by x87 fisttp operator. 458(define_mode_macro X87MODEI [HI SI DI]) 459 460;; All integer modes handled by integer x87 operators. 461(define_mode_macro X87MODEI12 [HI SI]) 462 463;; All SSE floating point modes 464(define_mode_macro SSEMODEF [SF DF]) 465 466;; All integer modes handled by SSE cvtts?2si* operators. 467(define_mode_macro SSEMODEI24 [SI DI]) 468 469 470;; Scheduling descriptions 471 472(include "pentium.md") 473(include "ppro.md") 474(include "k6.md") 475(include "athlon.md") 476 477 478;; Operand and operator predicates and constraints 479 480(include "predicates.md") 481(include "constraints.md") 482 483 484;; Compare instructions. 485 486;; All compare insns have expanders that save the operands away without 487;; actually generating RTL. The bCOND or sCOND (emitted immediately 488;; after the cmp) will actually emit the cmpM. 489 490(define_expand "cmpti" 491 [(set (reg:CC FLAGS_REG) 492 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "") 493 (match_operand:TI 1 "x86_64_general_operand" "")))] 494 "TARGET_64BIT" 495{ 496 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 497 operands[0] = force_reg (TImode, operands[0]); 498 ix86_compare_op0 = operands[0]; 499 ix86_compare_op1 = operands[1]; 500 DONE; 501}) 502 503(define_expand "cmpdi" 504 [(set (reg:CC FLAGS_REG) 505 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "") 506 (match_operand:DI 1 "x86_64_general_operand" "")))] 507 "" 508{ 509 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 510 operands[0] = force_reg (DImode, operands[0]); 511 ix86_compare_op0 = operands[0]; 512 ix86_compare_op1 = operands[1]; 513 DONE; 514}) 515 516(define_expand "cmpsi" 517 [(set (reg:CC FLAGS_REG) 518 (compare:CC (match_operand:SI 0 "cmpsi_operand" "") 519 (match_operand:SI 1 "general_operand" "")))] 520 "" 521{ 522 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 523 operands[0] = force_reg (SImode, operands[0]); 524 ix86_compare_op0 = operands[0]; 525 ix86_compare_op1 = operands[1]; 526 DONE; 527}) 528 529(define_expand "cmphi" 530 [(set (reg:CC FLAGS_REG) 531 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "") 532 (match_operand:HI 1 "general_operand" "")))] 533 "" 534{ 535 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 536 operands[0] = force_reg (HImode, operands[0]); 537 ix86_compare_op0 = operands[0]; 538 ix86_compare_op1 = operands[1]; 539 DONE; 540}) 541 542(define_expand "cmpqi" 543 [(set (reg:CC FLAGS_REG) 544 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "") 545 (match_operand:QI 1 "general_operand" "")))] 546 "TARGET_QIMODE_MATH" 547{ 548 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 549 operands[0] = force_reg (QImode, operands[0]); 550 ix86_compare_op0 = operands[0]; 551 ix86_compare_op1 = operands[1]; 552 DONE; 553}) 554 555(define_insn "cmpdi_ccno_1_rex64" 556 [(set (reg FLAGS_REG) 557 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr") 558 (match_operand:DI 1 "const0_operand" "n,n")))] 559 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 560 "@ 561 test{q}\t{%0, %0|%0, %0} 562 cmp{q}\t{%1, %0|%0, %1}" 563 [(set_attr "type" "test,icmp") 564 (set_attr "length_immediate" "0,1") 565 (set_attr "mode" "DI")]) 566 567(define_insn "*cmpdi_minus_1_rex64" 568 [(set (reg FLAGS_REG) 569 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r") 570 (match_operand:DI 1 "x86_64_general_operand" "re,mr")) 571 (const_int 0)))] 572 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)" 573 "cmp{q}\t{%1, %0|%0, %1}" 574 [(set_attr "type" "icmp") 575 (set_attr "mode" "DI")]) 576 577(define_expand "cmpdi_1_rex64" 578 [(set (reg:CC FLAGS_REG) 579 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "") 580 (match_operand:DI 1 "general_operand" "")))] 581 "TARGET_64BIT" 582 "") 583 584(define_insn "cmpdi_1_insn_rex64" 585 [(set (reg FLAGS_REG) 586 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r") 587 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))] 588 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 589 "cmp{q}\t{%1, %0|%0, %1}" 590 [(set_attr "type" "icmp") 591 (set_attr "mode" "DI")]) 592 593 594(define_insn "*cmpsi_ccno_1" 595 [(set (reg FLAGS_REG) 596 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr") 597 (match_operand:SI 1 "const0_operand" "n,n")))] 598 "ix86_match_ccmode (insn, CCNOmode)" 599 "@ 600 test{l}\t{%0, %0|%0, %0} 601 cmp{l}\t{%1, %0|%0, %1}" 602 [(set_attr "type" "test,icmp") 603 (set_attr "length_immediate" "0,1") 604 (set_attr "mode" "SI")]) 605 606(define_insn "*cmpsi_minus_1" 607 [(set (reg FLAGS_REG) 608 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r") 609 (match_operand:SI 1 "general_operand" "ri,mr")) 610 (const_int 0)))] 611 "ix86_match_ccmode (insn, CCGOCmode)" 612 "cmp{l}\t{%1, %0|%0, %1}" 613 [(set_attr "type" "icmp") 614 (set_attr "mode" "SI")]) 615 616(define_expand "cmpsi_1" 617 [(set (reg:CC FLAGS_REG) 618 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r") 619 (match_operand:SI 1 "general_operand" "ri,mr")))] 620 "" 621 "") 622 623(define_insn "*cmpsi_1_insn" 624 [(set (reg FLAGS_REG) 625 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r") 626 (match_operand:SI 1 "general_operand" "ri,mr")))] 627 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 628 && ix86_match_ccmode (insn, CCmode)" 629 "cmp{l}\t{%1, %0|%0, %1}" 630 [(set_attr "type" "icmp") 631 (set_attr "mode" "SI")]) 632 633(define_insn "*cmphi_ccno_1" 634 [(set (reg FLAGS_REG) 635 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr") 636 (match_operand:HI 1 "const0_operand" "n,n")))] 637 "ix86_match_ccmode (insn, CCNOmode)" 638 "@ 639 test{w}\t{%0, %0|%0, %0} 640 cmp{w}\t{%1, %0|%0, %1}" 641 [(set_attr "type" "test,icmp") 642 (set_attr "length_immediate" "0,1") 643 (set_attr "mode" "HI")]) 644 645(define_insn "*cmphi_minus_1" 646 [(set (reg FLAGS_REG) 647 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r") 648 (match_operand:HI 1 "general_operand" "ri,mr")) 649 (const_int 0)))] 650 "ix86_match_ccmode (insn, CCGOCmode)" 651 "cmp{w}\t{%1, %0|%0, %1}" 652 [(set_attr "type" "icmp") 653 (set_attr "mode" "HI")]) 654 655(define_insn "*cmphi_1" 656 [(set (reg FLAGS_REG) 657 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r") 658 (match_operand:HI 1 "general_operand" "ri,mr")))] 659 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 660 && ix86_match_ccmode (insn, CCmode)" 661 "cmp{w}\t{%1, %0|%0, %1}" 662 [(set_attr "type" "icmp") 663 (set_attr "mode" "HI")]) 664 665(define_insn "*cmpqi_ccno_1" 666 [(set (reg FLAGS_REG) 667 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq") 668 (match_operand:QI 1 "const0_operand" "n,n")))] 669 "ix86_match_ccmode (insn, CCNOmode)" 670 "@ 671 test{b}\t{%0, %0|%0, %0} 672 cmp{b}\t{$0, %0|%0, 0}" 673 [(set_attr "type" "test,icmp") 674 (set_attr "length_immediate" "0,1") 675 (set_attr "mode" "QI")]) 676 677(define_insn "*cmpqi_1" 678 [(set (reg FLAGS_REG) 679 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q") 680 (match_operand:QI 1 "general_operand" "qi,mq")))] 681 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 682 && ix86_match_ccmode (insn, CCmode)" 683 "cmp{b}\t{%1, %0|%0, %1}" 684 [(set_attr "type" "icmp") 685 (set_attr "mode" "QI")]) 686 687(define_insn "*cmpqi_minus_1" 688 [(set (reg FLAGS_REG) 689 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q") 690 (match_operand:QI 1 "general_operand" "qi,mq")) 691 (const_int 0)))] 692 "ix86_match_ccmode (insn, CCGOCmode)" 693 "cmp{b}\t{%1, %0|%0, %1}" 694 [(set_attr "type" "icmp") 695 (set_attr "mode" "QI")]) 696 697(define_insn "*cmpqi_ext_1" 698 [(set (reg FLAGS_REG) 699 (compare 700 (match_operand:QI 0 "general_operand" "Qm") 701 (subreg:QI 702 (zero_extract:SI 703 (match_operand 1 "ext_register_operand" "Q") 704 (const_int 8) 705 (const_int 8)) 0)))] 706 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 707 "cmp{b}\t{%h1, %0|%0, %h1}" 708 [(set_attr "type" "icmp") 709 (set_attr "mode" "QI")]) 710 711(define_insn "*cmpqi_ext_1_rex64" 712 [(set (reg FLAGS_REG) 713 (compare 714 (match_operand:QI 0 "register_operand" "Q") 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_2" 726 [(set (reg FLAGS_REG) 727 (compare 728 (subreg:QI 729 (zero_extract:SI 730 (match_operand 0 "ext_register_operand" "Q") 731 (const_int 8) 732 (const_int 8)) 0) 733 (match_operand:QI 1 "const0_operand" "n")))] 734 "ix86_match_ccmode (insn, CCNOmode)" 735 "test{b}\t%h0, %h0" 736 [(set_attr "type" "test") 737 (set_attr "length_immediate" "0") 738 (set_attr "mode" "QI")]) 739 740(define_expand "cmpqi_ext_3" 741 [(set (reg:CC FLAGS_REG) 742 (compare:CC 743 (subreg:QI 744 (zero_extract:SI 745 (match_operand 0 "ext_register_operand" "") 746 (const_int 8) 747 (const_int 8)) 0) 748 (match_operand:QI 1 "general_operand" "")))] 749 "" 750 "") 751 752(define_insn "cmpqi_ext_3_insn" 753 [(set (reg FLAGS_REG) 754 (compare 755 (subreg:QI 756 (zero_extract:SI 757 (match_operand 0 "ext_register_operand" "Q") 758 (const_int 8) 759 (const_int 8)) 0) 760 (match_operand:QI 1 "general_operand" "Qmn")))] 761 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)" 762 "cmp{b}\t{%1, %h0|%h0, %1}" 763 [(set_attr "type" "icmp") 764 (set_attr "mode" "QI")]) 765 766(define_insn "cmpqi_ext_3_insn_rex64" 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 "nonmemory_operand" "Qn")))] 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_4" 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 (subreg:QI 789 (zero_extract:SI 790 (match_operand 1 "ext_register_operand" "Q") 791 (const_int 8) 792 (const_int 8)) 0)))] 793 "ix86_match_ccmode (insn, CCmode)" 794 "cmp{b}\t{%h1, %h0|%h0, %h1}" 795 [(set_attr "type" "icmp") 796 (set_attr "mode" "QI")]) 797 798;; These implement float point compares. 799;; %%% See if we can get away with VOIDmode operands on the actual insns, 800;; which would allow mix and match FP modes on the compares. Which is what 801;; the old patterns did, but with many more of them. 802 803(define_expand "cmpxf" 804 [(set (reg:CC FLAGS_REG) 805 (compare:CC (match_operand:XF 0 "nonmemory_operand" "") 806 (match_operand:XF 1 "nonmemory_operand" "")))] 807 "TARGET_80387" 808{ 809 ix86_compare_op0 = operands[0]; 810 ix86_compare_op1 = operands[1]; 811 DONE; 812}) 813 814(define_expand "cmpdf" 815 [(set (reg:CC FLAGS_REG) 816 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "") 817 (match_operand:DF 1 "cmp_fp_expander_operand" "")))] 818 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 819{ 820 ix86_compare_op0 = operands[0]; 821 ix86_compare_op1 = operands[1]; 822 DONE; 823}) 824 825(define_expand "cmpsf" 826 [(set (reg:CC FLAGS_REG) 827 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "") 828 (match_operand:SF 1 "cmp_fp_expander_operand" "")))] 829 "TARGET_80387 || TARGET_SSE_MATH" 830{ 831 ix86_compare_op0 = operands[0]; 832 ix86_compare_op1 = operands[1]; 833 DONE; 834}) 835 836;; FP compares, step 1: 837;; Set the FP condition codes. 838;; 839;; CCFPmode compare with exceptions 840;; CCFPUmode compare with no exceptions 841 842;; We may not use "#" to split and emit these, since the REG_DEAD notes 843;; used to manage the reg stack popping would not be preserved. 844 845(define_insn "*cmpfp_0" 846 [(set (match_operand:HI 0 "register_operand" "=a") 847 (unspec:HI 848 [(compare:CCFP 849 (match_operand 1 "register_operand" "f") 850 (match_operand 2 "const0_operand" "X"))] 851 UNSPEC_FNSTSW))] 852 "TARGET_80387 853 && FLOAT_MODE_P (GET_MODE (operands[1])) 854 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 855 "* return output_fp_compare (insn, operands, 0, 0);" 856 [(set_attr "type" "multi") 857 (set_attr "unit" "i387") 858 (set (attr "mode") 859 (cond [(match_operand:SF 1 "" "") 860 (const_string "SF") 861 (match_operand:DF 1 "" "") 862 (const_string "DF") 863 ] 864 (const_string "XF")))]) 865 866(define_insn "*cmpfp_sf" 867 [(set (match_operand:HI 0 "register_operand" "=a") 868 (unspec:HI 869 [(compare:CCFP 870 (match_operand:SF 1 "register_operand" "f") 871 (match_operand:SF 2 "nonimmediate_operand" "fm"))] 872 UNSPEC_FNSTSW))] 873 "TARGET_80387" 874 "* return output_fp_compare (insn, operands, 0, 0);" 875 [(set_attr "type" "multi") 876 (set_attr "unit" "i387") 877 (set_attr "mode" "SF")]) 878 879(define_insn "*cmpfp_df" 880 [(set (match_operand:HI 0 "register_operand" "=a") 881 (unspec:HI 882 [(compare:CCFP 883 (match_operand:DF 1 "register_operand" "f") 884 (match_operand:DF 2 "nonimmediate_operand" "fm"))] 885 UNSPEC_FNSTSW))] 886 "TARGET_80387" 887 "* return output_fp_compare (insn, operands, 0, 0);" 888 [(set_attr "type" "multi") 889 (set_attr "unit" "i387") 890 (set_attr "mode" "DF")]) 891 892(define_insn "*cmpfp_xf" 893 [(set (match_operand:HI 0 "register_operand" "=a") 894 (unspec:HI 895 [(compare:CCFP 896 (match_operand:XF 1 "register_operand" "f") 897 (match_operand:XF 2 "register_operand" "f"))] 898 UNSPEC_FNSTSW))] 899 "TARGET_80387" 900 "* return output_fp_compare (insn, operands, 0, 0);" 901 [(set_attr "type" "multi") 902 (set_attr "unit" "i387") 903 (set_attr "mode" "XF")]) 904 905(define_insn "*cmpfp_u" 906 [(set (match_operand:HI 0 "register_operand" "=a") 907 (unspec:HI 908 [(compare:CCFPU 909 (match_operand 1 "register_operand" "f") 910 (match_operand 2 "register_operand" "f"))] 911 UNSPEC_FNSTSW))] 912 "TARGET_80387 913 && FLOAT_MODE_P (GET_MODE (operands[1])) 914 && GET_MODE (operands[1]) == GET_MODE (operands[2])" 915 "* return output_fp_compare (insn, operands, 0, 1);" 916 [(set_attr "type" "multi") 917 (set_attr "unit" "i387") 918 (set (attr "mode") 919 (cond [(match_operand:SF 1 "" "") 920 (const_string "SF") 921 (match_operand:DF 1 "" "") 922 (const_string "DF") 923 ] 924 (const_string "XF")))]) 925 926(define_insn "*cmpfp_<mode>" 927 [(set (match_operand:HI 0 "register_operand" "=a") 928 (unspec:HI 929 [(compare:CCFP 930 (match_operand 1 "register_operand" "f") 931 (match_operator 3 "float_operator" 932 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))] 933 UNSPEC_FNSTSW))] 934 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 935 && FLOAT_MODE_P (GET_MODE (operands[1])) 936 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))" 937 "* return output_fp_compare (insn, operands, 0, 0);" 938 [(set_attr "type" "multi") 939 (set_attr "unit" "i387") 940 (set_attr "fp_int_src" "true") 941 (set_attr "mode" "<MODE>")]) 942 943;; FP compares, step 2 944;; Move the fpsw to ax. 945 946(define_insn "x86_fnstsw_1" 947 [(set (match_operand:HI 0 "register_operand" "=a") 948 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))] 949 "TARGET_80387" 950 "fnstsw\t%0" 951 [(set_attr "length" "2") 952 (set_attr "mode" "SI") 953 (set_attr "unit" "i387")]) 954 955;; FP compares, step 3 956;; Get ax into flags, general case. 957 958(define_insn "x86_sahf_1" 959 [(set (reg:CC FLAGS_REG) 960 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))] 961 "!TARGET_64BIT" 962 "sahf" 963 [(set_attr "length" "1") 964 (set_attr "athlon_decode" "vector") 965 (set_attr "mode" "SI")]) 966 967;; Pentium Pro can do steps 1 through 3 in one go. 968 969(define_insn "*cmpfp_i_mixed" 970 [(set (reg:CCFP FLAGS_REG) 971 (compare:CCFP (match_operand 0 "register_operand" "f,x") 972 (match_operand 1 "nonimmediate_operand" "f,xm")))] 973 "TARGET_MIX_SSE_I387 974 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 975 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 976 "* return output_fp_compare (insn, operands, 1, 0);" 977 [(set_attr "type" "fcmp,ssecomi") 978 (set (attr "mode") 979 (if_then_else (match_operand:SF 1 "" "") 980 (const_string "SF") 981 (const_string "DF"))) 982 (set_attr "athlon_decode" "vector")]) 983 984(define_insn "*cmpfp_i_sse" 985 [(set (reg:CCFP FLAGS_REG) 986 (compare:CCFP (match_operand 0 "register_operand" "x") 987 (match_operand 1 "nonimmediate_operand" "xm")))] 988 "TARGET_SSE_MATH 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" "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 999(define_insn "*cmpfp_i_i387" 1000 [(set (reg:CCFP FLAGS_REG) 1001 (compare:CCFP (match_operand 0 "register_operand" "f") 1002 (match_operand 1 "register_operand" "f")))] 1003 "TARGET_80387 && TARGET_CMOVE 1004 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))) 1005 && 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" "fcmp") 1009 (set (attr "mode") 1010 (cond [(match_operand:SF 1 "" "") 1011 (const_string "SF") 1012 (match_operand:DF 1 "" "") 1013 (const_string "DF") 1014 ] 1015 (const_string "XF"))) 1016 (set_attr "athlon_decode" "vector")]) 1017 1018(define_insn "*cmpfp_iu_mixed" 1019 [(set (reg:CCFPU FLAGS_REG) 1020 (compare:CCFPU (match_operand 0 "register_operand" "f,x") 1021 (match_operand 1 "nonimmediate_operand" "f,xm")))] 1022 "TARGET_MIX_SSE_I387 1023 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1024 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1025 "* return output_fp_compare (insn, operands, 1, 1);" 1026 [(set_attr "type" "fcmp,ssecomi") 1027 (set (attr "mode") 1028 (if_then_else (match_operand:SF 1 "" "") 1029 (const_string "SF") 1030 (const_string "DF"))) 1031 (set_attr "athlon_decode" "vector")]) 1032 1033(define_insn "*cmpfp_iu_sse" 1034 [(set (reg:CCFPU FLAGS_REG) 1035 (compare:CCFPU (match_operand 0 "register_operand" "x") 1036 (match_operand 1 "nonimmediate_operand" "xm")))] 1037 "TARGET_SSE_MATH 1038 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) 1039 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1040 "* return output_fp_compare (insn, operands, 1, 1);" 1041 [(set_attr "type" "ssecomi") 1042 (set (attr "mode") 1043 (if_then_else (match_operand:SF 1 "" "") 1044 (const_string "SF") 1045 (const_string "DF"))) 1046 (set_attr "athlon_decode" "vector")]) 1047 1048(define_insn "*cmpfp_iu_387" 1049 [(set (reg:CCFPU FLAGS_REG) 1050 (compare:CCFPU (match_operand 0 "register_operand" "f") 1051 (match_operand 1 "register_operand" "f")))] 1052 "TARGET_80387 && TARGET_CMOVE 1053 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))) 1054 && FLOAT_MODE_P (GET_MODE (operands[0])) 1055 && GET_MODE (operands[0]) == GET_MODE (operands[1])" 1056 "* return output_fp_compare (insn, operands, 1, 1);" 1057 [(set_attr "type" "fcmp") 1058 (set (attr "mode") 1059 (cond [(match_operand:SF 1 "" "") 1060 (const_string "SF") 1061 (match_operand:DF 1 "" "") 1062 (const_string "DF") 1063 ] 1064 (const_string "XF"))) 1065 (set_attr "athlon_decode" "vector")]) 1066 1067;; Move instructions. 1068 1069;; General case of fullword move. 1070 1071(define_expand "movsi" 1072 [(set (match_operand:SI 0 "nonimmediate_operand" "") 1073 (match_operand:SI 1 "general_operand" ""))] 1074 "" 1075 "ix86_expand_move (SImode, operands); DONE;") 1076 1077;; Push/pop instructions. They are separate since autoinc/dec is not a 1078;; general_operand. 1079;; 1080;; %%% We don't use a post-inc memory reference because x86 is not a 1081;; general AUTO_INC_DEC host, which impacts how it is treated in flow. 1082;; Changing this impacts compiler performance on other non-AUTO_INC_DEC 1083;; targets without our curiosities, and it is just as easy to represent 1084;; this differently. 1085 1086(define_insn "*pushsi2" 1087 [(set (match_operand:SI 0 "push_operand" "=<") 1088 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))] 1089 "!TARGET_64BIT" 1090 "push{l}\t%1" 1091 [(set_attr "type" "push") 1092 (set_attr "mode" "SI")]) 1093 1094;; For 64BIT abi we always round up to 8 bytes. 1095(define_insn "*pushsi2_rex64" 1096 [(set (match_operand:SI 0 "push_operand" "=X") 1097 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))] 1098 "TARGET_64BIT" 1099 "push{q}\t%q1" 1100 [(set_attr "type" "push") 1101 (set_attr "mode" "SI")]) 1102 1103(define_insn "*pushsi2_prologue" 1104 [(set (match_operand:SI 0 "push_operand" "=<") 1105 (match_operand:SI 1 "general_no_elim_operand" "ri*m")) 1106 (clobber (mem:BLK (scratch)))] 1107 "!TARGET_64BIT" 1108 "push{l}\t%1" 1109 [(set_attr "type" "push") 1110 (set_attr "mode" "SI")]) 1111 1112(define_insn "*popsi1_epilogue" 1113 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m") 1114 (mem:SI (reg:SI SP_REG))) 1115 (set (reg:SI SP_REG) 1116 (plus:SI (reg:SI SP_REG) (const_int 4))) 1117 (clobber (mem:BLK (scratch)))] 1118 "!TARGET_64BIT" 1119 "pop{l}\t%0" 1120 [(set_attr "type" "pop") 1121 (set_attr "mode" "SI")]) 1122 1123(define_insn "popsi1" 1124 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m") 1125 (mem:SI (reg:SI SP_REG))) 1126 (set (reg:SI SP_REG) 1127 (plus:SI (reg:SI SP_REG) (const_int 4)))] 1128 "!TARGET_64BIT" 1129 "pop{l}\t%0" 1130 [(set_attr "type" "pop") 1131 (set_attr "mode" "SI")]) 1132 1133(define_insn "*movsi_xor" 1134 [(set (match_operand:SI 0 "register_operand" "=r") 1135 (match_operand:SI 1 "const0_operand" "i")) 1136 (clobber (reg:CC FLAGS_REG))] 1137 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)" 1138 "xor{l}\t{%0, %0|%0, %0}" 1139 [(set_attr "type" "alu1") 1140 (set_attr "mode" "SI") 1141 (set_attr "length_immediate" "0")]) 1142 1143(define_insn "*movsi_or" 1144 [(set (match_operand:SI 0 "register_operand" "=r") 1145 (match_operand:SI 1 "immediate_operand" "i")) 1146 (clobber (reg:CC FLAGS_REG))] 1147 "reload_completed 1148 && operands[1] == constm1_rtx 1149 && (TARGET_PENTIUM || optimize_size)" 1150{ 1151 operands[1] = constm1_rtx; 1152 return "or{l}\t{%1, %0|%0, %1}"; 1153} 1154 [(set_attr "type" "alu1") 1155 (set_attr "mode" "SI") 1156 (set_attr "length_immediate" "1")]) 1157 1158(define_insn "*movsi_1" 1159 [(set (match_operand:SI 0 "nonimmediate_operand" 1160 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x") 1161 (match_operand:SI 1 "general_operand" 1162 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))] 1163 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 1164{ 1165 switch (get_attr_type (insn)) 1166 { 1167 case TYPE_SSELOG1: 1168 if (get_attr_mode (insn) == MODE_TI) 1169 return "pxor\t%0, %0"; 1170 return "xorps\t%0, %0"; 1171 1172 case TYPE_SSEMOV: 1173 switch (get_attr_mode (insn)) 1174 { 1175 case MODE_TI: 1176 return "movdqa\t{%1, %0|%0, %1}"; 1177 case MODE_V4SF: 1178 return "movaps\t{%1, %0|%0, %1}"; 1179 case MODE_SI: 1180 return "movd\t{%1, %0|%0, %1}"; 1181 case MODE_SF: 1182 return "movss\t{%1, %0|%0, %1}"; 1183 default: 1184 gcc_unreachable (); 1185 } 1186 1187 case TYPE_MMXADD: 1188 return "pxor\t%0, %0"; 1189 1190 case TYPE_MMXMOV: 1191 if (get_attr_mode (insn) == MODE_DI) 1192 return "movq\t{%1, %0|%0, %1}"; 1193 return "movd\t{%1, %0|%0, %1}"; 1194 1195 case TYPE_LEA: 1196 return "lea{l}\t{%1, %0|%0, %1}"; 1197 1198 default: 1199 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 1200 return "mov{l}\t{%1, %0|%0, %1}"; 1201 } 1202} 1203 [(set (attr "type") 1204 (cond [(eq_attr "alternative" "2") 1205 (const_string "mmxadd") 1206 (eq_attr "alternative" "3,4,5") 1207 (const_string "mmxmov") 1208 (eq_attr "alternative" "6") 1209 (const_string "sselog1") 1210 (eq_attr "alternative" "7,8,9,10,11") 1211 (const_string "ssemov") 1212 (match_operand:DI 1 "pic_32bit_operand" "") 1213 (const_string "lea") 1214 ] 1215 (const_string "imov"))) 1216 (set (attr "mode") 1217 (cond [(eq_attr "alternative" "2,3") 1218 (const_string "DI") 1219 (eq_attr "alternative" "6,7") 1220 (if_then_else 1221 (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 1222 (const_string "V4SF") 1223 (const_string "TI")) 1224 (and (eq_attr "alternative" "8,9,10,11") 1225 (eq (symbol_ref "TARGET_SSE2") (const_int 0))) 1226 (const_string "SF") 1227 ] 1228 (const_string "SI")))]) 1229 1230;; Stores and loads of ax to arbitrary constant address. 1231;; We fake an second form of instruction to force reload to load address 1232;; into register when rax is not available 1233(define_insn "*movabssi_1_rex64" 1234 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 1235 (match_operand:SI 1 "nonmemory_operand" "a,er"))] 1236 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 1237 "@ 1238 movabs{l}\t{%1, %P0|%P0, %1} 1239 mov{l}\t{%1, %a0|%a0, %1}" 1240 [(set_attr "type" "imov") 1241 (set_attr "modrm" "0,*") 1242 (set_attr "length_address" "8,0") 1243 (set_attr "length_immediate" "0,*") 1244 (set_attr "memory" "store") 1245 (set_attr "mode" "SI")]) 1246 1247(define_insn "*movabssi_2_rex64" 1248 [(set (match_operand:SI 0 "register_operand" "=a,r") 1249 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 1250 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 1251 "@ 1252 movabs{l}\t{%P1, %0|%0, %P1} 1253 mov{l}\t{%a1, %0|%0, %a1}" 1254 [(set_attr "type" "imov") 1255 (set_attr "modrm" "0,*") 1256 (set_attr "length_address" "8,0") 1257 (set_attr "length_immediate" "0") 1258 (set_attr "memory" "load") 1259 (set_attr "mode" "SI")]) 1260 1261(define_insn "*swapsi" 1262 [(set (match_operand:SI 0 "register_operand" "+r") 1263 (match_operand:SI 1 "register_operand" "+r")) 1264 (set (match_dup 1) 1265 (match_dup 0))] 1266 "" 1267 "xchg{l}\t%1, %0" 1268 [(set_attr "type" "imov") 1269 (set_attr "mode" "SI") 1270 (set_attr "pent_pair" "np") 1271 (set_attr "athlon_decode" "vector")]) 1272 1273(define_expand "movhi" 1274 [(set (match_operand:HI 0 "nonimmediate_operand" "") 1275 (match_operand:HI 1 "general_operand" ""))] 1276 "" 1277 "ix86_expand_move (HImode, operands); DONE;") 1278 1279(define_insn "*pushhi2" 1280 [(set (match_operand:HI 0 "push_operand" "=X") 1281 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))] 1282 "!TARGET_64BIT" 1283 "push{l}\t%k1" 1284 [(set_attr "type" "push") 1285 (set_attr "mode" "SI")]) 1286 1287;; For 64BIT abi we always round up to 8 bytes. 1288(define_insn "*pushhi2_rex64" 1289 [(set (match_operand:HI 0 "push_operand" "=X") 1290 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))] 1291 "TARGET_64BIT" 1292 "push{q}\t%q1" 1293 [(set_attr "type" "push") 1294 (set_attr "mode" "DI")]) 1295 1296(define_insn "*movhi_1" 1297 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m") 1298 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))] 1299 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 1300{ 1301 switch (get_attr_type (insn)) 1302 { 1303 case TYPE_IMOVX: 1304 /* movzwl is faster than movw on p2 due to partial word stalls, 1305 though not as fast as an aligned movl. */ 1306 return "movz{wl|x}\t{%1, %k0|%k0, %1}"; 1307 default: 1308 if (get_attr_mode (insn) == MODE_SI) 1309 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 1310 else 1311 return "mov{w}\t{%1, %0|%0, %1}"; 1312 } 1313} 1314 [(set (attr "type") 1315 (cond [(ne (symbol_ref "optimize_size") (const_int 0)) 1316 (const_string "imov") 1317 (and (eq_attr "alternative" "0") 1318 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1319 (const_int 0)) 1320 (eq (symbol_ref "TARGET_HIMODE_MATH") 1321 (const_int 0)))) 1322 (const_string "imov") 1323 (and (eq_attr "alternative" "1,2") 1324 (match_operand:HI 1 "aligned_operand" "")) 1325 (const_string "imov") 1326 (and (ne (symbol_ref "TARGET_MOVX") 1327 (const_int 0)) 1328 (eq_attr "alternative" "0,2")) 1329 (const_string "imovx") 1330 ] 1331 (const_string "imov"))) 1332 (set (attr "mode") 1333 (cond [(eq_attr "type" "imovx") 1334 (const_string "SI") 1335 (and (eq_attr "alternative" "1,2") 1336 (match_operand:HI 1 "aligned_operand" "")) 1337 (const_string "SI") 1338 (and (eq_attr "alternative" "0") 1339 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1340 (const_int 0)) 1341 (eq (symbol_ref "TARGET_HIMODE_MATH") 1342 (const_int 0)))) 1343 (const_string "SI") 1344 ] 1345 (const_string "HI")))]) 1346 1347;; Stores and loads of ax to arbitrary constant address. 1348;; We fake an second form of instruction to force reload to load address 1349;; into register when rax is not available 1350(define_insn "*movabshi_1_rex64" 1351 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 1352 (match_operand:HI 1 "nonmemory_operand" "a,er"))] 1353 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 1354 "@ 1355 movabs{w}\t{%1, %P0|%P0, %1} 1356 mov{w}\t{%1, %a0|%a0, %1}" 1357 [(set_attr "type" "imov") 1358 (set_attr "modrm" "0,*") 1359 (set_attr "length_address" "8,0") 1360 (set_attr "length_immediate" "0,*") 1361 (set_attr "memory" "store") 1362 (set_attr "mode" "HI")]) 1363 1364(define_insn "*movabshi_2_rex64" 1365 [(set (match_operand:HI 0 "register_operand" "=a,r") 1366 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 1367 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 1368 "@ 1369 movabs{w}\t{%P1, %0|%0, %P1} 1370 mov{w}\t{%a1, %0|%0, %a1}" 1371 [(set_attr "type" "imov") 1372 (set_attr "modrm" "0,*") 1373 (set_attr "length_address" "8,0") 1374 (set_attr "length_immediate" "0") 1375 (set_attr "memory" "load") 1376 (set_attr "mode" "HI")]) 1377 1378(define_insn "*swaphi_1" 1379 [(set (match_operand:HI 0 "register_operand" "+r") 1380 (match_operand:HI 1 "register_operand" "+r")) 1381 (set (match_dup 1) 1382 (match_dup 0))] 1383 "!TARGET_PARTIAL_REG_STALL || optimize_size" 1384 "xchg{l}\t%k1, %k0" 1385 [(set_attr "type" "imov") 1386 (set_attr "mode" "SI") 1387 (set_attr "pent_pair" "np") 1388 (set_attr "athlon_decode" "vector")]) 1389 1390(define_insn "*swaphi_2" 1391 [(set (match_operand:HI 0 "register_operand" "+r") 1392 (match_operand:HI 1 "register_operand" "+r")) 1393 (set (match_dup 1) 1394 (match_dup 0))] 1395 "TARGET_PARTIAL_REG_STALL" 1396 "xchg{w}\t%1, %0" 1397 [(set_attr "type" "imov") 1398 (set_attr "mode" "HI") 1399 (set_attr "pent_pair" "np") 1400 (set_attr "athlon_decode" "vector")]) 1401 1402(define_expand "movstricthi" 1403 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "")) 1404 (match_operand:HI 1 "general_operand" ""))] 1405 "! TARGET_PARTIAL_REG_STALL || optimize_size" 1406{ 1407 /* Don't generate memory->memory moves, go through a register */ 1408 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 1409 operands[1] = force_reg (HImode, operands[1]); 1410}) 1411 1412(define_insn "*movstricthi_1" 1413 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r")) 1414 (match_operand:HI 1 "general_operand" "rn,m"))] 1415 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 1416 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 1417 "mov{w}\t{%1, %0|%0, %1}" 1418 [(set_attr "type" "imov") 1419 (set_attr "mode" "HI")]) 1420 1421(define_insn "*movstricthi_xor" 1422 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) 1423 (match_operand:HI 1 "const0_operand" "i")) 1424 (clobber (reg:CC FLAGS_REG))] 1425 "reload_completed 1426 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)" 1427 "xor{w}\t{%0, %0|%0, %0}" 1428 [(set_attr "type" "alu1") 1429 (set_attr "mode" "HI") 1430 (set_attr "length_immediate" "0")]) 1431 1432(define_expand "movqi" 1433 [(set (match_operand:QI 0 "nonimmediate_operand" "") 1434 (match_operand:QI 1 "general_operand" ""))] 1435 "" 1436 "ix86_expand_move (QImode, operands); DONE;") 1437 1438;; emit_push_insn when it calls move_by_pieces requires an insn to 1439;; "push a byte". But actually we use pushl, which has the effect 1440;; of rounding the amount pushed up to a word. 1441 1442(define_insn "*pushqi2" 1443 [(set (match_operand:QI 0 "push_operand" "=X") 1444 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))] 1445 "!TARGET_64BIT" 1446 "push{l}\t%k1" 1447 [(set_attr "type" "push") 1448 (set_attr "mode" "SI")]) 1449 1450;; For 64BIT abi we always round up to 8 bytes. 1451(define_insn "*pushqi2_rex64" 1452 [(set (match_operand:QI 0 "push_operand" "=X") 1453 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))] 1454 "TARGET_64BIT" 1455 "push{q}\t%q1" 1456 [(set_attr "type" "push") 1457 (set_attr "mode" "DI")]) 1458 1459;; Situation is quite tricky about when to choose full sized (SImode) move 1460;; over QImode moves. For Q_REG -> Q_REG move we use full size only for 1461;; partial register dependency machines (such as AMD Athlon), where QImode 1462;; moves issue extra dependency and for partial register stalls machines 1463;; that don't use QImode patterns (and QImode move cause stall on the next 1464;; instruction). 1465;; 1466;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial 1467;; register stall machines with, where we use QImode instructions, since 1468;; partial register stall can be caused there. Then we use movzx. 1469(define_insn "*movqi_1" 1470 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m") 1471 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))] 1472 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 1473{ 1474 switch (get_attr_type (insn)) 1475 { 1476 case TYPE_IMOVX: 1477 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM); 1478 return "movz{bl|x}\t{%1, %k0|%k0, %1}"; 1479 default: 1480 if (get_attr_mode (insn) == MODE_SI) 1481 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 1482 else 1483 return "mov{b}\t{%1, %0|%0, %1}"; 1484 } 1485} 1486 [(set (attr "type") 1487 (cond [(and (eq_attr "alternative" "5") 1488 (not (match_operand:QI 1 "aligned_operand" ""))) 1489 (const_string "imovx") 1490 (ne (symbol_ref "optimize_size") (const_int 0)) 1491 (const_string "imov") 1492 (and (eq_attr "alternative" "3") 1493 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1494 (const_int 0)) 1495 (eq (symbol_ref "TARGET_QIMODE_MATH") 1496 (const_int 0)))) 1497 (const_string "imov") 1498 (eq_attr "alternative" "3,5") 1499 (const_string "imovx") 1500 (and (ne (symbol_ref "TARGET_MOVX") 1501 (const_int 0)) 1502 (eq_attr "alternative" "2")) 1503 (const_string "imovx") 1504 ] 1505 (const_string "imov"))) 1506 (set (attr "mode") 1507 (cond [(eq_attr "alternative" "3,4,5") 1508 (const_string "SI") 1509 (eq_attr "alternative" "6") 1510 (const_string "QI") 1511 (eq_attr "type" "imovx") 1512 (const_string "SI") 1513 (and (eq_attr "type" "imov") 1514 (and (eq_attr "alternative" "0,1") 1515 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY") 1516 (const_int 0)) 1517 (and (eq (symbol_ref "optimize_size") 1518 (const_int 0)) 1519 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL") 1520 (const_int 0)))))) 1521 (const_string "SI") 1522 ;; Avoid partial register stalls when not using QImode arithmetic 1523 (and (eq_attr "type" "imov") 1524 (and (eq_attr "alternative" "0,1") 1525 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL") 1526 (const_int 0)) 1527 (eq (symbol_ref "TARGET_QIMODE_MATH") 1528 (const_int 0))))) 1529 (const_string "SI") 1530 ] 1531 (const_string "QI")))]) 1532 1533(define_expand "reload_outqi" 1534 [(parallel [(match_operand:QI 0 "" "=m") 1535 (match_operand:QI 1 "register_operand" "r") 1536 (match_operand:QI 2 "register_operand" "=&q")])] 1537 "" 1538{ 1539 rtx op0, op1, op2; 1540 op0 = operands[0]; op1 = operands[1]; op2 = operands[2]; 1541 1542 gcc_assert (!reg_overlap_mentioned_p (op2, op0)); 1543 if (! q_regs_operand (op1, QImode)) 1544 { 1545 emit_insn (gen_movqi (op2, op1)); 1546 op1 = op2; 1547 } 1548 emit_insn (gen_movqi (op0, op1)); 1549 DONE; 1550}) 1551 1552(define_insn "*swapqi_1" 1553 [(set (match_operand:QI 0 "register_operand" "+r") 1554 (match_operand:QI 1 "register_operand" "+r")) 1555 (set (match_dup 1) 1556 (match_dup 0))] 1557 "!TARGET_PARTIAL_REG_STALL || optimize_size" 1558 "xchg{l}\t%k1, %k0" 1559 [(set_attr "type" "imov") 1560 (set_attr "mode" "SI") 1561 (set_attr "pent_pair" "np") 1562 (set_attr "athlon_decode" "vector")]) 1563 1564(define_insn "*swapqi_2" 1565 [(set (match_operand:QI 0 "register_operand" "+q") 1566 (match_operand:QI 1 "register_operand" "+q")) 1567 (set (match_dup 1) 1568 (match_dup 0))] 1569 "TARGET_PARTIAL_REG_STALL" 1570 "xchg{b}\t%1, %0" 1571 [(set_attr "type" "imov") 1572 (set_attr "mode" "QI") 1573 (set_attr "pent_pair" "np") 1574 (set_attr "athlon_decode" "vector")]) 1575 1576(define_expand "movstrictqi" 1577 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 1578 (match_operand:QI 1 "general_operand" ""))] 1579 "! TARGET_PARTIAL_REG_STALL || optimize_size" 1580{ 1581 /* Don't generate memory->memory moves, go through a register. */ 1582 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 1583 operands[1] = force_reg (QImode, operands[1]); 1584}) 1585 1586(define_insn "*movstrictqi_1" 1587 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 1588 (match_operand:QI 1 "general_operand" "*qn,m"))] 1589 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 1590 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 1591 "mov{b}\t{%1, %0|%0, %1}" 1592 [(set_attr "type" "imov") 1593 (set_attr "mode" "QI")]) 1594 1595(define_insn "*movstrictqi_xor" 1596 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q")) 1597 (match_operand:QI 1 "const0_operand" "i")) 1598 (clobber (reg:CC FLAGS_REG))] 1599 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)" 1600 "xor{b}\t{%0, %0|%0, %0}" 1601 [(set_attr "type" "alu1") 1602 (set_attr "mode" "QI") 1603 (set_attr "length_immediate" "0")]) 1604 1605(define_insn "*movsi_extv_1" 1606 [(set (match_operand:SI 0 "register_operand" "=R") 1607 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q") 1608 (const_int 8) 1609 (const_int 8)))] 1610 "" 1611 "movs{bl|x}\t{%h1, %0|%0, %h1}" 1612 [(set_attr "type" "imovx") 1613 (set_attr "mode" "SI")]) 1614 1615(define_insn "*movhi_extv_1" 1616 [(set (match_operand:HI 0 "register_operand" "=R") 1617 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q") 1618 (const_int 8) 1619 (const_int 8)))] 1620 "" 1621 "movs{bl|x}\t{%h1, %k0|%k0, %h1}" 1622 [(set_attr "type" "imovx") 1623 (set_attr "mode" "SI")]) 1624 1625(define_insn "*movqi_extv_1" 1626 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r") 1627 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") 1628 (const_int 8) 1629 (const_int 8)))] 1630 "!TARGET_64BIT" 1631{ 1632 switch (get_attr_type (insn)) 1633 { 1634 case TYPE_IMOVX: 1635 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; 1636 default: 1637 return "mov{b}\t{%h1, %0|%0, %h1}"; 1638 } 1639} 1640 [(set (attr "type") 1641 (if_then_else (and (match_operand:QI 0 "register_operand" "") 1642 (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1643 (ne (symbol_ref "TARGET_MOVX") 1644 (const_int 0)))) 1645 (const_string "imovx") 1646 (const_string "imov"))) 1647 (set (attr "mode") 1648 (if_then_else (eq_attr "type" "imovx") 1649 (const_string "SI") 1650 (const_string "QI")))]) 1651 1652(define_insn "*movqi_extv_1_rex64" 1653 [(set (match_operand:QI 0 "register_operand" "=Q,?R") 1654 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q") 1655 (const_int 8) 1656 (const_int 8)))] 1657 "TARGET_64BIT" 1658{ 1659 switch (get_attr_type (insn)) 1660 { 1661 case TYPE_IMOVX: 1662 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; 1663 default: 1664 return "mov{b}\t{%h1, %0|%0, %h1}"; 1665 } 1666} 1667 [(set (attr "type") 1668 (if_then_else (and (match_operand:QI 0 "register_operand" "") 1669 (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1670 (ne (symbol_ref "TARGET_MOVX") 1671 (const_int 0)))) 1672 (const_string "imovx") 1673 (const_string "imov"))) 1674 (set (attr "mode") 1675 (if_then_else (eq_attr "type" "imovx") 1676 (const_string "SI") 1677 (const_string "QI")))]) 1678 1679;; Stores and loads of ax to arbitrary constant address. 1680;; We fake an second form of instruction to force reload to load address 1681;; into register when rax is not available 1682(define_insn "*movabsqi_1_rex64" 1683 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 1684 (match_operand:QI 1 "nonmemory_operand" "a,er"))] 1685 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 1686 "@ 1687 movabs{b}\t{%1, %P0|%P0, %1} 1688 mov{b}\t{%1, %a0|%a0, %1}" 1689 [(set_attr "type" "imov") 1690 (set_attr "modrm" "0,*") 1691 (set_attr "length_address" "8,0") 1692 (set_attr "length_immediate" "0,*") 1693 (set_attr "memory" "store") 1694 (set_attr "mode" "QI")]) 1695 1696(define_insn "*movabsqi_2_rex64" 1697 [(set (match_operand:QI 0 "register_operand" "=a,r") 1698 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 1699 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 1700 "@ 1701 movabs{b}\t{%P1, %0|%0, %P1} 1702 mov{b}\t{%a1, %0|%0, %a1}" 1703 [(set_attr "type" "imov") 1704 (set_attr "modrm" "0,*") 1705 (set_attr "length_address" "8,0") 1706 (set_attr "length_immediate" "0") 1707 (set_attr "memory" "load") 1708 (set_attr "mode" "QI")]) 1709 1710(define_insn "*movdi_extzv_1" 1711 [(set (match_operand:DI 0 "register_operand" "=R") 1712 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q") 1713 (const_int 8) 1714 (const_int 8)))] 1715 "TARGET_64BIT" 1716 "movz{bl|x}\t{%h1, %k0|%k0, %h1}" 1717 [(set_attr "type" "imovx") 1718 (set_attr "mode" "DI")]) 1719 1720(define_insn "*movsi_extzv_1" 1721 [(set (match_operand:SI 0 "register_operand" "=R") 1722 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q") 1723 (const_int 8) 1724 (const_int 8)))] 1725 "" 1726 "movz{bl|x}\t{%h1, %0|%0, %h1}" 1727 [(set_attr "type" "imovx") 1728 (set_attr "mode" "SI")]) 1729 1730(define_insn "*movqi_extzv_2" 1731 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R") 1732 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") 1733 (const_int 8) 1734 (const_int 8)) 0))] 1735 "!TARGET_64BIT" 1736{ 1737 switch (get_attr_type (insn)) 1738 { 1739 case TYPE_IMOVX: 1740 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 1741 default: 1742 return "mov{b}\t{%h1, %0|%0, %h1}"; 1743 } 1744} 1745 [(set (attr "type") 1746 (if_then_else (and (match_operand:QI 0 "register_operand" "") 1747 (ior (not (match_operand:QI 0 "q_regs_operand" "")) 1748 (ne (symbol_ref "TARGET_MOVX") 1749 (const_int 0)))) 1750 (const_string "imovx") 1751 (const_string "imov"))) 1752 (set (attr "mode") 1753 (if_then_else (eq_attr "type" "imovx") 1754 (const_string "SI") 1755 (const_string "QI")))]) 1756 1757(define_insn "*movqi_extzv_2_rex64" 1758 [(set (match_operand:QI 0 "register_operand" "=Q,?R") 1759 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q") 1760 (const_int 8) 1761 (const_int 8)) 0))] 1762 "TARGET_64BIT" 1763{ 1764 switch (get_attr_type (insn)) 1765 { 1766 case TYPE_IMOVX: 1767 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 1768 default: 1769 return "mov{b}\t{%h1, %0|%0, %h1}"; 1770 } 1771} 1772 [(set (attr "type") 1773 (if_then_else (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 "movsi_insv_1" 1784 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 1785 (const_int 8) 1786 (const_int 8)) 1787 (match_operand:SI 1 "general_operand" "Qmn"))] 1788 "!TARGET_64BIT" 1789 "mov{b}\t{%b1, %h0|%h0, %b1}" 1790 [(set_attr "type" "imov") 1791 (set_attr "mode" "QI")]) 1792 1793(define_insn "movdi_insv_1_rex64" 1794 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q") 1795 (const_int 8) 1796 (const_int 8)) 1797 (match_operand:DI 1 "nonmemory_operand" "Qn"))] 1798 "TARGET_64BIT" 1799 "mov{b}\t{%b1, %h0|%h0, %b1}" 1800 [(set_attr "type" "imov") 1801 (set_attr "mode" "QI")]) 1802 1803(define_insn "*movqi_insv_2" 1804 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 1805 (const_int 8) 1806 (const_int 8)) 1807 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q") 1808 (const_int 8)))] 1809 "" 1810 "mov{b}\t{%h1, %h0|%h0, %h1}" 1811 [(set_attr "type" "imov") 1812 (set_attr "mode" "QI")]) 1813 1814(define_expand "movdi" 1815 [(set (match_operand:DI 0 "nonimmediate_operand" "") 1816 (match_operand:DI 1 "general_operand" ""))] 1817 "" 1818 "ix86_expand_move (DImode, operands); DONE;") 1819 1820(define_insn "*pushdi" 1821 [(set (match_operand:DI 0 "push_operand" "=<") 1822 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))] 1823 "!TARGET_64BIT" 1824 "#") 1825 1826(define_insn "*pushdi2_rex64" 1827 [(set (match_operand:DI 0 "push_operand" "=<,!<") 1828 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))] 1829 "TARGET_64BIT" 1830 "@ 1831 push{q}\t%1 1832 #" 1833 [(set_attr "type" "push,multi") 1834 (set_attr "mode" "DI")]) 1835 1836;; Convert impossible pushes of immediate to existing instructions. 1837;; First try to get scratch register and go through it. In case this 1838;; fails, push sign extended lower part first and then overwrite 1839;; upper part by 32bit move. 1840(define_peephole2 1841 [(match_scratch:DI 2 "r") 1842 (set (match_operand:DI 0 "push_operand" "") 1843 (match_operand:DI 1 "immediate_operand" ""))] 1844 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1845 && !x86_64_immediate_operand (operands[1], DImode)" 1846 [(set (match_dup 2) (match_dup 1)) 1847 (set (match_dup 0) (match_dup 2))] 1848 "") 1849 1850;; We need to define this as both peepholer and splitter for case 1851;; peephole2 pass is not run. 1852;; "&& 1" is needed to keep it from matching the previous pattern. 1853(define_peephole2 1854 [(set (match_operand:DI 0 "push_operand" "") 1855 (match_operand:DI 1 "immediate_operand" ""))] 1856 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1857 && !x86_64_immediate_operand (operands[1], DImode) && 1" 1858 [(set (match_dup 0) (match_dup 1)) 1859 (set (match_dup 2) (match_dup 3))] 1860 "split_di (operands + 1, 1, operands + 2, operands + 3); 1861 operands[1] = gen_lowpart (DImode, operands[2]); 1862 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, 1863 GEN_INT (4))); 1864 ") 1865 1866(define_split 1867 [(set (match_operand:DI 0 "push_operand" "") 1868 (match_operand:DI 1 "immediate_operand" ""))] 1869 "TARGET_64BIT && ((optimize > 0 && flag_peephole2) 1870 ? flow2_completed : reload_completed) 1871 && !symbolic_operand (operands[1], DImode) 1872 && !x86_64_immediate_operand (operands[1], DImode)" 1873 [(set (match_dup 0) (match_dup 1)) 1874 (set (match_dup 2) (match_dup 3))] 1875 "split_di (operands + 1, 1, operands + 2, operands + 3); 1876 operands[1] = gen_lowpart (DImode, operands[2]); 1877 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx, 1878 GEN_INT (4))); 1879 ") 1880 1881(define_insn "*pushdi2_prologue_rex64" 1882 [(set (match_operand:DI 0 "push_operand" "=<") 1883 (match_operand:DI 1 "general_no_elim_operand" "re*m")) 1884 (clobber (mem:BLK (scratch)))] 1885 "TARGET_64BIT" 1886 "push{q}\t%1" 1887 [(set_attr "type" "push") 1888 (set_attr "mode" "DI")]) 1889 1890(define_insn "*popdi1_epilogue_rex64" 1891 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m") 1892 (mem:DI (reg:DI SP_REG))) 1893 (set (reg:DI SP_REG) 1894 (plus:DI (reg:DI SP_REG) (const_int 8))) 1895 (clobber (mem:BLK (scratch)))] 1896 "TARGET_64BIT" 1897 "pop{q}\t%0" 1898 [(set_attr "type" "pop") 1899 (set_attr "mode" "DI")]) 1900 1901(define_insn "popdi1" 1902 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m") 1903 (mem:DI (reg:DI SP_REG))) 1904 (set (reg:DI SP_REG) 1905 (plus:DI (reg:DI SP_REG) (const_int 8)))] 1906 "TARGET_64BIT" 1907 "pop{q}\t%0" 1908 [(set_attr "type" "pop") 1909 (set_attr "mode" "DI")]) 1910 1911(define_insn "*movdi_xor_rex64" 1912 [(set (match_operand:DI 0 "register_operand" "=r") 1913 (match_operand:DI 1 "const0_operand" "i")) 1914 (clobber (reg:CC FLAGS_REG))] 1915 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size) 1916 && reload_completed" 1917 "xor{l}\t{%k0, %k0|%k0, %k0}" 1918 [(set_attr "type" "alu1") 1919 (set_attr "mode" "SI") 1920 (set_attr "length_immediate" "0")]) 1921 1922(define_insn "*movdi_or_rex64" 1923 [(set (match_operand:DI 0 "register_operand" "=r") 1924 (match_operand:DI 1 "const_int_operand" "i")) 1925 (clobber (reg:CC FLAGS_REG))] 1926 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size) 1927 && reload_completed 1928 && operands[1] == constm1_rtx" 1929{ 1930 operands[1] = constm1_rtx; 1931 return "or{q}\t{%1, %0|%0, %1}"; 1932} 1933 [(set_attr "type" "alu1") 1934 (set_attr "mode" "DI") 1935 (set_attr "length_immediate" "1")]) 1936 1937(define_insn "*movdi_2" 1938 [(set (match_operand:DI 0 "nonimmediate_operand" 1939 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x") 1940 (match_operand:DI 1 "general_operand" 1941 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))] 1942 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1943 "@ 1944 # 1945 # 1946 pxor\t%0, %0 1947 movq\t{%1, %0|%0, %1} 1948 movq\t{%1, %0|%0, %1} 1949 pxor\t%0, %0 1950 movq\t{%1, %0|%0, %1} 1951 movdqa\t{%1, %0|%0, %1} 1952 movq\t{%1, %0|%0, %1} 1953 xorps\t%0, %0 1954 movlps\t{%1, %0|%0, %1} 1955 movaps\t{%1, %0|%0, %1} 1956 movlps\t{%1, %0|%0, %1}" 1957 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov") 1958 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")]) 1959 1960(define_split 1961 [(set (match_operand:DI 0 "push_operand" "") 1962 (match_operand:DI 1 "general_operand" ""))] 1963 "!TARGET_64BIT && reload_completed 1964 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))" 1965 [(const_int 0)] 1966 "ix86_split_long_move (operands); DONE;") 1967 1968;; %%% This multiword shite has got to go. 1969(define_split 1970 [(set (match_operand:DI 0 "nonimmediate_operand" "") 1971 (match_operand:DI 1 "general_operand" ""))] 1972 "!TARGET_64BIT && reload_completed 1973 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0])) 1974 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))" 1975 [(const_int 0)] 1976 "ix86_split_long_move (operands); DONE;") 1977 1978(define_insn "*movdi_1_rex64" 1979 [(set (match_operand:DI 0 "nonimmediate_operand" 1980 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y") 1981 (match_operand:DI 1 "general_operand" 1982 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))] 1983 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1984{ 1985 switch (get_attr_type (insn)) 1986 { 1987 case TYPE_SSECVT: 1988 if (which_alternative == 13) 1989 return "movq2dq\t{%1, %0|%0, %1}"; 1990 else 1991 return "movdq2q\t{%1, %0|%0, %1}"; 1992 case TYPE_SSEMOV: 1993 if (get_attr_mode (insn) == MODE_TI) 1994 return "movdqa\t{%1, %0|%0, %1}"; 1995 /* FALLTHRU */ 1996 case TYPE_MMXMOV: 1997 /* Moves from and into integer register is done using movd opcode with 1998 REX prefix. */ 1999 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])) 2000 return "movd\t{%1, %0|%0, %1}"; 2001 return "movq\t{%1, %0|%0, %1}"; 2002 case TYPE_SSELOG1: 2003 case TYPE_MMXADD: 2004 return "pxor\t%0, %0"; 2005 case TYPE_MULTI: 2006 return "#"; 2007 case TYPE_LEA: 2008 return "lea{q}\t{%a1, %0|%0, %a1}"; 2009 default: 2010 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 2011 if (get_attr_mode (insn) == MODE_SI) 2012 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2013 else if (which_alternative == 2) 2014 return "movabs{q}\t{%1, %0|%0, %1}"; 2015 else 2016 return "mov{q}\t{%1, %0|%0, %1}"; 2017 } 2018} 2019 [(set (attr "type") 2020 (cond [(eq_attr "alternative" "5") 2021 (const_string "mmxadd") 2022 (eq_attr "alternative" "6,7,8") 2023 (const_string "mmxmov") 2024 (eq_attr "alternative" "9") 2025 (const_string "sselog1") 2026 (eq_attr "alternative" "10,11,12") 2027 (const_string "ssemov") 2028 (eq_attr "alternative" "13,14") 2029 (const_string "ssecvt") 2030 (eq_attr "alternative" "4") 2031 (const_string "multi") 2032 (match_operand:DI 1 "pic_32bit_operand" "") 2033 (const_string "lea") 2034 ] 2035 (const_string "imov"))) 2036 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*") 2037 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*") 2038 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")]) 2039 2040;; Stores and loads of ax to arbitrary constant address. 2041;; We fake an second form of instruction to force reload to load address 2042;; into register when rax is not available 2043(define_insn "*movabsdi_1_rex64" 2044 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 2045 (match_operand:DI 1 "nonmemory_operand" "a,er"))] 2046 "TARGET_64BIT && ix86_check_movabs (insn, 0)" 2047 "@ 2048 movabs{q}\t{%1, %P0|%P0, %1} 2049 mov{q}\t{%1, %a0|%a0, %1}" 2050 [(set_attr "type" "imov") 2051 (set_attr "modrm" "0,*") 2052 (set_attr "length_address" "8,0") 2053 (set_attr "length_immediate" "0,*") 2054 (set_attr "memory" "store") 2055 (set_attr "mode" "DI")]) 2056 2057(define_insn "*movabsdi_2_rex64" 2058 [(set (match_operand:DI 0 "register_operand" "=a,r") 2059 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 2060 "TARGET_64BIT && ix86_check_movabs (insn, 1)" 2061 "@ 2062 movabs{q}\t{%P1, %0|%0, %P1} 2063 mov{q}\t{%a1, %0|%0, %a1}" 2064 [(set_attr "type" "imov") 2065 (set_attr "modrm" "0,*") 2066 (set_attr "length_address" "8,0") 2067 (set_attr "length_immediate" "0") 2068 (set_attr "memory" "load") 2069 (set_attr "mode" "DI")]) 2070 2071;; Convert impossible stores of immediate to existing instructions. 2072;; First try to get scratch register and go through it. In case this 2073;; fails, move by 32bit parts. 2074(define_peephole2 2075 [(match_scratch:DI 2 "r") 2076 (set (match_operand:DI 0 "memory_operand" "") 2077 (match_operand:DI 1 "immediate_operand" ""))] 2078 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 2079 && !x86_64_immediate_operand (operands[1], DImode)" 2080 [(set (match_dup 2) (match_dup 1)) 2081 (set (match_dup 0) (match_dup 2))] 2082 "") 2083 2084;; We need to define this as both peepholer and splitter for case 2085;; peephole2 pass is not run. 2086;; "&& 1" is needed to keep it from matching the previous pattern. 2087(define_peephole2 2088 [(set (match_operand:DI 0 "memory_operand" "") 2089 (match_operand:DI 1 "immediate_operand" ""))] 2090 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 2091 && !x86_64_immediate_operand (operands[1], DImode) && 1" 2092 [(set (match_dup 2) (match_dup 3)) 2093 (set (match_dup 4) (match_dup 5))] 2094 "split_di (operands, 2, operands + 2, operands + 4);") 2095 2096(define_split 2097 [(set (match_operand:DI 0 "memory_operand" "") 2098 (match_operand:DI 1 "immediate_operand" ""))] 2099 "TARGET_64BIT && ((optimize > 0 && flag_peephole2) 2100 ? flow2_completed : reload_completed) 2101 && !symbolic_operand (operands[1], DImode) 2102 && !x86_64_immediate_operand (operands[1], DImode)" 2103 [(set (match_dup 2) (match_dup 3)) 2104 (set (match_dup 4) (match_dup 5))] 2105 "split_di (operands, 2, operands + 2, operands + 4);") 2106 2107(define_insn "*swapdi_rex64" 2108 [(set (match_operand:DI 0 "register_operand" "+r") 2109 (match_operand:DI 1 "register_operand" "+r")) 2110 (set (match_dup 1) 2111 (match_dup 0))] 2112 "TARGET_64BIT" 2113 "xchg{q}\t%1, %0" 2114 [(set_attr "type" "imov") 2115 (set_attr "mode" "DI") 2116 (set_attr "pent_pair" "np") 2117 (set_attr "athlon_decode" "vector")]) 2118 2119(define_expand "movti" 2120 [(set (match_operand:TI 0 "nonimmediate_operand" "") 2121 (match_operand:TI 1 "nonimmediate_operand" ""))] 2122 "TARGET_SSE || TARGET_64BIT" 2123{ 2124 if (TARGET_64BIT) 2125 ix86_expand_move (TImode, operands); 2126 else 2127 ix86_expand_vector_move (TImode, operands); 2128 DONE; 2129}) 2130 2131(define_insn "*movti_internal" 2132 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m") 2133 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))] 2134 "TARGET_SSE && !TARGET_64BIT 2135 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 2136{ 2137 switch (which_alternative) 2138 { 2139 case 0: 2140 if (get_attr_mode (insn) == MODE_V4SF) 2141 return "xorps\t%0, %0"; 2142 else 2143 return "pxor\t%0, %0"; 2144 case 1: 2145 case 2: 2146 if (get_attr_mode (insn) == MODE_V4SF) 2147 return "movaps\t{%1, %0|%0, %1}"; 2148 else 2149 return "movdqa\t{%1, %0|%0, %1}"; 2150 default: 2151 gcc_unreachable (); 2152 } 2153} 2154 [(set_attr "type" "sselog1,ssemov,ssemov") 2155 (set (attr "mode") 2156 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 2157 (ne (symbol_ref "optimize_size") (const_int 0))) 2158 (const_string "V4SF") 2159 (and (eq_attr "alternative" "2") 2160 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") 2161 (const_int 0))) 2162 (const_string "V4SF")] 2163 (const_string "TI")))]) 2164 2165(define_insn "*movti_rex64" 2166 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm") 2167 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))] 2168 "TARGET_64BIT 2169 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 2170{ 2171 switch (which_alternative) 2172 { 2173 case 0: 2174 case 1: 2175 return "#"; 2176 case 2: 2177 if (get_attr_mode (insn) == MODE_V4SF) 2178 return "xorps\t%0, %0"; 2179 else 2180 return "pxor\t%0, %0"; 2181 case 3: 2182 case 4: 2183 if (get_attr_mode (insn) == MODE_V4SF) 2184 return "movaps\t{%1, %0|%0, %1}"; 2185 else 2186 return "movdqa\t{%1, %0|%0, %1}"; 2187 default: 2188 gcc_unreachable (); 2189 } 2190} 2191 [(set_attr "type" "*,*,sselog1,ssemov,ssemov") 2192 (set (attr "mode") 2193 (cond [(eq_attr "alternative" "2,3") 2194 (if_then_else 2195 (ne (symbol_ref "optimize_size") 2196 (const_int 0)) 2197 (const_string "V4SF") 2198 (const_string "TI")) 2199 (eq_attr "alternative" "4") 2200 (if_then_else 2201 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") 2202 (const_int 0)) 2203 (ne (symbol_ref "optimize_size") 2204 (const_int 0))) 2205 (const_string "V4SF") 2206 (const_string "TI"))] 2207 (const_string "DI")))]) 2208 2209(define_split 2210 [(set (match_operand:TI 0 "nonimmediate_operand" "") 2211 (match_operand:TI 1 "general_operand" ""))] 2212 "reload_completed && !SSE_REG_P (operands[0]) 2213 && !SSE_REG_P (operands[1])" 2214 [(const_int 0)] 2215 "ix86_split_long_move (operands); DONE;") 2216 2217(define_expand "movsf" 2218 [(set (match_operand:SF 0 "nonimmediate_operand" "") 2219 (match_operand:SF 1 "general_operand" ""))] 2220 "" 2221 "ix86_expand_move (SFmode, operands); DONE;") 2222 2223(define_insn "*pushsf" 2224 [(set (match_operand:SF 0 "push_operand" "=<,<,<") 2225 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))] 2226 "!TARGET_64BIT" 2227{ 2228 /* Anything else should be already split before reg-stack. */ 2229 gcc_assert (which_alternative == 1); 2230 return "push{l}\t%1"; 2231} 2232 [(set_attr "type" "multi,push,multi") 2233 (set_attr "unit" "i387,*,*") 2234 (set_attr "mode" "SF,SI,SF")]) 2235 2236(define_insn "*pushsf_rex64" 2237 [(set (match_operand:SF 0 "push_operand" "=X,X,X") 2238 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))] 2239 "TARGET_64BIT" 2240{ 2241 /* Anything else should be already split before reg-stack. */ 2242 gcc_assert (which_alternative == 1); 2243 return "push{q}\t%q1"; 2244} 2245 [(set_attr "type" "multi,push,multi") 2246 (set_attr "unit" "i387,*,*") 2247 (set_attr "mode" "SF,DI,SF")]) 2248 2249(define_split 2250 [(set (match_operand:SF 0 "push_operand" "") 2251 (match_operand:SF 1 "memory_operand" ""))] 2252 "reload_completed 2253 && GET_CODE (operands[1]) == MEM 2254 && constant_pool_reference_p (operands[1])" 2255 [(set (match_dup 0) 2256 (match_dup 1))] 2257 "operands[1] = avoid_constant_pool_reference (operands[1]);") 2258 2259 2260;; %%% Kill this when call knows how to work this out. 2261(define_split 2262 [(set (match_operand:SF 0 "push_operand" "") 2263 (match_operand:SF 1 "any_fp_register_operand" ""))] 2264 "!TARGET_64BIT" 2265 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) 2266 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))]) 2267 2268(define_split 2269 [(set (match_operand:SF 0 "push_operand" "") 2270 (match_operand:SF 1 "any_fp_register_operand" ""))] 2271 "TARGET_64BIT" 2272 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 2273 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))]) 2274 2275(define_insn "*movsf_1" 2276 [(set (match_operand:SF 0 "nonimmediate_operand" 2277 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y") 2278 (match_operand:SF 1 "general_operand" 2279 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))] 2280 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 2281 && (reload_in_progress || reload_completed 2282 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2283 || GET_CODE (operands[1]) != CONST_DOUBLE 2284 || memory_operand (operands[0], SFmode))" 2285{ 2286 switch (which_alternative) 2287 { 2288 case 0: 2289 return output_387_reg_move (insn, operands); 2290 2291 case 1: 2292 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2293 return "fstp%z0\t%y0"; 2294 else 2295 return "fst%z0\t%y0"; 2296 2297 case 2: 2298 return standard_80387_constant_opcode (operands[1]); 2299 2300 case 3: 2301 case 4: 2302 return "mov{l}\t{%1, %0|%0, %1}"; 2303 case 5: 2304 if (get_attr_mode (insn) == MODE_TI) 2305 return "pxor\t%0, %0"; 2306 else 2307 return "xorps\t%0, %0"; 2308 case 6: 2309 if (get_attr_mode (insn) == MODE_V4SF) 2310 return "movaps\t{%1, %0|%0, %1}"; 2311 else 2312 return "movss\t{%1, %0|%0, %1}"; 2313 case 7: 2314 case 8: 2315 return "movss\t{%1, %0|%0, %1}"; 2316 2317 case 9: 2318 case 10: 2319 return "movd\t{%1, %0|%0, %1}"; 2320 2321 case 11: 2322 return "movq\t{%1, %0|%0, %1}"; 2323 2324 default: 2325 gcc_unreachable (); 2326 } 2327} 2328 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov") 2329 (set (attr "mode") 2330 (cond [(eq_attr "alternative" "3,4,9,10") 2331 (const_string "SI") 2332 (eq_attr "alternative" "5") 2333 (if_then_else 2334 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") 2335 (const_int 0)) 2336 (ne (symbol_ref "TARGET_SSE2") 2337 (const_int 0))) 2338 (eq (symbol_ref "optimize_size") 2339 (const_int 0))) 2340 (const_string "TI") 2341 (const_string "V4SF")) 2342 /* For architectures resolving dependencies on 2343 whole SSE registers use APS move to break dependency 2344 chains, otherwise use short move to avoid extra work. 2345 2346 Do the same for architectures resolving dependencies on 2347 the parts. While in DF mode it is better to always handle 2348 just register parts, the SF mode is different due to lack 2349 of instructions to load just part of the register. It is 2350 better to maintain the whole registers in single format 2351 to avoid problems on using packed logical operations. */ 2352 (eq_attr "alternative" "6") 2353 (if_then_else 2354 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 2355 (const_int 0)) 2356 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") 2357 (const_int 0))) 2358 (const_string "V4SF") 2359 (const_string "SF")) 2360 (eq_attr "alternative" "11") 2361 (const_string "DI")] 2362 (const_string "SF")))]) 2363 2364(define_insn "*swapsf" 2365 [(set (match_operand:SF 0 "fp_register_operand" "+f") 2366 (match_operand:SF 1 "fp_register_operand" "+f")) 2367 (set (match_dup 1) 2368 (match_dup 0))] 2369 "reload_completed || TARGET_80387" 2370{ 2371 if (STACK_TOP_P (operands[0])) 2372 return "fxch\t%1"; 2373 else 2374 return "fxch\t%0"; 2375} 2376 [(set_attr "type" "fxch") 2377 (set_attr "mode" "SF")]) 2378 2379(define_expand "movdf" 2380 [(set (match_operand:DF 0 "nonimmediate_operand" "") 2381 (match_operand:DF 1 "general_operand" ""))] 2382 "" 2383 "ix86_expand_move (DFmode, operands); DONE;") 2384 2385;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. 2386;; Size of pushdf using integer instructions is 2+2*memory operand size 2387;; On the average, pushdf using integers can be still shorter. Allow this 2388;; pattern for optimize_size too. 2389 2390(define_insn "*pushdf_nointeger" 2391 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<") 2392 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))] 2393 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES" 2394{ 2395 /* This insn should be already split before reg-stack. */ 2396 gcc_unreachable (); 2397} 2398 [(set_attr "type" "multi") 2399 (set_attr "unit" "i387,*,*,*") 2400 (set_attr "mode" "DF,SI,SI,DF")]) 2401 2402(define_insn "*pushdf_integer" 2403 [(set (match_operand:DF 0 "push_operand" "=<,<,<") 2404 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))] 2405 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES" 2406{ 2407 /* This insn should be already split before reg-stack. */ 2408 gcc_unreachable (); 2409} 2410 [(set_attr "type" "multi") 2411 (set_attr "unit" "i387,*,*") 2412 (set_attr "mode" "DF,SI,DF")]) 2413 2414;; %%% Kill this when call knows how to work this out. 2415(define_split 2416 [(set (match_operand:DF 0 "push_operand" "") 2417 (match_operand:DF 1 "any_fp_register_operand" ""))] 2418 "!TARGET_64BIT && reload_completed" 2419 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 2420 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))] 2421 "") 2422 2423(define_split 2424 [(set (match_operand:DF 0 "push_operand" "") 2425 (match_operand:DF 1 "any_fp_register_operand" ""))] 2426 "TARGET_64BIT && reload_completed" 2427 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 2428 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))] 2429 "") 2430 2431(define_split 2432 [(set (match_operand:DF 0 "push_operand" "") 2433 (match_operand:DF 1 "general_operand" ""))] 2434 "reload_completed" 2435 [(const_int 0)] 2436 "ix86_split_long_move (operands); DONE;") 2437 2438;; Moving is usually shorter when only FP registers are used. This separate 2439;; movdf pattern avoids the use of integer registers for FP operations 2440;; when optimizing for size. 2441 2442(define_insn "*movdf_nointeger" 2443 [(set (match_operand:DF 0 "nonimmediate_operand" 2444 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ") 2445 (match_operand:DF 1 "general_operand" 2446 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))] 2447 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2448 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT) 2449 && (reload_in_progress || reload_completed 2450 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2451 || GET_CODE (operands[1]) != CONST_DOUBLE 2452 || memory_operand (operands[0], DFmode))" 2453{ 2454 switch (which_alternative) 2455 { 2456 case 0: 2457 return output_387_reg_move (insn, operands); 2458 2459 case 1: 2460 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2461 return "fstp%z0\t%y0"; 2462 else 2463 return "fst%z0\t%y0"; 2464 2465 case 2: 2466 return standard_80387_constant_opcode (operands[1]); 2467 2468 case 3: 2469 case 4: 2470 return "#"; 2471 case 5: 2472 switch (get_attr_mode (insn)) 2473 { 2474 case MODE_V4SF: 2475 return "xorps\t%0, %0"; 2476 case MODE_V2DF: 2477 return "xorpd\t%0, %0"; 2478 case MODE_TI: 2479 return "pxor\t%0, %0"; 2480 default: 2481 gcc_unreachable (); 2482 } 2483 case 6: 2484 case 7: 2485 case 8: 2486 switch (get_attr_mode (insn)) 2487 { 2488 case MODE_V4SF: 2489 return "movaps\t{%1, %0|%0, %1}"; 2490 case MODE_V2DF: 2491 return "movapd\t{%1, %0|%0, %1}"; 2492 case MODE_TI: 2493 return "movdqa\t{%1, %0|%0, %1}"; 2494 case MODE_DI: 2495 return "movq\t{%1, %0|%0, %1}"; 2496 case MODE_DF: 2497 return "movsd\t{%1, %0|%0, %1}"; 2498 case MODE_V1DF: 2499 return "movlpd\t{%1, %0|%0, %1}"; 2500 case MODE_V2SF: 2501 return "movlps\t{%1, %0|%0, %1}"; 2502 default: 2503 gcc_unreachable (); 2504 } 2505 2506 default: 2507 gcc_unreachable (); 2508 } 2509} 2510 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov") 2511 (set (attr "mode") 2512 (cond [(eq_attr "alternative" "0,1,2") 2513 (const_string "DF") 2514 (eq_attr "alternative" "3,4") 2515 (const_string "SI") 2516 2517 /* For SSE1, we have many fewer alternatives. */ 2518 (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 2519 (cond [(eq_attr "alternative" "5,6") 2520 (const_string "V4SF") 2521 ] 2522 (const_string "V2SF")) 2523 2524 /* xorps is one byte shorter. */ 2525 (eq_attr "alternative" "5") 2526 (cond [(ne (symbol_ref "optimize_size") 2527 (const_int 0)) 2528 (const_string "V4SF") 2529 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") 2530 (const_int 0)) 2531 (const_string "TI") 2532 ] 2533 (const_string "V2DF")) 2534 2535 /* For architectures resolving dependencies on 2536 whole SSE registers use APD move to break dependency 2537 chains, otherwise use short move to avoid extra work. 2538 2539 movaps encodes one byte shorter. */ 2540 (eq_attr "alternative" "6") 2541 (cond 2542 [(ne (symbol_ref "optimize_size") 2543 (const_int 0)) 2544 (const_string "V4SF") 2545 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 2546 (const_int 0)) 2547 (const_string "V2DF") 2548 ] 2549 (const_string "DF")) 2550 /* For architectures resolving dependencies on register 2551 parts we may avoid extra work to zero out upper part 2552 of register. */ 2553 (eq_attr "alternative" "7") 2554 (if_then_else 2555 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") 2556 (const_int 0)) 2557 (const_string "V1DF") 2558 (const_string "DF")) 2559 ] 2560 (const_string "DF")))]) 2561 2562(define_insn "*movdf_integer" 2563 [(set (match_operand:DF 0 "nonimmediate_operand" 2564 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ") 2565 (match_operand:DF 1 "general_operand" 2566 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))] 2567 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2568 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT) 2569 && (reload_in_progress || reload_completed 2570 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2571 || GET_CODE (operands[1]) != CONST_DOUBLE 2572 || memory_operand (operands[0], DFmode))" 2573{ 2574 switch (which_alternative) 2575 { 2576 case 0: 2577 return output_387_reg_move (insn, operands); 2578 2579 case 1: 2580 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2581 return "fstp%z0\t%y0"; 2582 else 2583 return "fst%z0\t%y0"; 2584 2585 case 2: 2586 return standard_80387_constant_opcode (operands[1]); 2587 2588 case 3: 2589 case 4: 2590 return "#"; 2591 2592 case 5: 2593 switch (get_attr_mode (insn)) 2594 { 2595 case MODE_V4SF: 2596 return "xorps\t%0, %0"; 2597 case MODE_V2DF: 2598 return "xorpd\t%0, %0"; 2599 case MODE_TI: 2600 return "pxor\t%0, %0"; 2601 default: 2602 gcc_unreachable (); 2603 } 2604 case 6: 2605 case 7: 2606 case 8: 2607 switch (get_attr_mode (insn)) 2608 { 2609 case MODE_V4SF: 2610 return "movaps\t{%1, %0|%0, %1}"; 2611 case MODE_V2DF: 2612 return "movapd\t{%1, %0|%0, %1}"; 2613 case MODE_TI: 2614 return "movdqa\t{%1, %0|%0, %1}"; 2615 case MODE_DI: 2616 return "movq\t{%1, %0|%0, %1}"; 2617 case MODE_DF: 2618 return "movsd\t{%1, %0|%0, %1}"; 2619 case MODE_V1DF: 2620 return "movlpd\t{%1, %0|%0, %1}"; 2621 case MODE_V2SF: 2622 return "movlps\t{%1, %0|%0, %1}"; 2623 default: 2624 gcc_unreachable (); 2625 } 2626 2627 default: 2628 gcc_unreachable(); 2629 } 2630} 2631 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov") 2632 (set (attr "mode") 2633 (cond [(eq_attr "alternative" "0,1,2") 2634 (const_string "DF") 2635 (eq_attr "alternative" "3,4") 2636 (const_string "SI") 2637 2638 /* For SSE1, we have many fewer alternatives. */ 2639 (eq (symbol_ref "TARGET_SSE2") (const_int 0)) 2640 (cond [(eq_attr "alternative" "5,6") 2641 (const_string "V4SF") 2642 ] 2643 (const_string "V2SF")) 2644 2645 /* xorps is one byte shorter. */ 2646 (eq_attr "alternative" "5") 2647 (cond [(ne (symbol_ref "optimize_size") 2648 (const_int 0)) 2649 (const_string "V4SF") 2650 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR") 2651 (const_int 0)) 2652 (const_string "TI") 2653 ] 2654 (const_string "V2DF")) 2655 2656 /* For architectures resolving dependencies on 2657 whole SSE registers use APD move to break dependency 2658 chains, otherwise use short move to avoid extra work. 2659 2660 movaps encodes one byte shorter. */ 2661 (eq_attr "alternative" "6") 2662 (cond 2663 [(ne (symbol_ref "optimize_size") 2664 (const_int 0)) 2665 (const_string "V4SF") 2666 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 2667 (const_int 0)) 2668 (const_string "V2DF") 2669 ] 2670 (const_string "DF")) 2671 /* For architectures resolving dependencies on register 2672 parts we may avoid extra work to zero out upper part 2673 of register. */ 2674 (eq_attr "alternative" "7") 2675 (if_then_else 2676 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS") 2677 (const_int 0)) 2678 (const_string "V1DF") 2679 (const_string "DF")) 2680 ] 2681 (const_string "DF")))]) 2682 2683(define_split 2684 [(set (match_operand:DF 0 "nonimmediate_operand" "") 2685 (match_operand:DF 1 "general_operand" ""))] 2686 "reload_completed 2687 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2688 && ! (ANY_FP_REG_P (operands[0]) || 2689 (GET_CODE (operands[0]) == SUBREG 2690 && ANY_FP_REG_P (SUBREG_REG (operands[0])))) 2691 && ! (ANY_FP_REG_P (operands[1]) || 2692 (GET_CODE (operands[1]) == SUBREG 2693 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))" 2694 [(const_int 0)] 2695 "ix86_split_long_move (operands); DONE;") 2696 2697(define_insn "*swapdf" 2698 [(set (match_operand:DF 0 "fp_register_operand" "+f") 2699 (match_operand:DF 1 "fp_register_operand" "+f")) 2700 (set (match_dup 1) 2701 (match_dup 0))] 2702 "reload_completed || TARGET_80387" 2703{ 2704 if (STACK_TOP_P (operands[0])) 2705 return "fxch\t%1"; 2706 else 2707 return "fxch\t%0"; 2708} 2709 [(set_attr "type" "fxch") 2710 (set_attr "mode" "DF")]) 2711 2712(define_expand "movxf" 2713 [(set (match_operand:XF 0 "nonimmediate_operand" "") 2714 (match_operand:XF 1 "general_operand" ""))] 2715 "" 2716 "ix86_expand_move (XFmode, operands); DONE;") 2717 2718;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size. 2719;; Size of pushdf using integer instructions is 3+3*memory operand size 2720;; Pushing using integer instructions is longer except for constants 2721;; and direct memory references. 2722;; (assuming that any given constant is pushed only once, but this ought to be 2723;; handled elsewhere). 2724 2725(define_insn "*pushxf_nointeger" 2726 [(set (match_operand:XF 0 "push_operand" "=X,X,X") 2727 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))] 2728 "optimize_size" 2729{ 2730 /* This insn should be already split before reg-stack. */ 2731 gcc_unreachable (); 2732} 2733 [(set_attr "type" "multi") 2734 (set_attr "unit" "i387,*,*") 2735 (set_attr "mode" "XF,SI,SI")]) 2736 2737(define_insn "*pushxf_integer" 2738 [(set (match_operand:XF 0 "push_operand" "=<,<") 2739 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))] 2740 "!optimize_size" 2741{ 2742 /* This insn should be already split before reg-stack. */ 2743 gcc_unreachable (); 2744} 2745 [(set_attr "type" "multi") 2746 (set_attr "unit" "i387,*") 2747 (set_attr "mode" "XF,SI")]) 2748 2749(define_split 2750 [(set (match_operand 0 "push_operand" "") 2751 (match_operand 1 "general_operand" ""))] 2752 "reload_completed 2753 && (GET_MODE (operands[0]) == XFmode 2754 || GET_MODE (operands[0]) == DFmode) 2755 && !ANY_FP_REG_P (operands[1])" 2756 [(const_int 0)] 2757 "ix86_split_long_move (operands); DONE;") 2758 2759(define_split 2760 [(set (match_operand:XF 0 "push_operand" "") 2761 (match_operand:XF 1 "any_fp_register_operand" ""))] 2762 "!TARGET_64BIT" 2763 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2))) 2764 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))] 2765 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 2766 2767(define_split 2768 [(set (match_operand:XF 0 "push_operand" "") 2769 (match_operand:XF 1 "any_fp_register_operand" ""))] 2770 "TARGET_64BIT" 2771 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2))) 2772 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))] 2773 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 2774 2775;; Do not use integer registers when optimizing for size 2776(define_insn "*movxf_nointeger" 2777 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o") 2778 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))] 2779 "optimize_size 2780 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2781 && (reload_in_progress || reload_completed 2782 || GET_CODE (operands[1]) != CONST_DOUBLE 2783 || memory_operand (operands[0], XFmode))" 2784{ 2785 switch (which_alternative) 2786 { 2787 case 0: 2788 return output_387_reg_move (insn, operands); 2789 2790 case 1: 2791 /* There is no non-popping store to memory for XFmode. So if 2792 we need one, follow the store with a load. */ 2793 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2794 return "fstp%z0\t%y0\;fld%z0\t%y0"; 2795 else 2796 return "fstp%z0\t%y0"; 2797 2798 case 2: 2799 return standard_80387_constant_opcode (operands[1]); 2800 2801 case 3: case 4: 2802 return "#"; 2803 default: 2804 gcc_unreachable (); 2805 } 2806} 2807 [(set_attr "type" "fmov,fmov,fmov,multi,multi") 2808 (set_attr "mode" "XF,XF,XF,SI,SI")]) 2809 2810(define_insn "*movxf_integer" 2811 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o") 2812 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))] 2813 "!optimize_size 2814 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2815 && (reload_in_progress || reload_completed 2816 || GET_CODE (operands[1]) != CONST_DOUBLE 2817 || memory_operand (operands[0], XFmode))" 2818{ 2819 switch (which_alternative) 2820 { 2821 case 0: 2822 return output_387_reg_move (insn, operands); 2823 2824 case 1: 2825 /* There is no non-popping store to memory for XFmode. So if 2826 we need one, follow the store with a load. */ 2827 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 2828 return "fstp%z0\t%y0\;fld%z0\t%y0"; 2829 else 2830 return "fstp%z0\t%y0"; 2831 2832 case 2: 2833 return standard_80387_constant_opcode (operands[1]); 2834 2835 case 3: case 4: 2836 return "#"; 2837 2838 default: 2839 gcc_unreachable (); 2840 } 2841} 2842 [(set_attr "type" "fmov,fmov,fmov,multi,multi") 2843 (set_attr "mode" "XF,XF,XF,SI,SI")]) 2844 2845(define_split 2846 [(set (match_operand 0 "nonimmediate_operand" "") 2847 (match_operand 1 "general_operand" ""))] 2848 "reload_completed 2849 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 2850 && GET_MODE (operands[0]) == XFmode 2851 && ! (ANY_FP_REG_P (operands[0]) || 2852 (GET_CODE (operands[0]) == SUBREG 2853 && ANY_FP_REG_P (SUBREG_REG (operands[0])))) 2854 && ! (ANY_FP_REG_P (operands[1]) || 2855 (GET_CODE (operands[1]) == SUBREG 2856 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))" 2857 [(const_int 0)] 2858 "ix86_split_long_move (operands); DONE;") 2859 2860(define_split 2861 [(set (match_operand 0 "register_operand" "") 2862 (match_operand 1 "memory_operand" ""))] 2863 "reload_completed 2864 && GET_CODE (operands[1]) == MEM 2865 && (GET_MODE (operands[0]) == XFmode 2866 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode) 2867 && constant_pool_reference_p (operands[1])" 2868 [(set (match_dup 0) (match_dup 1))] 2869{ 2870 rtx c = avoid_constant_pool_reference (operands[1]); 2871 rtx r = operands[0]; 2872 2873 if (GET_CODE (r) == SUBREG) 2874 r = SUBREG_REG (r); 2875 2876 if (SSE_REG_P (r)) 2877 { 2878 if (!standard_sse_constant_p (c)) 2879 FAIL; 2880 } 2881 else if (FP_REG_P (r)) 2882 { 2883 if (!standard_80387_constant_p (c)) 2884 FAIL; 2885 } 2886 else if (MMX_REG_P (r)) 2887 FAIL; 2888 2889 operands[1] = c; 2890}) 2891 2892(define_insn "swapxf" 2893 [(set (match_operand:XF 0 "register_operand" "+f") 2894 (match_operand:XF 1 "register_operand" "+f")) 2895 (set (match_dup 1) 2896 (match_dup 0))] 2897 "TARGET_80387" 2898{ 2899 if (STACK_TOP_P (operands[0])) 2900 return "fxch\t%1"; 2901 else 2902 return "fxch\t%0"; 2903} 2904 [(set_attr "type" "fxch") 2905 (set_attr "mode" "XF")]) 2906 2907(define_expand "movtf" 2908 [(set (match_operand:TF 0 "nonimmediate_operand" "") 2909 (match_operand:TF 1 "nonimmediate_operand" ""))] 2910 "TARGET_64BIT" 2911{ 2912 ix86_expand_move (TFmode, operands); 2913 DONE; 2914}) 2915 2916(define_insn "*movtf_internal" 2917 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm") 2918 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))] 2919 "TARGET_64BIT 2920 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 2921{ 2922 switch (which_alternative) 2923 { 2924 case 0: 2925 case 1: 2926 return "#"; 2927 case 2: 2928 if (get_attr_mode (insn) == MODE_V4SF) 2929 return "xorps\t%0, %0"; 2930 else 2931 return "pxor\t%0, %0"; 2932 case 3: 2933 case 4: 2934 if (get_attr_mode (insn) == MODE_V4SF) 2935 return "movaps\t{%1, %0|%0, %1}"; 2936 else 2937 return "movdqa\t{%1, %0|%0, %1}"; 2938 default: 2939 gcc_unreachable (); 2940 } 2941} 2942 [(set_attr "type" "*,*,sselog1,ssemov,ssemov") 2943 (set (attr "mode") 2944 (cond [(eq_attr "alternative" "2,3") 2945 (if_then_else 2946 (ne (symbol_ref "optimize_size") 2947 (const_int 0)) 2948 (const_string "V4SF") 2949 (const_string "TI")) 2950 (eq_attr "alternative" "4") 2951 (if_then_else 2952 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES") 2953 (const_int 0)) 2954 (ne (symbol_ref "optimize_size") 2955 (const_int 0))) 2956 (const_string "V4SF") 2957 (const_string "TI"))] 2958 (const_string "DI")))]) 2959 2960(define_split 2961 [(set (match_operand:TF 0 "nonimmediate_operand" "") 2962 (match_operand:TF 1 "general_operand" ""))] 2963 "reload_completed && !SSE_REG_P (operands[0]) 2964 && !SSE_REG_P (operands[1])" 2965 [(const_int 0)] 2966 "ix86_split_long_move (operands); DONE;") 2967 2968;; Zero extension instructions 2969 2970(define_expand "zero_extendhisi2" 2971 [(set (match_operand:SI 0 "register_operand" "") 2972 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 2973 "" 2974{ 2975 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) 2976 { 2977 operands[1] = force_reg (HImode, operands[1]); 2978 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1])); 2979 DONE; 2980 } 2981}) 2982 2983(define_insn "zero_extendhisi2_and" 2984 [(set (match_operand:SI 0 "register_operand" "=r") 2985 (zero_extend:SI (match_operand:HI 1 "register_operand" "0"))) 2986 (clobber (reg:CC FLAGS_REG))] 2987 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 2988 "#" 2989 [(set_attr "type" "alu1") 2990 (set_attr "mode" "SI")]) 2991 2992(define_split 2993 [(set (match_operand:SI 0 "register_operand" "") 2994 (zero_extend:SI (match_operand:HI 1 "register_operand" ""))) 2995 (clobber (reg:CC FLAGS_REG))] 2996 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 2997 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535))) 2998 (clobber (reg:CC FLAGS_REG))])] 2999 "") 3000 3001(define_insn "*zero_extendhisi2_movzwl" 3002 [(set (match_operand:SI 0 "register_operand" "=r") 3003 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3004 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" 3005 "movz{wl|x}\t{%1, %0|%0, %1}" 3006 [(set_attr "type" "imovx") 3007 (set_attr "mode" "SI")]) 3008 3009(define_expand "zero_extendqihi2" 3010 [(parallel 3011 [(set (match_operand:HI 0 "register_operand" "") 3012 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) 3013 (clobber (reg:CC FLAGS_REG))])] 3014 "" 3015 "") 3016 3017(define_insn "*zero_extendqihi2_and" 3018 [(set (match_operand:HI 0 "register_operand" "=r,?&q") 3019 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) 3020 (clobber (reg:CC FLAGS_REG))] 3021 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 3022 "#" 3023 [(set_attr "type" "alu1") 3024 (set_attr "mode" "HI")]) 3025 3026(define_insn "*zero_extendqihi2_movzbw_and" 3027 [(set (match_operand:HI 0 "register_operand" "=r,r") 3028 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) 3029 (clobber (reg:CC FLAGS_REG))] 3030 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" 3031 "#" 3032 [(set_attr "type" "imovx,alu1") 3033 (set_attr "mode" "HI")]) 3034 3035; zero extend to SImode here to avoid partial register stalls 3036(define_insn "*zero_extendqihi2_movzbl" 3037 [(set (match_operand:HI 0 "register_operand" "=r") 3038 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3039 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed" 3040 "movz{bl|x}\t{%1, %k0|%k0, %k1}" 3041 [(set_attr "type" "imovx") 3042 (set_attr "mode" "SI")]) 3043 3044;; For the movzbw case strip only the clobber 3045(define_split 3046 [(set (match_operand:HI 0 "register_operand" "") 3047 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) 3048 (clobber (reg:CC FLAGS_REG))] 3049 "reload_completed 3050 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) 3051 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" 3052 [(set (match_operand:HI 0 "register_operand" "") 3053 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]) 3054 3055;; When source and destination does not overlap, clear destination 3056;; first and then do the movb 3057(define_split 3058 [(set (match_operand:HI 0 "register_operand" "") 3059 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))) 3060 (clobber (reg:CC FLAGS_REG))] 3061 "reload_completed 3062 && ANY_QI_REG_P (operands[0]) 3063 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) 3064 && !reg_overlap_mentioned_p (operands[0], operands[1])" 3065 [(set (match_dup 0) (const_int 0)) 3066 (set (strict_low_part (match_dup 2)) (match_dup 1))] 3067 "operands[2] = gen_lowpart (QImode, operands[0]);") 3068 3069;; Rest is handled by single and. 3070(define_split 3071 [(set (match_operand:HI 0 "register_operand" "") 3072 (zero_extend:HI (match_operand:QI 1 "register_operand" ""))) 3073 (clobber (reg:CC FLAGS_REG))] 3074 "reload_completed 3075 && true_regnum (operands[0]) == true_regnum (operands[1])" 3076 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255))) 3077 (clobber (reg:CC FLAGS_REG))])] 3078 "") 3079 3080(define_expand "zero_extendqisi2" 3081 [(parallel 3082 [(set (match_operand:SI 0 "register_operand" "") 3083 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) 3084 (clobber (reg:CC FLAGS_REG))])] 3085 "" 3086 "") 3087 3088(define_insn "*zero_extendqisi2_and" 3089 [(set (match_operand:SI 0 "register_operand" "=r,?&q") 3090 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) 3091 (clobber (reg:CC FLAGS_REG))] 3092 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size" 3093 "#" 3094 [(set_attr "type" "alu1") 3095 (set_attr "mode" "SI")]) 3096 3097(define_insn "*zero_extendqisi2_movzbw_and" 3098 [(set (match_operand:SI 0 "register_operand" "=r,r") 3099 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0"))) 3100 (clobber (reg:CC FLAGS_REG))] 3101 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size" 3102 "#" 3103 [(set_attr "type" "imovx,alu1") 3104 (set_attr "mode" "SI")]) 3105 3106(define_insn "*zero_extendqisi2_movzbw" 3107 [(set (match_operand:SI 0 "register_operand" "=r") 3108 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3109 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed" 3110 "movz{bl|x}\t{%1, %0|%0, %1}" 3111 [(set_attr "type" "imovx") 3112 (set_attr "mode" "SI")]) 3113 3114;; For the movzbl case strip only the clobber 3115(define_split 3116 [(set (match_operand:SI 0 "register_operand" "") 3117 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) 3118 (clobber (reg:CC FLAGS_REG))] 3119 "reload_completed 3120 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) 3121 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))" 3122 [(set (match_dup 0) 3123 (zero_extend:SI (match_dup 1)))]) 3124 3125;; When source and destination does not overlap, clear destination 3126;; first and then do the movb 3127(define_split 3128 [(set (match_operand:SI 0 "register_operand" "") 3129 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" ""))) 3130 (clobber (reg:CC FLAGS_REG))] 3131 "reload_completed 3132 && ANY_QI_REG_P (operands[0]) 3133 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM) 3134 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size) 3135 && !reg_overlap_mentioned_p (operands[0], operands[1])" 3136 [(set (match_dup 0) (const_int 0)) 3137 (set (strict_low_part (match_dup 2)) (match_dup 1))] 3138 "operands[2] = gen_lowpart (QImode, operands[0]);") 3139 3140;; Rest is handled by single and. 3141(define_split 3142 [(set (match_operand:SI 0 "register_operand" "") 3143 (zero_extend:SI (match_operand:QI 1 "register_operand" ""))) 3144 (clobber (reg:CC FLAGS_REG))] 3145 "reload_completed 3146 && true_regnum (operands[0]) == true_regnum (operands[1])" 3147 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255))) 3148 (clobber (reg:CC FLAGS_REG))])] 3149 "") 3150 3151;; %%% Kill me once multi-word ops are sane. 3152(define_expand "zero_extendsidi2" 3153 [(set (match_operand:DI 0 "register_operand" "=r") 3154 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))] 3155 "" 3156 "if (!TARGET_64BIT) 3157 { 3158 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1])); 3159 DONE; 3160 } 3161 ") 3162 3163(define_insn "zero_extendsidi2_32" 3164 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y") 3165 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm"))) 3166 (clobber (reg:CC FLAGS_REG))] 3167 "!TARGET_64BIT" 3168 "@ 3169 # 3170 # 3171 # 3172 movd\t{%1, %0|%0, %1} 3173 movd\t{%1, %0|%0, %1}" 3174 [(set_attr "mode" "SI,SI,SI,DI,TI") 3175 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")]) 3176 3177(define_insn "zero_extendsidi2_rex64" 3178 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y") 3179 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))] 3180 "TARGET_64BIT" 3181 "@ 3182 mov\t{%k1, %k0|%k0, %k1} 3183 # 3184 movd\t{%1, %0|%0, %1} 3185 movd\t{%1, %0|%0, %1}" 3186 [(set_attr "type" "imovx,imov,mmxmov,ssemov") 3187 (set_attr "mode" "SI,DI,SI,SI")]) 3188 3189(define_split 3190 [(set (match_operand:DI 0 "memory_operand" "") 3191 (zero_extend:DI (match_dup 0)))] 3192 "TARGET_64BIT" 3193 [(set (match_dup 4) (const_int 0))] 3194 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3195 3196(define_split 3197 [(set (match_operand:DI 0 "register_operand" "") 3198 (zero_extend:DI (match_operand:SI 1 "register_operand" ""))) 3199 (clobber (reg:CC FLAGS_REG))] 3200 "!TARGET_64BIT && reload_completed 3201 && true_regnum (operands[0]) == true_regnum (operands[1])" 3202 [(set (match_dup 4) (const_int 0))] 3203 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3204 3205(define_split 3206 [(set (match_operand:DI 0 "nonimmediate_operand" "") 3207 (zero_extend:DI (match_operand:SI 1 "general_operand" ""))) 3208 (clobber (reg:CC FLAGS_REG))] 3209 "!TARGET_64BIT && reload_completed 3210 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])" 3211 [(set (match_dup 3) (match_dup 1)) 3212 (set (match_dup 4) (const_int 0))] 3213 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3214 3215(define_insn "zero_extendhidi2" 3216 [(set (match_operand:DI 0 "register_operand" "=r") 3217 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3218 "TARGET_64BIT" 3219 "movz{wl|x}\t{%1, %k0|%k0, %1}" 3220 [(set_attr "type" "imovx") 3221 (set_attr "mode" "DI")]) 3222 3223(define_insn "zero_extendqidi2" 3224 [(set (match_operand:DI 0 "register_operand" "=r") 3225 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))] 3226 "TARGET_64BIT" 3227 "movz{bl|x}\t{%1, %k0|%k0, %1}" 3228 [(set_attr "type" "imovx") 3229 (set_attr "mode" "DI")]) 3230 3231;; Sign extension instructions 3232 3233(define_expand "extendsidi2" 3234 [(parallel [(set (match_operand:DI 0 "register_operand" "") 3235 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3236 (clobber (reg:CC FLAGS_REG)) 3237 (clobber (match_scratch:SI 2 ""))])] 3238 "" 3239{ 3240 if (TARGET_64BIT) 3241 { 3242 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1])); 3243 DONE; 3244 } 3245}) 3246 3247(define_insn "*extendsidi2_1" 3248 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o") 3249 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r"))) 3250 (clobber (reg:CC FLAGS_REG)) 3251 (clobber (match_scratch:SI 2 "=X,X,X,&r"))] 3252 "!TARGET_64BIT" 3253 "#") 3254 3255(define_insn "extendsidi2_rex64" 3256 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3257 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))] 3258 "TARGET_64BIT" 3259 "@ 3260 {cltq|cdqe} 3261 movs{lq|x}\t{%1,%0|%0, %1}" 3262 [(set_attr "type" "imovx") 3263 (set_attr "mode" "DI") 3264 (set_attr "prefix_0f" "0") 3265 (set_attr "modrm" "0,1")]) 3266 3267(define_insn "extendhidi2" 3268 [(set (match_operand:DI 0 "register_operand" "=r") 3269 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 3270 "TARGET_64BIT" 3271 "movs{wq|x}\t{%1,%0|%0, %1}" 3272 [(set_attr "type" "imovx") 3273 (set_attr "mode" "DI")]) 3274 3275(define_insn "extendqidi2" 3276 [(set (match_operand:DI 0 "register_operand" "=r") 3277 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3278 "TARGET_64BIT" 3279 "movs{bq|x}\t{%1,%0|%0, %1}" 3280 [(set_attr "type" "imovx") 3281 (set_attr "mode" "DI")]) 3282 3283;; Extend to memory case when source register does die. 3284(define_split 3285 [(set (match_operand:DI 0 "memory_operand" "") 3286 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3287 (clobber (reg:CC FLAGS_REG)) 3288 (clobber (match_operand:SI 2 "register_operand" ""))] 3289 "(reload_completed 3290 && dead_or_set_p (insn, operands[1]) 3291 && !reg_mentioned_p (operands[1], operands[0]))" 3292 [(set (match_dup 3) (match_dup 1)) 3293 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) 3294 (clobber (reg:CC FLAGS_REG))]) 3295 (set (match_dup 4) (match_dup 1))] 3296 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 3297 3298;; Extend to memory case when source register does not die. 3299(define_split 3300 [(set (match_operand:DI 0 "memory_operand" "") 3301 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3302 (clobber (reg:CC FLAGS_REG)) 3303 (clobber (match_operand:SI 2 "register_operand" ""))] 3304 "reload_completed" 3305 [(const_int 0)] 3306{ 3307 split_di (&operands[0], 1, &operands[3], &operands[4]); 3308 3309 emit_move_insn (operands[3], operands[1]); 3310 3311 /* Generate a cltd if possible and doing so it profitable. */ 3312 if (true_regnum (operands[1]) == 0 3313 && true_regnum (operands[2]) == 1 3314 && (optimize_size || TARGET_USE_CLTD)) 3315 { 3316 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31))); 3317 } 3318 else 3319 { 3320 emit_move_insn (operands[2], operands[1]); 3321 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31))); 3322 } 3323 emit_move_insn (operands[4], operands[2]); 3324 DONE; 3325}) 3326 3327;; Extend to register case. Optimize case where source and destination 3328;; registers match and cases where we can use cltd. 3329(define_split 3330 [(set (match_operand:DI 0 "register_operand" "") 3331 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 3332 (clobber (reg:CC FLAGS_REG)) 3333 (clobber (match_scratch:SI 2 ""))] 3334 "reload_completed" 3335 [(const_int 0)] 3336{ 3337 split_di (&operands[0], 1, &operands[3], &operands[4]); 3338 3339 if (true_regnum (operands[3]) != true_regnum (operands[1])) 3340 emit_move_insn (operands[3], operands[1]); 3341 3342 /* Generate a cltd if possible and doing so it profitable. */ 3343 if (true_regnum (operands[3]) == 0 3344 && (optimize_size || TARGET_USE_CLTD)) 3345 { 3346 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31))); 3347 DONE; 3348 } 3349 3350 if (true_regnum (operands[4]) != true_regnum (operands[1])) 3351 emit_move_insn (operands[4], operands[1]); 3352 3353 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31))); 3354 DONE; 3355}) 3356 3357(define_insn "extendhisi2" 3358 [(set (match_operand:SI 0 "register_operand" "=*a,r") 3359 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))] 3360 "" 3361{ 3362 switch (get_attr_prefix_0f (insn)) 3363 { 3364 case 0: 3365 return "{cwtl|cwde}"; 3366 default: 3367 return "movs{wl|x}\t{%1,%0|%0, %1}"; 3368 } 3369} 3370 [(set_attr "type" "imovx") 3371 (set_attr "mode" "SI") 3372 (set (attr "prefix_0f") 3373 ;; movsx is short decodable while cwtl is vector decoded. 3374 (if_then_else (and (eq_attr "cpu" "!k6") 3375 (eq_attr "alternative" "0")) 3376 (const_string "0") 3377 (const_string "1"))) 3378 (set (attr "modrm") 3379 (if_then_else (eq_attr "prefix_0f" "0") 3380 (const_string "0") 3381 (const_string "1")))]) 3382 3383(define_insn "*extendhisi2_zext" 3384 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3385 (zero_extend:DI 3386 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))] 3387 "TARGET_64BIT" 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,%k0|%k0, %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 "extendqihi2" 3411 [(set (match_operand:HI 0 "register_operand" "=*a,r") 3412 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))] 3413 "" 3414{ 3415 switch (get_attr_prefix_0f (insn)) 3416 { 3417 case 0: 3418 return "{cbtw|cbw}"; 3419 default: 3420 return "movs{bw|x}\t{%1,%0|%0, %1}"; 3421 } 3422} 3423 [(set_attr "type" "imovx") 3424 (set_attr "mode" "HI") 3425 (set (attr "prefix_0f") 3426 ;; movsx is short decodable while cwtl is vector decoded. 3427 (if_then_else (and (eq_attr "cpu" "!k6") 3428 (eq_attr "alternative" "0")) 3429 (const_string "0") 3430 (const_string "1"))) 3431 (set (attr "modrm") 3432 (if_then_else (eq_attr "prefix_0f" "0") 3433 (const_string "0") 3434 (const_string "1")))]) 3435 3436(define_insn "extendqisi2" 3437 [(set (match_operand:SI 0 "register_operand" "=r") 3438 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3439 "" 3440 "movs{bl|x}\t{%1,%0|%0, %1}" 3441 [(set_attr "type" "imovx") 3442 (set_attr "mode" "SI")]) 3443 3444(define_insn "*extendqisi2_zext" 3445 [(set (match_operand:DI 0 "register_operand" "=r") 3446 (zero_extend:DI 3447 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))] 3448 "TARGET_64BIT" 3449 "movs{bl|x}\t{%1,%k0|%k0, %1}" 3450 [(set_attr "type" "imovx") 3451 (set_attr "mode" "SI")]) 3452 3453;; Conversions between float and double. 3454 3455;; These are all no-ops in the model used for the 80387. So just 3456;; emit moves. 3457 3458;; %%% Kill these when call knows how to work out a DFmode push earlier. 3459(define_insn "*dummy_extendsfdf2" 3460 [(set (match_operand:DF 0 "push_operand" "=<") 3461 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))] 3462 "0" 3463 "#") 3464 3465(define_split 3466 [(set (match_operand:DF 0 "push_operand" "") 3467 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))] 3468 "!TARGET_64BIT" 3469 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 3470 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))]) 3471 3472(define_split 3473 [(set (match_operand:DF 0 "push_operand" "") 3474 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))] 3475 "TARGET_64BIT" 3476 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 3477 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))]) 3478 3479(define_insn "*dummy_extendsfxf2" 3480 [(set (match_operand:XF 0 "push_operand" "=<") 3481 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))] 3482 "0" 3483 "#") 3484 3485(define_split 3486 [(set (match_operand:XF 0 "push_operand" "") 3487 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))] 3488 "" 3489 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2))) 3490 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))] 3491 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3492 3493(define_split 3494 [(set (match_operand:XF 0 "push_operand" "") 3495 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))] 3496 "TARGET_64BIT" 3497 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2))) 3498 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))] 3499 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3500 3501(define_split 3502 [(set (match_operand:XF 0 "push_operand" "") 3503 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))] 3504 "" 3505 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2))) 3506 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))] 3507 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3508 3509(define_split 3510 [(set (match_operand:XF 0 "push_operand" "") 3511 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))] 3512 "TARGET_64BIT" 3513 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2))) 3514 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))] 3515 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);") 3516 3517(define_expand "extendsfdf2" 3518 [(set (match_operand:DF 0 "nonimmediate_operand" "") 3519 (float_extend:DF (match_operand:SF 1 "general_operand" "")))] 3520 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 3521{ 3522 /* ??? Needed for compress_float_constant since all fp constants 3523 are LEGITIMATE_CONSTANT_P. */ 3524 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3525 { 3526 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387) 3527 && standard_80387_constant_p (operands[1]) > 0) 3528 { 3529 operands[1] = simplify_const_unary_operation 3530 (FLOAT_EXTEND, DFmode, operands[1], SFmode); 3531 emit_move_insn_1 (operands[0], operands[1]); 3532 DONE; 3533 } 3534 operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 3535 } 3536 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 3537 operands[1] = force_reg (SFmode, operands[1]); 3538}) 3539 3540(define_insn "*extendsfdf2_mixed" 3541 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y") 3542 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))] 3543 "TARGET_SSE2 && TARGET_MIX_SSE_I387 3544 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3545{ 3546 switch (which_alternative) 3547 { 3548 case 0: 3549 return output_387_reg_move (insn, operands); 3550 3551 case 1: 3552 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3553 return "fstp%z0\t%y0"; 3554 else 3555 return "fst%z0\t%y0"; 3556 3557 case 2: 3558 return "cvtss2sd\t{%1, %0|%0, %1}"; 3559 3560 default: 3561 gcc_unreachable (); 3562 } 3563} 3564 [(set_attr "type" "fmov,fmov,ssecvt") 3565 (set_attr "mode" "SF,XF,DF")]) 3566 3567(define_insn "*extendsfdf2_sse" 3568 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y") 3569 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))] 3570 "TARGET_SSE2 && TARGET_SSE_MATH 3571 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3572 "cvtss2sd\t{%1, %0|%0, %1}" 3573 [(set_attr "type" "ssecvt") 3574 (set_attr "mode" "DF")]) 3575 3576(define_insn "*extendsfdf2_i387" 3577 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m") 3578 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 3579 "TARGET_80387 3580 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3581{ 3582 switch (which_alternative) 3583 { 3584 case 0: 3585 return output_387_reg_move (insn, operands); 3586 3587 case 1: 3588 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3589 return "fstp%z0\t%y0"; 3590 else 3591 return "fst%z0\t%y0"; 3592 3593 default: 3594 gcc_unreachable (); 3595 } 3596} 3597 [(set_attr "type" "fmov") 3598 (set_attr "mode" "SF,XF")]) 3599 3600(define_expand "extendsfxf2" 3601 [(set (match_operand:XF 0 "nonimmediate_operand" "") 3602 (float_extend:XF (match_operand:SF 1 "general_operand" "")))] 3603 "TARGET_80387" 3604{ 3605 /* ??? Needed for compress_float_constant since all fp constants 3606 are LEGITIMATE_CONSTANT_P. */ 3607 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3608 { 3609 if (standard_80387_constant_p (operands[1]) > 0) 3610 { 3611 operands[1] = simplify_const_unary_operation 3612 (FLOAT_EXTEND, XFmode, operands[1], SFmode); 3613 emit_move_insn_1 (operands[0], operands[1]); 3614 DONE; 3615 } 3616 operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 3617 } 3618 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 3619 operands[1] = force_reg (SFmode, operands[1]); 3620}) 3621 3622(define_insn "*extendsfxf2_i387" 3623 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 3624 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 3625 "TARGET_80387 3626 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3627{ 3628 switch (which_alternative) 3629 { 3630 case 0: 3631 return output_387_reg_move (insn, operands); 3632 3633 case 1: 3634 /* There is no non-popping store to memory for XFmode. So if 3635 we need one, follow the store with a load. */ 3636 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3637 return "fstp%z0\t%y0"; 3638 else 3639 return "fstp%z0\t%y0\n\tfld%z0\t%y0"; 3640 3641 default: 3642 gcc_unreachable (); 3643 } 3644} 3645 [(set_attr "type" "fmov") 3646 (set_attr "mode" "SF,XF")]) 3647 3648(define_expand "extenddfxf2" 3649 [(set (match_operand:XF 0 "nonimmediate_operand" "") 3650 (float_extend:XF (match_operand:DF 1 "general_operand" "")))] 3651 "TARGET_80387" 3652{ 3653 /* ??? Needed for compress_float_constant since all fp constants 3654 are LEGITIMATE_CONSTANT_P. */ 3655 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3656 { 3657 if (standard_80387_constant_p (operands[1]) > 0) 3658 { 3659 operands[1] = simplify_const_unary_operation 3660 (FLOAT_EXTEND, XFmode, operands[1], DFmode); 3661 emit_move_insn_1 (operands[0], operands[1]); 3662 DONE; 3663 } 3664 operands[1] = validize_mem (force_const_mem (DFmode, operands[1])); 3665 } 3666 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 3667 operands[1] = force_reg (DFmode, operands[1]); 3668}) 3669 3670(define_insn "*extenddfxf2_i387" 3671 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 3672 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))] 3673 "TARGET_80387 3674 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 3675{ 3676 switch (which_alternative) 3677 { 3678 case 0: 3679 return output_387_reg_move (insn, operands); 3680 3681 case 1: 3682 /* There is no non-popping store to memory for XFmode. So if 3683 we need one, follow the store with a load. */ 3684 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3685 return "fstp%z0\t%y0\n\tfld%z0\t%y0"; 3686 else 3687 return "fstp%z0\t%y0"; 3688 3689 default: 3690 gcc_unreachable (); 3691 } 3692} 3693 [(set_attr "type" "fmov") 3694 (set_attr "mode" "DF,XF")]) 3695 3696;; %%% This seems bad bad news. 3697;; This cannot output into an f-reg because there is no way to be sure 3698;; of truncating in that case. Otherwise this is just like a simple move 3699;; insn. So we pretend we can output to a reg in order to get better 3700;; register preferencing, but we really use a stack slot. 3701 3702;; Conversion from DFmode to SFmode. 3703 3704(define_expand "truncdfsf2" 3705 [(set (match_operand:SF 0 "nonimmediate_operand" "") 3706 (float_truncate:SF 3707 (match_operand:DF 1 "nonimmediate_operand" "")))] 3708 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 3709{ 3710 if (MEM_P (operands[0]) && MEM_P (operands[1])) 3711 operands[1] = force_reg (DFmode, operands[1]); 3712 3713 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387) 3714 ; 3715 else if (flag_unsafe_math_optimizations) 3716 ; 3717 else 3718 { 3719 rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL); 3720 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp)); 3721 DONE; 3722 } 3723}) 3724 3725(define_expand "truncdfsf2_with_temp" 3726 [(parallel [(set (match_operand:SF 0 "" "") 3727 (float_truncate:SF (match_operand:DF 1 "" ""))) 3728 (clobber (match_operand:SF 2 "" ""))])] 3729 "") 3730 3731(define_insn "*truncdfsf_fast_mixed" 3732 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y") 3733 (float_truncate:SF 3734 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))] 3735 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations" 3736{ 3737 switch (which_alternative) 3738 { 3739 case 0: 3740 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3741 return "fstp%z0\t%y0"; 3742 else 3743 return "fst%z0\t%y0"; 3744 case 1: 3745 return output_387_reg_move (insn, operands); 3746 case 2: 3747 return "cvtsd2ss\t{%1, %0|%0, %1}"; 3748 default: 3749 gcc_unreachable (); 3750 } 3751} 3752 [(set_attr "type" "fmov,fmov,ssecvt") 3753 (set_attr "mode" "SF")]) 3754 3755;; Yes, this one doesn't depend on flag_unsafe_math_optimizations, 3756;; because nothing we do here is unsafe. 3757(define_insn "*truncdfsf_fast_sse" 3758 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y") 3759 (float_truncate:SF 3760 (match_operand:DF 1 "nonimmediate_operand" "Ym")))] 3761 "TARGET_SSE2 && TARGET_SSE_MATH" 3762 "cvtsd2ss\t{%1, %0|%0, %1}" 3763 [(set_attr "type" "ssecvt") 3764 (set_attr "mode" "SF")]) 3765 3766(define_insn "*truncdfsf_fast_i387" 3767 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm") 3768 (float_truncate:SF 3769 (match_operand:DF 1 "nonimmediate_operand" "f")))] 3770 "TARGET_80387 && flag_unsafe_math_optimizations" 3771 "* return output_387_reg_move (insn, operands);" 3772 [(set_attr "type" "fmov") 3773 (set_attr "mode" "SF")]) 3774 3775(define_insn "*truncdfsf_mixed" 3776 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y") 3777 (float_truncate:SF 3778 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym"))) 3779 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))] 3780 "TARGET_MIX_SSE_I387" 3781{ 3782 switch (which_alternative) 3783 { 3784 case 0: 3785 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3786 return "fstp%z0\t%y0"; 3787 else 3788 return "fst%z0\t%y0"; 3789 case 1: 3790 return "#"; 3791 case 2: 3792 return "cvtsd2ss\t{%1, %0|%0, %1}"; 3793 default: 3794 gcc_unreachable (); 3795 } 3796} 3797 [(set_attr "type" "fmov,multi,ssecvt") 3798 (set_attr "unit" "*,i387,*") 3799 (set_attr "mode" "SF")]) 3800 3801(define_insn "*truncdfsf_i387" 3802 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r") 3803 (float_truncate:SF 3804 (match_operand:DF 1 "nonimmediate_operand" "f,f"))) 3805 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))] 3806 "TARGET_80387" 3807{ 3808 switch (which_alternative) 3809 { 3810 case 0: 3811 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3812 return "fstp%z0\t%y0"; 3813 else 3814 return "fst%z0\t%y0"; 3815 case 1: 3816 return "#"; 3817 default: 3818 gcc_unreachable (); 3819 } 3820} 3821 [(set_attr "type" "fmov,multi") 3822 (set_attr "unit" "*,i387") 3823 (set_attr "mode" "SF")]) 3824 3825(define_insn "*truncdfsf2_i387_1" 3826 [(set (match_operand:SF 0 "memory_operand" "=m") 3827 (float_truncate:SF 3828 (match_operand:DF 1 "register_operand" "f")))] 3829 "TARGET_80387 3830 && !(TARGET_SSE2 && TARGET_SSE_MATH) 3831 && !TARGET_MIX_SSE_I387" 3832{ 3833 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3834 return "fstp%z0\t%y0"; 3835 else 3836 return "fst%z0\t%y0"; 3837} 3838 [(set_attr "type" "fmov") 3839 (set_attr "mode" "SF")]) 3840 3841(define_split 3842 [(set (match_operand:SF 0 "register_operand" "") 3843 (float_truncate:SF 3844 (match_operand:DF 1 "fp_register_operand" ""))) 3845 (clobber (match_operand 2 "" ""))] 3846 "reload_completed" 3847 [(set (match_dup 2) (match_dup 1)) 3848 (set (match_dup 0) (match_dup 2))] 3849{ 3850 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1])); 3851}) 3852 3853;; Conversion from XFmode to SFmode. 3854 3855(define_expand "truncxfsf2" 3856 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") 3857 (float_truncate:SF 3858 (match_operand:XF 1 "register_operand" ""))) 3859 (clobber (match_dup 2))])] 3860 "TARGET_80387" 3861{ 3862 if (flag_unsafe_math_optimizations) 3863 { 3864 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode); 3865 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1])); 3866 if (reg != operands[0]) 3867 emit_move_insn (operands[0], reg); 3868 DONE; 3869 } 3870 else 3871 operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL); 3872}) 3873 3874(define_insn "*truncxfsf2_mixed" 3875 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x") 3876 (float_truncate:SF 3877 (match_operand:XF 1 "register_operand" "f,f,f,f"))) 3878 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))] 3879 "TARGET_MIX_SSE_I387" 3880{ 3881 gcc_assert (!which_alternative); 3882 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3883 return "fstp%z0\t%y0"; 3884 else 3885 return "fst%z0\t%y0"; 3886} 3887 [(set_attr "type" "fmov,multi,multi,multi") 3888 (set_attr "unit" "*,i387,i387,i387") 3889 (set_attr "mode" "SF")]) 3890 3891(define_insn "truncxfsf2_i387_noop" 3892 [(set (match_operand:SF 0 "register_operand" "=f") 3893 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))] 3894 "TARGET_80387 && flag_unsafe_math_optimizations" 3895{ 3896 return output_387_reg_move (insn, operands); 3897} 3898 [(set_attr "type" "fmov") 3899 (set_attr "mode" "SF")]) 3900 3901(define_insn "*truncxfsf2_i387" 3902 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r") 3903 (float_truncate:SF 3904 (match_operand:XF 1 "register_operand" "f,f,f"))) 3905 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))] 3906 "TARGET_80387" 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") 3915 (set_attr "unit" "*,i387,i387") 3916 (set_attr "mode" "SF")]) 3917 3918(define_insn "*truncxfsf2_i387_1" 3919 [(set (match_operand:SF 0 "memory_operand" "=m") 3920 (float_truncate:SF 3921 (match_operand:XF 1 "register_operand" "f")))] 3922 "TARGET_80387" 3923{ 3924 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3925 return "fstp%z0\t%y0"; 3926 else 3927 return "fst%z0\t%y0"; 3928} 3929 [(set_attr "type" "fmov") 3930 (set_attr "mode" "SF")]) 3931 3932(define_split 3933 [(set (match_operand:SF 0 "register_operand" "") 3934 (float_truncate:SF 3935 (match_operand:XF 1 "register_operand" ""))) 3936 (clobber (match_operand:SF 2 "memory_operand" ""))] 3937 "TARGET_80387 && reload_completed" 3938 [(set (match_dup 2) (float_truncate:SF (match_dup 1))) 3939 (set (match_dup 0) (match_dup 2))] 3940 "") 3941 3942(define_split 3943 [(set (match_operand:SF 0 "memory_operand" "") 3944 (float_truncate:SF 3945 (match_operand:XF 1 "register_operand" ""))) 3946 (clobber (match_operand:SF 2 "memory_operand" ""))] 3947 "TARGET_80387" 3948 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))] 3949 "") 3950 3951;; Conversion from XFmode to DFmode. 3952 3953(define_expand "truncxfdf2" 3954 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "") 3955 (float_truncate:DF 3956 (match_operand:XF 1 "register_operand" ""))) 3957 (clobber (match_dup 2))])] 3958 "TARGET_80387" 3959{ 3960 if (flag_unsafe_math_optimizations) 3961 { 3962 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode); 3963 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1])); 3964 if (reg != operands[0]) 3965 emit_move_insn (operands[0], reg); 3966 DONE; 3967 } 3968 else 3969 operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL); 3970}) 3971 3972(define_insn "*truncxfdf2_mixed" 3973 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y") 3974 (float_truncate:DF 3975 (match_operand:XF 1 "register_operand" "f,f,f,f"))) 3976 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))] 3977 "TARGET_SSE2 && TARGET_MIX_SSE_I387" 3978{ 3979 gcc_assert (!which_alternative); 3980 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 3981 return "fstp%z0\t%y0"; 3982 else 3983 return "fst%z0\t%y0"; 3984} 3985 [(set_attr "type" "fmov,multi,multi,multi") 3986 (set_attr "unit" "*,i387,i387,i387") 3987 (set_attr "mode" "DF")]) 3988 3989(define_insn "truncxfdf2_i387_noop" 3990 [(set (match_operand:DF 0 "register_operand" "=f") 3991 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))] 3992 "TARGET_80387 && flag_unsafe_math_optimizations" 3993{ 3994 return output_387_reg_move (insn, operands); 3995} 3996 [(set_attr "type" "fmov") 3997 (set_attr "mode" "DF")]) 3998 3999(define_insn "*truncxfdf2_i387" 4000 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r") 4001 (float_truncate:DF 4002 (match_operand:XF 1 "register_operand" "f,f,f"))) 4003 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))] 4004 "TARGET_80387" 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") 4013 (set_attr "unit" "*,i387,i387") 4014 (set_attr "mode" "DF")]) 4015 4016(define_insn "*truncxfdf2_i387_1" 4017 [(set (match_operand:DF 0 "memory_operand" "=m") 4018 (float_truncate:DF 4019 (match_operand:XF 1 "register_operand" "f")))] 4020 "TARGET_80387" 4021{ 4022 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) 4023 return "fstp%z0\t%y0"; 4024 else 4025 return "fst%z0\t%y0"; 4026} 4027 [(set_attr "type" "fmov") 4028 (set_attr "mode" "DF")]) 4029 4030(define_split 4031 [(set (match_operand:DF 0 "register_operand" "") 4032 (float_truncate:DF 4033 (match_operand:XF 1 "register_operand" ""))) 4034 (clobber (match_operand:DF 2 "memory_operand" ""))] 4035 "TARGET_80387 && reload_completed" 4036 [(set (match_dup 2) (float_truncate:DF (match_dup 1))) 4037 (set (match_dup 0) (match_dup 2))] 4038 "") 4039 4040(define_split 4041 [(set (match_operand:DF 0 "memory_operand" "") 4042 (float_truncate:DF 4043 (match_operand:XF 1 "register_operand" ""))) 4044 (clobber (match_operand:DF 2 "memory_operand" ""))] 4045 "TARGET_80387" 4046 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))] 4047 "") 4048 4049;; Signed conversion to DImode. 4050 4051(define_expand "fix_truncxfdi2" 4052 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 4053 (fix:DI (match_operand:XF 1 "register_operand" ""))) 4054 (clobber (reg:CC FLAGS_REG))])] 4055 "TARGET_80387" 4056{ 4057 if (TARGET_FISTTP) 4058 { 4059 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4060 DONE; 4061 } 4062}) 4063 4064(define_expand "fix_trunc<mode>di2" 4065 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 4066 (fix:DI (match_operand:SSEMODEF 1 "register_operand" ""))) 4067 (clobber (reg:CC FLAGS_REG))])] 4068 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))" 4069{ 4070 if (TARGET_FISTTP 4071 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4072 { 4073 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4074 DONE; 4075 } 4076 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)) 4077 { 4078 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode); 4079 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1])); 4080 if (out != operands[0]) 4081 emit_move_insn (operands[0], out); 4082 DONE; 4083 } 4084}) 4085 4086;; Signed conversion to SImode. 4087 4088(define_expand "fix_truncxfsi2" 4089 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4090 (fix:SI (match_operand:XF 1 "register_operand" ""))) 4091 (clobber (reg:CC FLAGS_REG))])] 4092 "TARGET_80387" 4093{ 4094 if (TARGET_FISTTP) 4095 { 4096 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4097 DONE; 4098 } 4099}) 4100 4101(define_expand "fix_trunc<mode>si2" 4102 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4103 (fix:SI (match_operand:SSEMODEF 1 "register_operand" ""))) 4104 (clobber (reg:CC FLAGS_REG))])] 4105 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)" 4106{ 4107 if (TARGET_FISTTP 4108 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4109 { 4110 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4111 DONE; 4112 } 4113 if (SSE_FLOAT_MODE_P (<MODE>mode)) 4114 { 4115 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode); 4116 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1])); 4117 if (out != operands[0]) 4118 emit_move_insn (operands[0], out); 4119 DONE; 4120 } 4121}) 4122 4123;; Signed conversion to HImode. 4124 4125(define_expand "fix_trunc<mode>hi2" 4126 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 4127 (fix:HI (match_operand:X87MODEF 1 "register_operand" ""))) 4128 (clobber (reg:CC FLAGS_REG))])] 4129 "TARGET_80387 4130 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))" 4131{ 4132 if (TARGET_FISTTP) 4133 { 4134 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1])); 4135 DONE; 4136 } 4137}) 4138 4139;; When SSE is available, it is always faster to use it! 4140(define_insn "fix_truncsfdi_sse" 4141 [(set (match_operand:DI 0 "register_operand" "=r,r") 4142 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))] 4143 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4144 "cvttss2si{q}\t{%1, %0|%0, %1}" 4145 [(set_attr "type" "sseicvt") 4146 (set_attr "mode" "SF") 4147 (set_attr "athlon_decode" "double,vector")]) 4148 4149(define_insn "fix_truncdfdi_sse" 4150 [(set (match_operand:DI 0 "register_operand" "=r,r") 4151 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))] 4152 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4153 "cvttsd2si{q}\t{%1, %0|%0, %1}" 4154 [(set_attr "type" "sseicvt") 4155 (set_attr "mode" "DF") 4156 (set_attr "athlon_decode" "double,vector")]) 4157 4158(define_insn "fix_truncsfsi_sse" 4159 [(set (match_operand:SI 0 "register_operand" "=r,r") 4160 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))] 4161 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4162 "cvttss2si\t{%1, %0|%0, %1}" 4163 [(set_attr "type" "sseicvt") 4164 (set_attr "mode" "DF") 4165 (set_attr "athlon_decode" "double,vector")]) 4166 4167(define_insn "fix_truncdfsi_sse" 4168 [(set (match_operand:SI 0 "register_operand" "=r,r") 4169 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))] 4170 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4171 "cvttsd2si\t{%1, %0|%0, %1}" 4172 [(set_attr "type" "sseicvt") 4173 (set_attr "mode" "DF") 4174 (set_attr "athlon_decode" "double,vector")]) 4175 4176;; Avoid vector decoded forms of the instruction. 4177(define_peephole2 4178 [(match_scratch:DF 2 "Y") 4179 (set (match_operand:SSEMODEI24 0 "register_operand" "") 4180 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))] 4181 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size" 4182 [(set (match_dup 2) (match_dup 1)) 4183 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))] 4184 "") 4185 4186(define_peephole2 4187 [(match_scratch:SF 2 "x") 4188 (set (match_operand:SSEMODEI24 0 "register_operand" "") 4189 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))] 4190 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size" 4191 [(set (match_dup 2) (match_dup 1)) 4192 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))] 4193 "") 4194 4195(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1" 4196 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 4197 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))] 4198 "TARGET_FISTTP 4199 && FLOAT_MODE_P (GET_MODE (operands[1])) 4200 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4201 && (TARGET_64BIT || <MODE>mode != DImode)) 4202 && TARGET_SSE_MATH) 4203 && !(reload_completed || reload_in_progress)" 4204 "#" 4205 "&& 1" 4206 [(const_int 0)] 4207{ 4208 if (memory_operand (operands[0], VOIDmode)) 4209 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1])); 4210 else 4211 { 4212 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4213 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0], 4214 operands[1], 4215 operands[2])); 4216 } 4217 DONE; 4218} 4219 [(set_attr "type" "fisttp") 4220 (set_attr "mode" "<MODE>")]) 4221 4222(define_insn "fix_trunc<mode>_i387_fisttp" 4223 [(set (match_operand:X87MODEI 0 "memory_operand" "=m") 4224 (fix:X87MODEI (match_operand 1 "register_operand" "f"))) 4225 (clobber (match_scratch:XF 2 "=&1f"))] 4226 "TARGET_FISTTP 4227 && FLOAT_MODE_P (GET_MODE (operands[1])) 4228 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4229 && (TARGET_64BIT || <MODE>mode != DImode)) 4230 && TARGET_SSE_MATH)" 4231 "* return output_fix_trunc (insn, operands, 1);" 4232 [(set_attr "type" "fisttp") 4233 (set_attr "mode" "<MODE>")]) 4234 4235(define_insn "fix_trunc<mode>_i387_fisttp_with_temp" 4236 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 4237 (fix:X87MODEI (match_operand 1 "register_operand" "f,f"))) 4238 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m")) 4239 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 4240 "TARGET_FISTTP 4241 && FLOAT_MODE_P (GET_MODE (operands[1])) 4242 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4243 && (TARGET_64BIT || <MODE>mode != DImode)) 4244 && TARGET_SSE_MATH)" 4245 "#" 4246 [(set_attr "type" "fisttp") 4247 (set_attr "mode" "<MODE>")]) 4248 4249(define_split 4250 [(set (match_operand:X87MODEI 0 "register_operand" "") 4251 (fix:X87MODEI (match_operand 1 "register_operand" ""))) 4252 (clobber (match_operand:X87MODEI 2 "memory_operand" "")) 4253 (clobber (match_scratch 3 ""))] 4254 "reload_completed" 4255 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1))) 4256 (clobber (match_dup 3))]) 4257 (set (match_dup 0) (match_dup 2))] 4258 "") 4259 4260(define_split 4261 [(set (match_operand:X87MODEI 0 "memory_operand" "") 4262 (fix:X87MODEI (match_operand 1 "register_operand" ""))) 4263 (clobber (match_operand:X87MODEI 2 "memory_operand" "")) 4264 (clobber (match_scratch 3 ""))] 4265 "reload_completed" 4266 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1))) 4267 (clobber (match_dup 3))])] 4268 "") 4269 4270;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description 4271;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control 4272;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG 4273;; clobbering insns can be used. Look at emit_i387_cw_initialization () 4274;; function in i386.c. 4275(define_insn_and_split "*fix_trunc<mode>_i387_1" 4276 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 4277 (fix:X87MODEI (match_operand 1 "register_operand" "f,f"))) 4278 (clobber (reg:CC FLAGS_REG))] 4279 "TARGET_80387 && !TARGET_FISTTP 4280 && FLOAT_MODE_P (GET_MODE (operands[1])) 4281 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4282 && (TARGET_64BIT || <MODE>mode != DImode)) 4283 && !(reload_completed || reload_in_progress)" 4284 "#" 4285 "&& 1" 4286 [(const_int 0)] 4287{ 4288 ix86_optimize_mode_switching[I387_TRUNC] = 1; 4289 4290 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 4291 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 4292 if (memory_operand (operands[0], VOIDmode)) 4293 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1], 4294 operands[2], operands[3])); 4295 else 4296 { 4297 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4298 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1], 4299 operands[2], operands[3], 4300 operands[4])); 4301 } 4302 DONE; 4303} 4304 [(set_attr "type" "fistp") 4305 (set_attr "i387_cw" "trunc") 4306 (set_attr "mode" "<MODE>")]) 4307 4308(define_insn "fix_truncdi_i387" 4309 [(set (match_operand:DI 0 "memory_operand" "=m") 4310 (fix:DI (match_operand 1 "register_operand" "f"))) 4311 (use (match_operand:HI 2 "memory_operand" "m")) 4312 (use (match_operand:HI 3 "memory_operand" "m")) 4313 (clobber (match_scratch:XF 4 "=&1f"))] 4314 "TARGET_80387 && !TARGET_FISTTP 4315 && FLOAT_MODE_P (GET_MODE (operands[1])) 4316 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4317 "* return output_fix_trunc (insn, operands, 0);" 4318 [(set_attr "type" "fistp") 4319 (set_attr "i387_cw" "trunc") 4320 (set_attr "mode" "DI")]) 4321 4322(define_insn "fix_truncdi_i387_with_temp" 4323 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 4324 (fix:DI (match_operand 1 "register_operand" "f,f"))) 4325 (use (match_operand:HI 2 "memory_operand" "m,m")) 4326 (use (match_operand:HI 3 "memory_operand" "m,m")) 4327 (clobber (match_operand:DI 4 "memory_operand" "=m,m")) 4328 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 4329 "TARGET_80387 && !TARGET_FISTTP 4330 && FLOAT_MODE_P (GET_MODE (operands[1])) 4331 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4332 "#" 4333 [(set_attr "type" "fistp") 4334 (set_attr "i387_cw" "trunc") 4335 (set_attr "mode" "DI")]) 4336 4337(define_split 4338 [(set (match_operand:DI 0 "register_operand" "") 4339 (fix:DI (match_operand 1 "register_operand" ""))) 4340 (use (match_operand:HI 2 "memory_operand" "")) 4341 (use (match_operand:HI 3 "memory_operand" "")) 4342 (clobber (match_operand:DI 4 "memory_operand" "")) 4343 (clobber (match_scratch 5 ""))] 4344 "reload_completed" 4345 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1))) 4346 (use (match_dup 2)) 4347 (use (match_dup 3)) 4348 (clobber (match_dup 5))]) 4349 (set (match_dup 0) (match_dup 4))] 4350 "") 4351 4352(define_split 4353 [(set (match_operand:DI 0 "memory_operand" "") 4354 (fix:DI (match_operand 1 "register_operand" ""))) 4355 (use (match_operand:HI 2 "memory_operand" "")) 4356 (use (match_operand:HI 3 "memory_operand" "")) 4357 (clobber (match_operand:DI 4 "memory_operand" "")) 4358 (clobber (match_scratch 5 ""))] 4359 "reload_completed" 4360 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1))) 4361 (use (match_dup 2)) 4362 (use (match_dup 3)) 4363 (clobber (match_dup 5))])] 4364 "") 4365 4366(define_insn "fix_trunc<mode>_i387" 4367 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 4368 (fix:X87MODEI12 (match_operand 1 "register_operand" "f"))) 4369 (use (match_operand:HI 2 "memory_operand" "m")) 4370 (use (match_operand:HI 3 "memory_operand" "m"))] 4371 "TARGET_80387 && !TARGET_FISTTP 4372 && FLOAT_MODE_P (GET_MODE (operands[1])) 4373 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4374 "* return output_fix_trunc (insn, operands, 0);" 4375 [(set_attr "type" "fistp") 4376 (set_attr "i387_cw" "trunc") 4377 (set_attr "mode" "<MODE>")]) 4378 4379(define_insn "fix_trunc<mode>_i387_with_temp" 4380 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") 4381 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f"))) 4382 (use (match_operand:HI 2 "memory_operand" "m,m")) 4383 (use (match_operand:HI 3 "memory_operand" "m,m")) 4384 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))] 4385 "TARGET_80387 && !TARGET_FISTTP 4386 && FLOAT_MODE_P (GET_MODE (operands[1])) 4387 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4388 "#" 4389 [(set_attr "type" "fistp") 4390 (set_attr "i387_cw" "trunc") 4391 (set_attr "mode" "<MODE>")]) 4392 4393(define_split 4394 [(set (match_operand:X87MODEI12 0 "register_operand" "") 4395 (fix:X87MODEI12 (match_operand 1 "register_operand" ""))) 4396 (use (match_operand:HI 2 "memory_operand" "")) 4397 (use (match_operand:HI 3 "memory_operand" "")) 4398 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 4399 "reload_completed" 4400 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1))) 4401 (use (match_dup 2)) 4402 (use (match_dup 3))]) 4403 (set (match_dup 0) (match_dup 4))] 4404 "") 4405 4406(define_split 4407 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 4408 (fix:X87MODEI12 (match_operand 1 "register_operand" ""))) 4409 (use (match_operand:HI 2 "memory_operand" "")) 4410 (use (match_operand:HI 3 "memory_operand" "")) 4411 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 4412 "reload_completed" 4413 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1))) 4414 (use (match_dup 2)) 4415 (use (match_dup 3))])] 4416 "") 4417 4418(define_insn "x86_fnstcw_1" 4419 [(set (match_operand:HI 0 "memory_operand" "=m") 4420 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))] 4421 "TARGET_80387" 4422 "fnstcw\t%0" 4423 [(set_attr "length" "2") 4424 (set_attr "mode" "HI") 4425 (set_attr "unit" "i387")]) 4426 4427(define_insn "x86_fldcw_1" 4428 [(set (reg:HI FPSR_REG) 4429 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))] 4430 "TARGET_80387" 4431 "fldcw\t%0" 4432 [(set_attr "length" "2") 4433 (set_attr "mode" "HI") 4434 (set_attr "unit" "i387") 4435 (set_attr "athlon_decode" "vector")]) 4436 4437;; Conversion between fixed point and floating point. 4438 4439;; Even though we only accept memory inputs, the backend _really_ 4440;; wants to be able to do this between registers. 4441 4442(define_expand "floathisf2" 4443 [(set (match_operand:SF 0 "register_operand" "") 4444 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))] 4445 "TARGET_80387 || TARGET_SSE_MATH" 4446{ 4447 if (TARGET_SSE_MATH) 4448 { 4449 emit_insn (gen_floatsisf2 (operands[0], 4450 convert_to_mode (SImode, operands[1], 0))); 4451 DONE; 4452 } 4453}) 4454 4455(define_insn "*floathisf2_i387" 4456 [(set (match_operand:SF 0 "register_operand" "=f,f") 4457 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))] 4458 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 4459 "@ 4460 fild%z1\t%1 4461 #" 4462 [(set_attr "type" "fmov,multi") 4463 (set_attr "mode" "SF") 4464 (set_attr "unit" "*,i387") 4465 (set_attr "fp_int_src" "true")]) 4466 4467(define_expand "floatsisf2" 4468 [(set (match_operand:SF 0 "register_operand" "") 4469 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))] 4470 "TARGET_80387 || TARGET_SSE_MATH" 4471 "") 4472 4473(define_insn "*floatsisf2_mixed" 4474 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x") 4475 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))] 4476 "TARGET_MIX_SSE_I387" 4477 "@ 4478 fild%z1\t%1 4479 # 4480 cvtsi2ss\t{%1, %0|%0, %1} 4481 cvtsi2ss\t{%1, %0|%0, %1}" 4482 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4483 (set_attr "mode" "SF") 4484 (set_attr "unit" "*,i387,*,*") 4485 (set_attr "athlon_decode" "*,*,vector,double") 4486 (set_attr "fp_int_src" "true")]) 4487 4488(define_insn "*floatsisf2_sse" 4489 [(set (match_operand:SF 0 "register_operand" "=x,x") 4490 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))] 4491 "TARGET_SSE_MATH" 4492 "cvtsi2ss\t{%1, %0|%0, %1}" 4493 [(set_attr "type" "sseicvt") 4494 (set_attr "mode" "SF") 4495 (set_attr "athlon_decode" "vector,double") 4496 (set_attr "fp_int_src" "true")]) 4497 4498(define_insn "*floatsisf2_i387" 4499 [(set (match_operand:SF 0 "register_operand" "=f,f") 4500 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))] 4501 "TARGET_80387" 4502 "@ 4503 fild%z1\t%1 4504 #" 4505 [(set_attr "type" "fmov,multi") 4506 (set_attr "mode" "SF") 4507 (set_attr "unit" "*,i387") 4508 (set_attr "fp_int_src" "true")]) 4509 4510(define_expand "floatdisf2" 4511 [(set (match_operand:SF 0 "register_operand" "") 4512 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))] 4513 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)" 4514 "") 4515 4516(define_insn "*floatdisf2_mixed" 4517 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x") 4518 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))] 4519 "TARGET_64BIT && TARGET_MIX_SSE_I387" 4520 "@ 4521 fild%z1\t%1 4522 # 4523 cvtsi2ss{q}\t{%1, %0|%0, %1} 4524 cvtsi2ss{q}\t{%1, %0|%0, %1}" 4525 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4526 (set_attr "mode" "SF") 4527 (set_attr "unit" "*,i387,*,*") 4528 (set_attr "athlon_decode" "*,*,vector,double") 4529 (set_attr "fp_int_src" "true")]) 4530 4531(define_insn "*floatdisf2_sse" 4532 [(set (match_operand:SF 0 "register_operand" "=x,x") 4533 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))] 4534 "TARGET_64BIT && TARGET_SSE_MATH" 4535 "cvtsi2ss{q}\t{%1, %0|%0, %1}" 4536 [(set_attr "type" "sseicvt") 4537 (set_attr "mode" "SF") 4538 (set_attr "athlon_decode" "vector,double") 4539 (set_attr "fp_int_src" "true")]) 4540 4541(define_insn "*floatdisf2_i387" 4542 [(set (match_operand:SF 0 "register_operand" "=f,f") 4543 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))] 4544 "TARGET_80387" 4545 "@ 4546 fild%z1\t%1 4547 #" 4548 [(set_attr "type" "fmov,multi") 4549 (set_attr "mode" "SF") 4550 (set_attr "unit" "*,i387") 4551 (set_attr "fp_int_src" "true")]) 4552 4553(define_expand "floathidf2" 4554 [(set (match_operand:DF 0 "register_operand" "") 4555 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))] 4556 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4557{ 4558 if (TARGET_SSE2 && TARGET_SSE_MATH) 4559 { 4560 emit_insn (gen_floatsidf2 (operands[0], 4561 convert_to_mode (SImode, operands[1], 0))); 4562 DONE; 4563 } 4564}) 4565 4566(define_insn "*floathidf2_i387" 4567 [(set (match_operand:DF 0 "register_operand" "=f,f") 4568 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))] 4569 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)" 4570 "@ 4571 fild%z1\t%1 4572 #" 4573 [(set_attr "type" "fmov,multi") 4574 (set_attr "mode" "DF") 4575 (set_attr "unit" "*,i387") 4576 (set_attr "fp_int_src" "true")]) 4577 4578(define_expand "floatsidf2" 4579 [(set (match_operand:DF 0 "register_operand" "") 4580 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))] 4581 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4582 "") 4583 4584(define_insn "*floatsidf2_mixed" 4585 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y") 4586 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))] 4587 "TARGET_SSE2 && TARGET_MIX_SSE_I387" 4588 "@ 4589 fild%z1\t%1 4590 # 4591 cvtsi2sd\t{%1, %0|%0, %1} 4592 cvtsi2sd\t{%1, %0|%0, %1}" 4593 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4594 (set_attr "mode" "DF") 4595 (set_attr "unit" "*,i387,*,*") 4596 (set_attr "athlon_decode" "*,*,double,direct") 4597 (set_attr "fp_int_src" "true")]) 4598 4599(define_insn "*floatsidf2_sse" 4600 [(set (match_operand:DF 0 "register_operand" "=Y,Y") 4601 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))] 4602 "TARGET_SSE2 && TARGET_SSE_MATH" 4603 "cvtsi2sd\t{%1, %0|%0, %1}" 4604 [(set_attr "type" "sseicvt") 4605 (set_attr "mode" "DF") 4606 (set_attr "athlon_decode" "double,direct") 4607 (set_attr "fp_int_src" "true")]) 4608 4609(define_insn "*floatsidf2_i387" 4610 [(set (match_operand:DF 0 "register_operand" "=f,f") 4611 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))] 4612 "TARGET_80387" 4613 "@ 4614 fild%z1\t%1 4615 #" 4616 [(set_attr "type" "fmov,multi") 4617 (set_attr "mode" "DF") 4618 (set_attr "unit" "*,i387") 4619 (set_attr "fp_int_src" "true")]) 4620 4621(define_expand "floatdidf2" 4622 [(set (match_operand:DF 0 "register_operand" "") 4623 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))] 4624 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)" 4625 "") 4626 4627(define_insn "*floatdidf2_mixed" 4628 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y") 4629 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))] 4630 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387" 4631 "@ 4632 fild%z1\t%1 4633 # 4634 cvtsi2sd{q}\t{%1, %0|%0, %1} 4635 cvtsi2sd{q}\t{%1, %0|%0, %1}" 4636 [(set_attr "type" "fmov,multi,sseicvt,sseicvt") 4637 (set_attr "mode" "DF") 4638 (set_attr "unit" "*,i387,*,*") 4639 (set_attr "athlon_decode" "*,*,double,direct") 4640 (set_attr "fp_int_src" "true")]) 4641 4642(define_insn "*floatdidf2_sse" 4643 [(set (match_operand:DF 0 "register_operand" "=Y,Y") 4644 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))] 4645 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH" 4646 "cvtsi2sd{q}\t{%1, %0|%0, %1}" 4647 [(set_attr "type" "sseicvt") 4648 (set_attr "mode" "DF") 4649 (set_attr "athlon_decode" "double,direct") 4650 (set_attr "fp_int_src" "true")]) 4651 4652(define_insn "*floatdidf2_i387" 4653 [(set (match_operand:DF 0 "register_operand" "=f,f") 4654 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))] 4655 "TARGET_80387" 4656 "@ 4657 fild%z1\t%1 4658 #" 4659 [(set_attr "type" "fmov,multi") 4660 (set_attr "mode" "DF") 4661 (set_attr "unit" "*,i387") 4662 (set_attr "fp_int_src" "true")]) 4663 4664(define_insn "floathixf2" 4665 [(set (match_operand:XF 0 "register_operand" "=f,f") 4666 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))] 4667 "TARGET_80387" 4668 "@ 4669 fild%z1\t%1 4670 #" 4671 [(set_attr "type" "fmov,multi") 4672 (set_attr "mode" "XF") 4673 (set_attr "unit" "*,i387") 4674 (set_attr "fp_int_src" "true")]) 4675 4676(define_insn "floatsixf2" 4677 [(set (match_operand:XF 0 "register_operand" "=f,f") 4678 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))] 4679 "TARGET_80387" 4680 "@ 4681 fild%z1\t%1 4682 #" 4683 [(set_attr "type" "fmov,multi") 4684 (set_attr "mode" "XF") 4685 (set_attr "unit" "*,i387") 4686 (set_attr "fp_int_src" "true")]) 4687 4688(define_insn "floatdixf2" 4689 [(set (match_operand:XF 0 "register_operand" "=f,f") 4690 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))] 4691 "TARGET_80387" 4692 "@ 4693 fild%z1\t%1 4694 #" 4695 [(set_attr "type" "fmov,multi") 4696 (set_attr "mode" "XF") 4697 (set_attr "unit" "*,i387") 4698 (set_attr "fp_int_src" "true")]) 4699 4700;; %%% Kill these when reload knows how to do it. 4701(define_split 4702 [(set (match_operand 0 "fp_register_operand" "") 4703 (float (match_operand 1 "register_operand" "")))] 4704 "reload_completed 4705 && TARGET_80387 4706 && FLOAT_MODE_P (GET_MODE (operands[0]))" 4707 [(const_int 0)] 4708{ 4709 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]); 4710 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]); 4711 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2])); 4712 ix86_free_from_memory (GET_MODE (operands[1])); 4713 DONE; 4714}) 4715 4716(define_expand "floatunssisf2" 4717 [(use (match_operand:SF 0 "register_operand" "")) 4718 (use (match_operand:SI 1 "register_operand" ""))] 4719 "!TARGET_64BIT && TARGET_SSE_MATH" 4720 "x86_emit_floatuns (operands); DONE;") 4721 4722(define_expand "floatunsdisf2" 4723 [(use (match_operand:SF 0 "register_operand" "")) 4724 (use (match_operand:DI 1 "register_operand" ""))] 4725 "TARGET_64BIT && TARGET_SSE_MATH" 4726 "x86_emit_floatuns (operands); DONE;") 4727 4728(define_expand "floatunsdidf2" 4729 [(use (match_operand:DF 0 "register_operand" "")) 4730 (use (match_operand:DI 1 "register_operand" ""))] 4731 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH" 4732 "x86_emit_floatuns (operands); DONE;") 4733 4734;; SSE extract/set expanders 4735 4736 4737;; Add instructions 4738 4739;; %%% splits for addditi3 4740 4741(define_expand "addti3" 4742 [(set (match_operand:TI 0 "nonimmediate_operand" "") 4743 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "") 4744 (match_operand:TI 2 "x86_64_general_operand" ""))) 4745 (clobber (reg:CC FLAGS_REG))] 4746 "TARGET_64BIT" 4747 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;") 4748 4749(define_insn "*addti3_1" 4750 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o") 4751 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0") 4752 (match_operand:TI 2 "x86_64_general_operand" "roe,re"))) 4753 (clobber (reg:CC FLAGS_REG))] 4754 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)" 4755 "#") 4756 4757(define_split 4758 [(set (match_operand:TI 0 "nonimmediate_operand" "") 4759 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "") 4760 (match_operand:TI 2 "x86_64_general_operand" ""))) 4761 (clobber (reg:CC FLAGS_REG))] 4762 "TARGET_64BIT && reload_completed" 4763 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)] 4764 UNSPEC_ADD_CARRY)) 4765 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]) 4766 (parallel [(set (match_dup 3) 4767 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) 4768 (match_dup 4)) 4769 (match_dup 5))) 4770 (clobber (reg:CC FLAGS_REG))])] 4771 "split_ti (operands+0, 1, operands+0, operands+3); 4772 split_ti (operands+1, 1, operands+1, operands+4); 4773 split_ti (operands+2, 1, operands+2, operands+5);") 4774 4775;; %%% splits for addsidi3 4776; [(set (match_operand:DI 0 "nonimmediate_operand" "") 4777; (plus:DI (match_operand:DI 1 "general_operand" "") 4778; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))] 4779 4780(define_expand "adddi3" 4781 [(set (match_operand:DI 0 "nonimmediate_operand" "") 4782 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") 4783 (match_operand:DI 2 "x86_64_general_operand" ""))) 4784 (clobber (reg:CC FLAGS_REG))] 4785 "" 4786 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;") 4787 4788(define_insn "*adddi3_1" 4789 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") 4790 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 4791 (match_operand:DI 2 "general_operand" "roiF,riF"))) 4792 (clobber (reg:CC FLAGS_REG))] 4793 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 4794 "#") 4795 4796(define_split 4797 [(set (match_operand:DI 0 "nonimmediate_operand" "") 4798 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") 4799 (match_operand:DI 2 "general_operand" ""))) 4800 (clobber (reg:CC FLAGS_REG))] 4801 "!TARGET_64BIT && reload_completed" 4802 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)] 4803 UNSPEC_ADD_CARRY)) 4804 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) 4805 (parallel [(set (match_dup 3) 4806 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) 4807 (match_dup 4)) 4808 (match_dup 5))) 4809 (clobber (reg:CC FLAGS_REG))])] 4810 "split_di (operands+0, 1, operands+0, operands+3); 4811 split_di (operands+1, 1, operands+1, operands+4); 4812 split_di (operands+2, 1, operands+2, operands+5);") 4813 4814(define_insn "adddi3_carry_rex64" 4815 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 4816 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "") 4817 (match_operand:DI 1 "nonimmediate_operand" "%0,0")) 4818 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 4819 (clobber (reg:CC FLAGS_REG))] 4820 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 4821 "adc{q}\t{%2, %0|%0, %2}" 4822 [(set_attr "type" "alu") 4823 (set_attr "pent_pair" "pu") 4824 (set_attr "mode" "DI")]) 4825 4826(define_insn "*adddi3_cc_rex64" 4827 [(set (reg:CC FLAGS_REG) 4828 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0") 4829 (match_operand:DI 2 "x86_64_general_operand" "re,rm")] 4830 UNSPEC_ADD_CARRY)) 4831 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 4832 (plus:DI (match_dup 1) (match_dup 2)))] 4833 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 4834 "add{q}\t{%2, %0|%0, %2}" 4835 [(set_attr "type" "alu") 4836 (set_attr "mode" "DI")]) 4837 4838(define_insn "addqi3_carry" 4839 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 4840 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "") 4841 (match_operand:QI 1 "nonimmediate_operand" "%0,0")) 4842 (match_operand:QI 2 "general_operand" "qi,qm"))) 4843 (clobber (reg:CC FLAGS_REG))] 4844 "ix86_binary_operator_ok (PLUS, QImode, operands)" 4845 "adc{b}\t{%2, %0|%0, %2}" 4846 [(set_attr "type" "alu") 4847 (set_attr "pent_pair" "pu") 4848 (set_attr "mode" "QI")]) 4849 4850(define_insn "addhi3_carry" 4851 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 4852 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "") 4853 (match_operand:HI 1 "nonimmediate_operand" "%0,0")) 4854 (match_operand:HI 2 "general_operand" "ri,rm"))) 4855 (clobber (reg:CC FLAGS_REG))] 4856 "ix86_binary_operator_ok (PLUS, HImode, operands)" 4857 "adc{w}\t{%2, %0|%0, %2}" 4858 [(set_attr "type" "alu") 4859 (set_attr "pent_pair" "pu") 4860 (set_attr "mode" "HI")]) 4861 4862(define_insn "addsi3_carry" 4863 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 4864 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 4865 (match_operand:SI 1 "nonimmediate_operand" "%0,0")) 4866 (match_operand:SI 2 "general_operand" "ri,rm"))) 4867 (clobber (reg:CC FLAGS_REG))] 4868 "ix86_binary_operator_ok (PLUS, SImode, operands)" 4869 "adc{l}\t{%2, %0|%0, %2}" 4870 [(set_attr "type" "alu") 4871 (set_attr "pent_pair" "pu") 4872 (set_attr "mode" "SI")]) 4873 4874(define_insn "*addsi3_carry_zext" 4875 [(set (match_operand:DI 0 "register_operand" "=r") 4876 (zero_extend:DI 4877 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 4878 (match_operand:SI 1 "nonimmediate_operand" "%0")) 4879 (match_operand:SI 2 "general_operand" "rim")))) 4880 (clobber (reg:CC FLAGS_REG))] 4881 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 4882 "adc{l}\t{%2, %k0|%k0, %2}" 4883 [(set_attr "type" "alu") 4884 (set_attr "pent_pair" "pu") 4885 (set_attr "mode" "SI")]) 4886 4887(define_insn "*addsi3_cc" 4888 [(set (reg:CC FLAGS_REG) 4889 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0") 4890 (match_operand:SI 2 "general_operand" "ri,rm")] 4891 UNSPEC_ADD_CARRY)) 4892 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 4893 (plus:SI (match_dup 1) (match_dup 2)))] 4894 "ix86_binary_operator_ok (PLUS, SImode, operands)" 4895 "add{l}\t{%2, %0|%0, %2}" 4896 [(set_attr "type" "alu") 4897 (set_attr "mode" "SI")]) 4898 4899(define_insn "addqi3_cc" 4900 [(set (reg:CC FLAGS_REG) 4901 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0") 4902 (match_operand:QI 2 "general_operand" "qi,qm")] 4903 UNSPEC_ADD_CARRY)) 4904 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 4905 (plus:QI (match_dup 1) (match_dup 2)))] 4906 "ix86_binary_operator_ok (PLUS, QImode, operands)" 4907 "add{b}\t{%2, %0|%0, %2}" 4908 [(set_attr "type" "alu") 4909 (set_attr "mode" "QI")]) 4910 4911(define_expand "addsi3" 4912 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 4913 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "") 4914 (match_operand:SI 2 "general_operand" ""))) 4915 (clobber (reg:CC FLAGS_REG))])] 4916 "" 4917 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;") 4918 4919(define_insn "*lea_1" 4920 [(set (match_operand:SI 0 "register_operand" "=r") 4921 (match_operand:SI 1 "no_seg_address_operand" "p"))] 4922 "!TARGET_64BIT" 4923 "lea{l}\t{%a1, %0|%0, %a1}" 4924 [(set_attr "type" "lea") 4925 (set_attr "mode" "SI")]) 4926 4927(define_insn "*lea_1_rex64" 4928 [(set (match_operand:SI 0 "register_operand" "=r") 4929 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))] 4930 "TARGET_64BIT" 4931 "lea{l}\t{%a1, %0|%0, %a1}" 4932 [(set_attr "type" "lea") 4933 (set_attr "mode" "SI")]) 4934 4935(define_insn "*lea_1_zext" 4936 [(set (match_operand:DI 0 "register_operand" "=r") 4937 (zero_extend:DI 4938 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))] 4939 "TARGET_64BIT" 4940 "lea{l}\t{%a1, %k0|%k0, %a1}" 4941 [(set_attr "type" "lea") 4942 (set_attr "mode" "SI")]) 4943 4944(define_insn "*lea_2_rex64" 4945 [(set (match_operand:DI 0 "register_operand" "=r") 4946 (match_operand:DI 1 "no_seg_address_operand" "p"))] 4947 "TARGET_64BIT" 4948 "lea{q}\t{%a1, %0|%0, %a1}" 4949 [(set_attr "type" "lea") 4950 (set_attr "mode" "DI")]) 4951 4952;; The lea patterns for non-Pmodes needs to be matched by several 4953;; insns converted to real lea by splitters. 4954 4955(define_insn_and_split "*lea_general_1" 4956 [(set (match_operand 0 "register_operand" "=r") 4957 (plus (plus (match_operand 1 "index_register_operand" "l") 4958 (match_operand 2 "register_operand" "r")) 4959 (match_operand 3 "immediate_operand" "i")))] 4960 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode 4961 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) 4962 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 4963 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 4964 && GET_MODE (operands[0]) == GET_MODE (operands[2]) 4965 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 4966 || GET_MODE (operands[3]) == VOIDmode)" 4967 "#" 4968 "&& reload_completed" 4969 [(const_int 0)] 4970{ 4971 rtx pat; 4972 operands[0] = gen_lowpart (SImode, operands[0]); 4973 operands[1] = gen_lowpart (Pmode, operands[1]); 4974 operands[2] = gen_lowpart (Pmode, operands[2]); 4975 operands[3] = gen_lowpart (Pmode, operands[3]); 4976 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]), 4977 operands[3]); 4978 if (Pmode != SImode) 4979 pat = gen_rtx_SUBREG (SImode, pat, 0); 4980 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 4981 DONE; 4982} 4983 [(set_attr "type" "lea") 4984 (set_attr "mode" "SI")]) 4985 4986(define_insn_and_split "*lea_general_1_zext" 4987 [(set (match_operand:DI 0 "register_operand" "=r") 4988 (zero_extend:DI 4989 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l") 4990 (match_operand:SI 2 "register_operand" "r")) 4991 (match_operand:SI 3 "immediate_operand" "i"))))] 4992 "TARGET_64BIT" 4993 "#" 4994 "&& reload_completed" 4995 [(set (match_dup 0) 4996 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1) 4997 (match_dup 2)) 4998 (match_dup 3)) 0)))] 4999{ 5000 operands[1] = gen_lowpart (Pmode, operands[1]); 5001 operands[2] = gen_lowpart (Pmode, operands[2]); 5002 operands[3] = gen_lowpart (Pmode, operands[3]); 5003} 5004 [(set_attr "type" "lea") 5005 (set_attr "mode" "SI")]) 5006 5007(define_insn_and_split "*lea_general_2" 5008 [(set (match_operand 0 "register_operand" "=r") 5009 (plus (mult (match_operand 1 "index_register_operand" "l") 5010 (match_operand 2 "const248_operand" "i")) 5011 (match_operand 3 "nonmemory_operand" "ri")))] 5012 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode 5013 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) 5014 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 5015 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 5016 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 5017 || GET_MODE (operands[3]) == VOIDmode)" 5018 "#" 5019 "&& reload_completed" 5020 [(const_int 0)] 5021{ 5022 rtx pat; 5023 operands[0] = gen_lowpart (SImode, operands[0]); 5024 operands[1] = gen_lowpart (Pmode, operands[1]); 5025 operands[3] = gen_lowpart (Pmode, operands[3]); 5026 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]), 5027 operands[3]); 5028 if (Pmode != SImode) 5029 pat = gen_rtx_SUBREG (SImode, pat, 0); 5030 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5031 DONE; 5032} 5033 [(set_attr "type" "lea") 5034 (set_attr "mode" "SI")]) 5035 5036(define_insn_and_split "*lea_general_2_zext" 5037 [(set (match_operand:DI 0 "register_operand" "=r") 5038 (zero_extend:DI 5039 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l") 5040 (match_operand:SI 2 "const248_operand" "n")) 5041 (match_operand:SI 3 "nonmemory_operand" "ri"))))] 5042 "TARGET_64BIT" 5043 "#" 5044 "&& reload_completed" 5045 [(set (match_dup 0) 5046 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1) 5047 (match_dup 2)) 5048 (match_dup 3)) 0)))] 5049{ 5050 operands[1] = gen_lowpart (Pmode, operands[1]); 5051 operands[3] = gen_lowpart (Pmode, operands[3]); 5052} 5053 [(set_attr "type" "lea") 5054 (set_attr "mode" "SI")]) 5055 5056(define_insn_and_split "*lea_general_3" 5057 [(set (match_operand 0 "register_operand" "=r") 5058 (plus (plus (mult (match_operand 1 "index_register_operand" "l") 5059 (match_operand 2 "const248_operand" "i")) 5060 (match_operand 3 "register_operand" "r")) 5061 (match_operand 4 "immediate_operand" "i")))] 5062 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode 5063 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode)) 5064 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 5065 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 5066 && GET_MODE (operands[0]) == GET_MODE (operands[3])" 5067 "#" 5068 "&& reload_completed" 5069 [(const_int 0)] 5070{ 5071 rtx pat; 5072 operands[0] = gen_lowpart (SImode, operands[0]); 5073 operands[1] = gen_lowpart (Pmode, operands[1]); 5074 operands[3] = gen_lowpart (Pmode, operands[3]); 5075 operands[4] = gen_lowpart (Pmode, operands[4]); 5076 pat = gen_rtx_PLUS (Pmode, 5077 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], 5078 operands[2]), 5079 operands[3]), 5080 operands[4]); 5081 if (Pmode != SImode) 5082 pat = gen_rtx_SUBREG (SImode, pat, 0); 5083 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5084 DONE; 5085} 5086 [(set_attr "type" "lea") 5087 (set_attr "mode" "SI")]) 5088 5089(define_insn_and_split "*lea_general_3_zext" 5090 [(set (match_operand:DI 0 "register_operand" "=r") 5091 (zero_extend:DI 5092 (plus:SI (plus:SI (mult:SI 5093 (match_operand:SI 1 "index_register_operand" "l") 5094 (match_operand:SI 2 "const248_operand" "n")) 5095 (match_operand:SI 3 "register_operand" "r")) 5096 (match_operand:SI 4 "immediate_operand" "i"))))] 5097 "TARGET_64BIT" 5098 "#" 5099 "&& reload_completed" 5100 [(set (match_dup 0) 5101 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1) 5102 (match_dup 2)) 5103 (match_dup 3)) 5104 (match_dup 4)) 0)))] 5105{ 5106 operands[1] = gen_lowpart (Pmode, operands[1]); 5107 operands[3] = gen_lowpart (Pmode, operands[3]); 5108 operands[4] = gen_lowpart (Pmode, operands[4]); 5109} 5110 [(set_attr "type" "lea") 5111 (set_attr "mode" "SI")]) 5112 5113(define_insn "*adddi_1_rex64" 5114 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r") 5115 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r") 5116 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le"))) 5117 (clobber (reg:CC FLAGS_REG))] 5118 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)" 5119{ 5120 switch (get_attr_type (insn)) 5121 { 5122 case TYPE_LEA: 5123 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 5124 return "lea{q}\t{%a2, %0|%0, %a2}"; 5125 5126 case TYPE_INCDEC: 5127 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5128 if (operands[2] == const1_rtx) 5129 return "inc{q}\t%0"; 5130 else 5131 { 5132 gcc_assert (operands[2] == constm1_rtx); 5133 return "dec{q}\t%0"; 5134 } 5135 5136 default: 5137 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5138 5139 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5140 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5141 if (GET_CODE (operands[2]) == CONST_INT 5142 /* Avoid overflows. */ 5143 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5144 && (INTVAL (operands[2]) == 128 5145 || (INTVAL (operands[2]) < 0 5146 && INTVAL (operands[2]) != -128))) 5147 { 5148 operands[2] = GEN_INT (-INTVAL (operands[2])); 5149 return "sub{q}\t{%2, %0|%0, %2}"; 5150 } 5151 return "add{q}\t{%2, %0|%0, %2}"; 5152 } 5153} 5154 [(set (attr "type") 5155 (cond [(eq_attr "alternative" "2") 5156 (const_string "lea") 5157 ; Current assemblers are broken and do not allow @GOTOFF in 5158 ; ought but a memory context. 5159 (match_operand:DI 2 "pic_symbolic_operand" "") 5160 (const_string "lea") 5161 (match_operand:DI 2 "incdec_operand" "") 5162 (const_string "incdec") 5163 ] 5164 (const_string "alu"))) 5165 (set_attr "mode" "DI")]) 5166 5167;; Convert lea to the lea pattern to avoid flags dependency. 5168(define_split 5169 [(set (match_operand:DI 0 "register_operand" "") 5170 (plus:DI (match_operand:DI 1 "register_operand" "") 5171 (match_operand:DI 2 "x86_64_nonmemory_operand" ""))) 5172 (clobber (reg:CC FLAGS_REG))] 5173 "TARGET_64BIT && reload_completed 5174 && true_regnum (operands[0]) != true_regnum (operands[1])" 5175 [(set (match_dup 0) 5176 (plus:DI (match_dup 1) 5177 (match_dup 2)))] 5178 "") 5179 5180(define_insn "*adddi_2_rex64" 5181 [(set (reg FLAGS_REG) 5182 (compare 5183 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 5184 (match_operand:DI 2 "x86_64_general_operand" "rme,re")) 5185 (const_int 0))) 5186 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") 5187 (plus:DI (match_dup 1) (match_dup 2)))] 5188 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 5189 && ix86_binary_operator_ok (PLUS, DImode, operands) 5190 /* Current assemblers are broken and do not allow @GOTOFF in 5191 ought but a memory context. */ 5192 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5193{ 5194 switch (get_attr_type (insn)) 5195 { 5196 case TYPE_INCDEC: 5197 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5198 if (operands[2] == const1_rtx) 5199 return "inc{q}\t%0"; 5200 else 5201 { 5202 gcc_assert (operands[2] == constm1_rtx); 5203 return "dec{q}\t%0"; 5204 } 5205 5206 default: 5207 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5208 /* ???? We ought to handle there the 32bit case too 5209 - do we need new constraint? */ 5210 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5211 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5212 if (GET_CODE (operands[2]) == CONST_INT 5213 /* Avoid overflows. */ 5214 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5215 && (INTVAL (operands[2]) == 128 5216 || (INTVAL (operands[2]) < 0 5217 && INTVAL (operands[2]) != -128))) 5218 { 5219 operands[2] = GEN_INT (-INTVAL (operands[2])); 5220 return "sub{q}\t{%2, %0|%0, %2}"; 5221 } 5222 return "add{q}\t{%2, %0|%0, %2}"; 5223 } 5224} 5225 [(set (attr "type") 5226 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5227 (const_string "incdec") 5228 (const_string "alu"))) 5229 (set_attr "mode" "DI")]) 5230 5231(define_insn "*adddi_3_rex64" 5232 [(set (reg FLAGS_REG) 5233 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme")) 5234 (match_operand:DI 1 "x86_64_general_operand" "%0"))) 5235 (clobber (match_scratch:DI 0 "=r"))] 5236 "TARGET_64BIT 5237 && ix86_match_ccmode (insn, CCZmode) 5238 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5239 /* Current assemblers are broken and do not allow @GOTOFF in 5240 ought but a memory context. */ 5241 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5242{ 5243 switch (get_attr_type (insn)) 5244 { 5245 case TYPE_INCDEC: 5246 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5247 if (operands[2] == const1_rtx) 5248 return "inc{q}\t%0"; 5249 else 5250 { 5251 gcc_assert (operands[2] == constm1_rtx); 5252 return "dec{q}\t%0"; 5253 } 5254 5255 default: 5256 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5257 /* ???? We ought to handle there the 32bit case too 5258 - do we need new constraint? */ 5259 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5260 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5261 if (GET_CODE (operands[2]) == CONST_INT 5262 /* Avoid overflows. */ 5263 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5264 && (INTVAL (operands[2]) == 128 5265 || (INTVAL (operands[2]) < 0 5266 && INTVAL (operands[2]) != -128))) 5267 { 5268 operands[2] = GEN_INT (-INTVAL (operands[2])); 5269 return "sub{q}\t{%2, %0|%0, %2}"; 5270 } 5271 return "add{q}\t{%2, %0|%0, %2}"; 5272 } 5273} 5274 [(set (attr "type") 5275 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5276 (const_string "incdec") 5277 (const_string "alu"))) 5278 (set_attr "mode" "DI")]) 5279 5280; For comparisons against 1, -1 and 128, we may generate better code 5281; by converting cmp to add, inc or dec as done by peephole2. This pattern 5282; is matched then. We can't accept general immediate, because for 5283; case of overflows, the result is messed up. 5284; This pattern also don't hold of 0x8000000000000000, since the value overflows 5285; when negated. 5286; Also carry flag is reversed compared to cmp, so this conversion is valid 5287; only for comparisons not depending on it. 5288(define_insn "*adddi_4_rex64" 5289 [(set (reg FLAGS_REG) 5290 (compare (match_operand:DI 1 "nonimmediate_operand" "0") 5291 (match_operand:DI 2 "x86_64_immediate_operand" "e"))) 5292 (clobber (match_scratch:DI 0 "=rm"))] 5293 "TARGET_64BIT 5294 && ix86_match_ccmode (insn, CCGCmode)" 5295{ 5296 switch (get_attr_type (insn)) 5297 { 5298 case TYPE_INCDEC: 5299 if (operands[2] == constm1_rtx) 5300 return "inc{q}\t%0"; 5301 else 5302 { 5303 gcc_assert (operands[2] == const1_rtx); 5304 return "dec{q}\t%0"; 5305 } 5306 5307 default: 5308 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5309 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5310 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5311 if ((INTVAL (operands[2]) == -128 5312 || (INTVAL (operands[2]) > 0 5313 && INTVAL (operands[2]) != 128)) 5314 /* Avoid overflows. */ 5315 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))) 5316 return "sub{q}\t{%2, %0|%0, %2}"; 5317 operands[2] = GEN_INT (-INTVAL (operands[2])); 5318 return "add{q}\t{%2, %0|%0, %2}"; 5319 } 5320} 5321 [(set (attr "type") 5322 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5323 (const_string "incdec") 5324 (const_string "alu"))) 5325 (set_attr "mode" "DI")]) 5326 5327(define_insn "*adddi_5_rex64" 5328 [(set (reg FLAGS_REG) 5329 (compare 5330 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0") 5331 (match_operand:DI 2 "x86_64_general_operand" "rme")) 5332 (const_int 0))) 5333 (clobber (match_scratch:DI 0 "=r"))] 5334 "TARGET_64BIT 5335 && ix86_match_ccmode (insn, CCGOCmode) 5336 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5337 /* Current assemblers are broken and do not allow @GOTOFF in 5338 ought but a memory context. */ 5339 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5340{ 5341 switch (get_attr_type (insn)) 5342 { 5343 case TYPE_INCDEC: 5344 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5345 if (operands[2] == const1_rtx) 5346 return "inc{q}\t%0"; 5347 else 5348 { 5349 gcc_assert (operands[2] == constm1_rtx); 5350 return "dec{q}\t%0"; 5351 } 5352 5353 default: 5354 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5355 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5356 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5357 if (GET_CODE (operands[2]) == CONST_INT 5358 /* Avoid overflows. */ 5359 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 5360 && (INTVAL (operands[2]) == 128 5361 || (INTVAL (operands[2]) < 0 5362 && INTVAL (operands[2]) != -128))) 5363 { 5364 operands[2] = GEN_INT (-INTVAL (operands[2])); 5365 return "sub{q}\t{%2, %0|%0, %2}"; 5366 } 5367 return "add{q}\t{%2, %0|%0, %2}"; 5368 } 5369} 5370 [(set (attr "type") 5371 (if_then_else (match_operand:DI 2 "incdec_operand" "") 5372 (const_string "incdec") 5373 (const_string "alu"))) 5374 (set_attr "mode" "DI")]) 5375 5376 5377(define_insn "*addsi_1" 5378 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r") 5379 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r") 5380 (match_operand:SI 2 "general_operand" "rmni,rni,lni"))) 5381 (clobber (reg:CC FLAGS_REG))] 5382 "ix86_binary_operator_ok (PLUS, SImode, operands)" 5383{ 5384 switch (get_attr_type (insn)) 5385 { 5386 case TYPE_LEA: 5387 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 5388 return "lea{l}\t{%a2, %0|%0, %a2}"; 5389 5390 case TYPE_INCDEC: 5391 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5392 if (operands[2] == const1_rtx) 5393 return "inc{l}\t%0"; 5394 else 5395 { 5396 gcc_assert (operands[2] == constm1_rtx); 5397 return "dec{l}\t%0"; 5398 } 5399 5400 default: 5401 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5402 5403 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5404 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5405 if (GET_CODE (operands[2]) == CONST_INT 5406 && (INTVAL (operands[2]) == 128 5407 || (INTVAL (operands[2]) < 0 5408 && INTVAL (operands[2]) != -128))) 5409 { 5410 operands[2] = GEN_INT (-INTVAL (operands[2])); 5411 return "sub{l}\t{%2, %0|%0, %2}"; 5412 } 5413 return "add{l}\t{%2, %0|%0, %2}"; 5414 } 5415} 5416 [(set (attr "type") 5417 (cond [(eq_attr "alternative" "2") 5418 (const_string "lea") 5419 ; Current assemblers are broken and do not allow @GOTOFF in 5420 ; ought but a memory context. 5421 (match_operand:SI 2 "pic_symbolic_operand" "") 5422 (const_string "lea") 5423 (match_operand:SI 2 "incdec_operand" "") 5424 (const_string "incdec") 5425 ] 5426 (const_string "alu"))) 5427 (set_attr "mode" "SI")]) 5428 5429;; Convert lea to the lea pattern to avoid flags dependency. 5430(define_split 5431 [(set (match_operand 0 "register_operand" "") 5432 (plus (match_operand 1 "register_operand" "") 5433 (match_operand 2 "nonmemory_operand" ""))) 5434 (clobber (reg:CC FLAGS_REG))] 5435 "reload_completed 5436 && true_regnum (operands[0]) != true_regnum (operands[1])" 5437 [(const_int 0)] 5438{ 5439 rtx pat; 5440 /* In -fPIC mode the constructs like (const (unspec [symbol_ref])) 5441 may confuse gen_lowpart. */ 5442 if (GET_MODE (operands[0]) != Pmode) 5443 { 5444 operands[1] = gen_lowpart (Pmode, operands[1]); 5445 operands[2] = gen_lowpart (Pmode, operands[2]); 5446 } 5447 operands[0] = gen_lowpart (SImode, operands[0]); 5448 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]); 5449 if (Pmode != SImode) 5450 pat = gen_rtx_SUBREG (SImode, pat, 0); 5451 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5452 DONE; 5453}) 5454 5455;; It may seem that nonimmediate operand is proper one for operand 1. 5456;; The addsi_1 pattern allows nonimmediate operand at that place and 5457;; we take care in ix86_binary_operator_ok to not allow two memory 5458;; operands so proper swapping will be done in reload. This allow 5459;; patterns constructed from addsi_1 to match. 5460(define_insn "addsi_1_zext" 5461 [(set (match_operand:DI 0 "register_operand" "=r,r") 5462 (zero_extend:DI 5463 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") 5464 (match_operand:SI 2 "general_operand" "rmni,lni")))) 5465 (clobber (reg:CC FLAGS_REG))] 5466 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 5467{ 5468 switch (get_attr_type (insn)) 5469 { 5470 case TYPE_LEA: 5471 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 5472 return "lea{l}\t{%a2, %k0|%k0, %a2}"; 5473 5474 case TYPE_INCDEC: 5475 if (operands[2] == const1_rtx) 5476 return "inc{l}\t%k0"; 5477 else 5478 { 5479 gcc_assert (operands[2] == constm1_rtx); 5480 return "dec{l}\t%k0"; 5481 } 5482 5483 default: 5484 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5485 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5486 if (GET_CODE (operands[2]) == CONST_INT 5487 && (INTVAL (operands[2]) == 128 5488 || (INTVAL (operands[2]) < 0 5489 && INTVAL (operands[2]) != -128))) 5490 { 5491 operands[2] = GEN_INT (-INTVAL (operands[2])); 5492 return "sub{l}\t{%2, %k0|%k0, %2}"; 5493 } 5494 return "add{l}\t{%2, %k0|%k0, %2}"; 5495 } 5496} 5497 [(set (attr "type") 5498 (cond [(eq_attr "alternative" "1") 5499 (const_string "lea") 5500 ; Current assemblers are broken and do not allow @GOTOFF in 5501 ; ought but a memory context. 5502 (match_operand:SI 2 "pic_symbolic_operand" "") 5503 (const_string "lea") 5504 (match_operand:SI 2 "incdec_operand" "") 5505 (const_string "incdec") 5506 ] 5507 (const_string "alu"))) 5508 (set_attr "mode" "SI")]) 5509 5510;; Convert lea to the lea pattern to avoid flags dependency. 5511(define_split 5512 [(set (match_operand:DI 0 "register_operand" "") 5513 (zero_extend:DI 5514 (plus:SI (match_operand:SI 1 "register_operand" "") 5515 (match_operand:SI 2 "nonmemory_operand" "")))) 5516 (clobber (reg:CC FLAGS_REG))] 5517 "TARGET_64BIT && reload_completed 5518 && true_regnum (operands[0]) != true_regnum (operands[1])" 5519 [(set (match_dup 0) 5520 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))] 5521{ 5522 operands[1] = gen_lowpart (Pmode, operands[1]); 5523 operands[2] = gen_lowpart (Pmode, operands[2]); 5524}) 5525 5526(define_insn "*addsi_2" 5527 [(set (reg FLAGS_REG) 5528 (compare 5529 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 5530 (match_operand:SI 2 "general_operand" "rmni,rni")) 5531 (const_int 0))) 5532 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 5533 (plus:SI (match_dup 1) (match_dup 2)))] 5534 "ix86_match_ccmode (insn, CCGOCmode) 5535 && ix86_binary_operator_ok (PLUS, SImode, operands) 5536 /* Current assemblers are broken and do not allow @GOTOFF in 5537 ought but a memory context. */ 5538 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5539{ 5540 switch (get_attr_type (insn)) 5541 { 5542 case TYPE_INCDEC: 5543 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5544 if (operands[2] == const1_rtx) 5545 return "inc{l}\t%0"; 5546 else 5547 { 5548 gcc_assert (operands[2] == constm1_rtx); 5549 return "dec{l}\t%0"; 5550 } 5551 5552 default: 5553 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5554 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5555 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5556 if (GET_CODE (operands[2]) == CONST_INT 5557 && (INTVAL (operands[2]) == 128 5558 || (INTVAL (operands[2]) < 0 5559 && INTVAL (operands[2]) != -128))) 5560 { 5561 operands[2] = GEN_INT (-INTVAL (operands[2])); 5562 return "sub{l}\t{%2, %0|%0, %2}"; 5563 } 5564 return "add{l}\t{%2, %0|%0, %2}"; 5565 } 5566} 5567 [(set (attr "type") 5568 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5569 (const_string "incdec") 5570 (const_string "alu"))) 5571 (set_attr "mode" "SI")]) 5572 5573;; See comment for addsi_1_zext why we do use nonimmediate_operand 5574(define_insn "*addsi_2_zext" 5575 [(set (reg FLAGS_REG) 5576 (compare 5577 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 5578 (match_operand:SI 2 "general_operand" "rmni")) 5579 (const_int 0))) 5580 (set (match_operand:DI 0 "register_operand" "=r") 5581 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5582 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 5583 && ix86_binary_operator_ok (PLUS, SImode, operands) 5584 /* Current assemblers are broken and do not allow @GOTOFF in 5585 ought but a memory context. */ 5586 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5587{ 5588 switch (get_attr_type (insn)) 5589 { 5590 case TYPE_INCDEC: 5591 if (operands[2] == const1_rtx) 5592 return "inc{l}\t%k0"; 5593 else 5594 { 5595 gcc_assert (operands[2] == constm1_rtx); 5596 return "dec{l}\t%k0"; 5597 } 5598 5599 default: 5600 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5601 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5602 if (GET_CODE (operands[2]) == CONST_INT 5603 && (INTVAL (operands[2]) == 128 5604 || (INTVAL (operands[2]) < 0 5605 && INTVAL (operands[2]) != -128))) 5606 { 5607 operands[2] = GEN_INT (-INTVAL (operands[2])); 5608 return "sub{l}\t{%2, %k0|%k0, %2}"; 5609 } 5610 return "add{l}\t{%2, %k0|%k0, %2}"; 5611 } 5612} 5613 [(set (attr "type") 5614 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5615 (const_string "incdec") 5616 (const_string "alu"))) 5617 (set_attr "mode" "SI")]) 5618 5619(define_insn "*addsi_3" 5620 [(set (reg FLAGS_REG) 5621 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni")) 5622 (match_operand:SI 1 "nonimmediate_operand" "%0"))) 5623 (clobber (match_scratch:SI 0 "=r"))] 5624 "ix86_match_ccmode (insn, CCZmode) 5625 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5626 /* Current assemblers are broken and do not allow @GOTOFF in 5627 ought but a memory context. */ 5628 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5629{ 5630 switch (get_attr_type (insn)) 5631 { 5632 case TYPE_INCDEC: 5633 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5634 if (operands[2] == const1_rtx) 5635 return "inc{l}\t%0"; 5636 else 5637 { 5638 gcc_assert (operands[2] == constm1_rtx); 5639 return "dec{l}\t%0"; 5640 } 5641 5642 default: 5643 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5644 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5645 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5646 if (GET_CODE (operands[2]) == CONST_INT 5647 && (INTVAL (operands[2]) == 128 5648 || (INTVAL (operands[2]) < 0 5649 && INTVAL (operands[2]) != -128))) 5650 { 5651 operands[2] = GEN_INT (-INTVAL (operands[2])); 5652 return "sub{l}\t{%2, %0|%0, %2}"; 5653 } 5654 return "add{l}\t{%2, %0|%0, %2}"; 5655 } 5656} 5657 [(set (attr "type") 5658 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5659 (const_string "incdec") 5660 (const_string "alu"))) 5661 (set_attr "mode" "SI")]) 5662 5663;; See comment for addsi_1_zext why we do use nonimmediate_operand 5664(define_insn "*addsi_3_zext" 5665 [(set (reg FLAGS_REG) 5666 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni")) 5667 (match_operand:SI 1 "nonimmediate_operand" "%0"))) 5668 (set (match_operand:DI 0 "register_operand" "=r") 5669 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5670 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode) 5671 && ix86_binary_operator_ok (PLUS, SImode, operands) 5672 /* Current assemblers are broken and do not allow @GOTOFF in 5673 ought but a memory context. */ 5674 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5675{ 5676 switch (get_attr_type (insn)) 5677 { 5678 case TYPE_INCDEC: 5679 if (operands[2] == const1_rtx) 5680 return "inc{l}\t%k0"; 5681 else 5682 { 5683 gcc_assert (operands[2] == constm1_rtx); 5684 return "dec{l}\t%k0"; 5685 } 5686 5687 default: 5688 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5689 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5690 if (GET_CODE (operands[2]) == CONST_INT 5691 && (INTVAL (operands[2]) == 128 5692 || (INTVAL (operands[2]) < 0 5693 && INTVAL (operands[2]) != -128))) 5694 { 5695 operands[2] = GEN_INT (-INTVAL (operands[2])); 5696 return "sub{l}\t{%2, %k0|%k0, %2}"; 5697 } 5698 return "add{l}\t{%2, %k0|%k0, %2}"; 5699 } 5700} 5701 [(set (attr "type") 5702 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5703 (const_string "incdec") 5704 (const_string "alu"))) 5705 (set_attr "mode" "SI")]) 5706 5707; For comparisons against 1, -1 and 128, we may generate better code 5708; by converting cmp to add, inc or dec as done by peephole2. This pattern 5709; is matched then. We can't accept general immediate, because for 5710; case of overflows, the result is messed up. 5711; This pattern also don't hold of 0x80000000, since the value overflows 5712; when negated. 5713; Also carry flag is reversed compared to cmp, so this conversion is valid 5714; only for comparisons not depending on it. 5715(define_insn "*addsi_4" 5716 [(set (reg FLAGS_REG) 5717 (compare (match_operand:SI 1 "nonimmediate_operand" "0") 5718 (match_operand:SI 2 "const_int_operand" "n"))) 5719 (clobber (match_scratch:SI 0 "=rm"))] 5720 "ix86_match_ccmode (insn, CCGCmode) 5721 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000" 5722{ 5723 switch (get_attr_type (insn)) 5724 { 5725 case TYPE_INCDEC: 5726 if (operands[2] == constm1_rtx) 5727 return "inc{l}\t%0"; 5728 else 5729 { 5730 gcc_assert (operands[2] == const1_rtx); 5731 return "dec{l}\t%0"; 5732 } 5733 5734 default: 5735 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5736 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5737 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5738 if ((INTVAL (operands[2]) == -128 5739 || (INTVAL (operands[2]) > 0 5740 && INTVAL (operands[2]) != 128))) 5741 return "sub{l}\t{%2, %0|%0, %2}"; 5742 operands[2] = GEN_INT (-INTVAL (operands[2])); 5743 return "add{l}\t{%2, %0|%0, %2}"; 5744 } 5745} 5746 [(set (attr "type") 5747 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5748 (const_string "incdec") 5749 (const_string "alu"))) 5750 (set_attr "mode" "SI")]) 5751 5752(define_insn "*addsi_5" 5753 [(set (reg FLAGS_REG) 5754 (compare 5755 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 5756 (match_operand:SI 2 "general_operand" "rmni")) 5757 (const_int 0))) 5758 (clobber (match_scratch:SI 0 "=r"))] 5759 "ix86_match_ccmode (insn, CCGOCmode) 5760 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM) 5761 /* Current assemblers are broken and do not allow @GOTOFF in 5762 ought but a memory context. */ 5763 && ! pic_symbolic_operand (operands[2], VOIDmode)" 5764{ 5765 switch (get_attr_type (insn)) 5766 { 5767 case TYPE_INCDEC: 5768 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5769 if (operands[2] == const1_rtx) 5770 return "inc{l}\t%0"; 5771 else 5772 { 5773 gcc_assert (operands[2] == constm1_rtx); 5774 return "dec{l}\t%0"; 5775 } 5776 5777 default: 5778 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5779 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5780 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5781 if (GET_CODE (operands[2]) == CONST_INT 5782 && (INTVAL (operands[2]) == 128 5783 || (INTVAL (operands[2]) < 0 5784 && INTVAL (operands[2]) != -128))) 5785 { 5786 operands[2] = GEN_INT (-INTVAL (operands[2])); 5787 return "sub{l}\t{%2, %0|%0, %2}"; 5788 } 5789 return "add{l}\t{%2, %0|%0, %2}"; 5790 } 5791} 5792 [(set (attr "type") 5793 (if_then_else (match_operand:SI 2 "incdec_operand" "") 5794 (const_string "incdec") 5795 (const_string "alu"))) 5796 (set_attr "mode" "SI")]) 5797 5798(define_expand "addhi3" 5799 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 5800 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "") 5801 (match_operand:HI 2 "general_operand" ""))) 5802 (clobber (reg:CC FLAGS_REG))])] 5803 "TARGET_HIMODE_MATH" 5804 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;") 5805 5806;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah 5807;; type optimizations enabled by define-splits. This is not important 5808;; for PII, and in fact harmful because of partial register stalls. 5809 5810(define_insn "*addhi_1_lea" 5811 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") 5812 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r") 5813 (match_operand:HI 2 "general_operand" "ri,rm,lni"))) 5814 (clobber (reg:CC FLAGS_REG))] 5815 "!TARGET_PARTIAL_REG_STALL 5816 && ix86_binary_operator_ok (PLUS, HImode, operands)" 5817{ 5818 switch (get_attr_type (insn)) 5819 { 5820 case TYPE_LEA: 5821 return "#"; 5822 case TYPE_INCDEC: 5823 if (operands[2] == const1_rtx) 5824 return "inc{w}\t%0"; 5825 else 5826 { 5827 gcc_assert (operands[2] == constm1_rtx); 5828 return "dec{w}\t%0"; 5829 } 5830 5831 default: 5832 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5833 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5834 if (GET_CODE (operands[2]) == CONST_INT 5835 && (INTVAL (operands[2]) == 128 5836 || (INTVAL (operands[2]) < 0 5837 && INTVAL (operands[2]) != -128))) 5838 { 5839 operands[2] = GEN_INT (-INTVAL (operands[2])); 5840 return "sub{w}\t{%2, %0|%0, %2}"; 5841 } 5842 return "add{w}\t{%2, %0|%0, %2}"; 5843 } 5844} 5845 [(set (attr "type") 5846 (if_then_else (eq_attr "alternative" "2") 5847 (const_string "lea") 5848 (if_then_else (match_operand:HI 2 "incdec_operand" "") 5849 (const_string "incdec") 5850 (const_string "alu")))) 5851 (set_attr "mode" "HI,HI,SI")]) 5852 5853(define_insn "*addhi_1" 5854 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 5855 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 5856 (match_operand:HI 2 "general_operand" "ri,rm"))) 5857 (clobber (reg:CC FLAGS_REG))] 5858 "TARGET_PARTIAL_REG_STALL 5859 && ix86_binary_operator_ok (PLUS, HImode, operands)" 5860{ 5861 switch (get_attr_type (insn)) 5862 { 5863 case TYPE_INCDEC: 5864 if (operands[2] == const1_rtx) 5865 return "inc{w}\t%0"; 5866 else 5867 { 5868 gcc_assert (operands[2] == constm1_rtx); 5869 return "dec{w}\t%0"; 5870 } 5871 5872 default: 5873 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5874 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5875 if (GET_CODE (operands[2]) == CONST_INT 5876 && (INTVAL (operands[2]) == 128 5877 || (INTVAL (operands[2]) < 0 5878 && INTVAL (operands[2]) != -128))) 5879 { 5880 operands[2] = GEN_INT (-INTVAL (operands[2])); 5881 return "sub{w}\t{%2, %0|%0, %2}"; 5882 } 5883 return "add{w}\t{%2, %0|%0, %2}"; 5884 } 5885} 5886 [(set (attr "type") 5887 (if_then_else (match_operand:HI 2 "incdec_operand" "") 5888 (const_string "incdec") 5889 (const_string "alu"))) 5890 (set_attr "mode" "HI")]) 5891 5892(define_insn "*addhi_2" 5893 [(set (reg FLAGS_REG) 5894 (compare 5895 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 5896 (match_operand:HI 2 "general_operand" "rmni,rni")) 5897 (const_int 0))) 5898 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 5899 (plus:HI (match_dup 1) (match_dup 2)))] 5900 "ix86_match_ccmode (insn, CCGOCmode) 5901 && ix86_binary_operator_ok (PLUS, HImode, operands)" 5902{ 5903 switch (get_attr_type (insn)) 5904 { 5905 case TYPE_INCDEC: 5906 if (operands[2] == const1_rtx) 5907 return "inc{w}\t%0"; 5908 else 5909 { 5910 gcc_assert (operands[2] == constm1_rtx); 5911 return "dec{w}\t%0"; 5912 } 5913 5914 default: 5915 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5916 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5917 if (GET_CODE (operands[2]) == CONST_INT 5918 && (INTVAL (operands[2]) == 128 5919 || (INTVAL (operands[2]) < 0 5920 && INTVAL (operands[2]) != -128))) 5921 { 5922 operands[2] = GEN_INT (-INTVAL (operands[2])); 5923 return "sub{w}\t{%2, %0|%0, %2}"; 5924 } 5925 return "add{w}\t{%2, %0|%0, %2}"; 5926 } 5927} 5928 [(set (attr "type") 5929 (if_then_else (match_operand:HI 2 "incdec_operand" "") 5930 (const_string "incdec") 5931 (const_string "alu"))) 5932 (set_attr "mode" "HI")]) 5933 5934(define_insn "*addhi_3" 5935 [(set (reg FLAGS_REG) 5936 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni")) 5937 (match_operand:HI 1 "nonimmediate_operand" "%0"))) 5938 (clobber (match_scratch:HI 0 "=r"))] 5939 "ix86_match_ccmode (insn, CCZmode) 5940 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 5941{ 5942 switch (get_attr_type (insn)) 5943 { 5944 case TYPE_INCDEC: 5945 if (operands[2] == const1_rtx) 5946 return "inc{w}\t%0"; 5947 else 5948 { 5949 gcc_assert (operands[2] == constm1_rtx); 5950 return "dec{w}\t%0"; 5951 } 5952 5953 default: 5954 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5955 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5956 if (GET_CODE (operands[2]) == CONST_INT 5957 && (INTVAL (operands[2]) == 128 5958 || (INTVAL (operands[2]) < 0 5959 && INTVAL (operands[2]) != -128))) 5960 { 5961 operands[2] = GEN_INT (-INTVAL (operands[2])); 5962 return "sub{w}\t{%2, %0|%0, %2}"; 5963 } 5964 return "add{w}\t{%2, %0|%0, %2}"; 5965 } 5966} 5967 [(set (attr "type") 5968 (if_then_else (match_operand:HI 2 "incdec_operand" "") 5969 (const_string "incdec") 5970 (const_string "alu"))) 5971 (set_attr "mode" "HI")]) 5972 5973; See comments above addsi_4 for details. 5974(define_insn "*addhi_4" 5975 [(set (reg FLAGS_REG) 5976 (compare (match_operand:HI 1 "nonimmediate_operand" "0") 5977 (match_operand:HI 2 "const_int_operand" "n"))) 5978 (clobber (match_scratch:HI 0 "=rm"))] 5979 "ix86_match_ccmode (insn, CCGCmode) 5980 && (INTVAL (operands[2]) & 0xffff) != 0x8000" 5981{ 5982 switch (get_attr_type (insn)) 5983 { 5984 case TYPE_INCDEC: 5985 if (operands[2] == constm1_rtx) 5986 return "inc{w}\t%0"; 5987 else 5988 { 5989 gcc_assert (operands[2] == const1_rtx); 5990 return "dec{w}\t%0"; 5991 } 5992 5993 default: 5994 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5995 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 5996 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 5997 if ((INTVAL (operands[2]) == -128 5998 || (INTVAL (operands[2]) > 0 5999 && INTVAL (operands[2]) != 128))) 6000 return "sub{w}\t{%2, %0|%0, %2}"; 6001 operands[2] = GEN_INT (-INTVAL (operands[2])); 6002 return "add{w}\t{%2, %0|%0, %2}"; 6003 } 6004} 6005 [(set (attr "type") 6006 (if_then_else (match_operand:HI 2 "incdec_operand" "") 6007 (const_string "incdec") 6008 (const_string "alu"))) 6009 (set_attr "mode" "SI")]) 6010 6011 6012(define_insn "*addhi_5" 6013 [(set (reg FLAGS_REG) 6014 (compare 6015 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0") 6016 (match_operand:HI 2 "general_operand" "rmni")) 6017 (const_int 0))) 6018 (clobber (match_scratch:HI 0 "=r"))] 6019 "ix86_match_ccmode (insn, CCGOCmode) 6020 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6021{ 6022 switch (get_attr_type (insn)) 6023 { 6024 case TYPE_INCDEC: 6025 if (operands[2] == const1_rtx) 6026 return "inc{w}\t%0"; 6027 else 6028 { 6029 gcc_assert (operands[2] == constm1_rtx); 6030 return "dec{w}\t%0"; 6031 } 6032 6033 default: 6034 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 6035 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 6036 if (GET_CODE (operands[2]) == CONST_INT 6037 && (INTVAL (operands[2]) == 128 6038 || (INTVAL (operands[2]) < 0 6039 && INTVAL (operands[2]) != -128))) 6040 { 6041 operands[2] = GEN_INT (-INTVAL (operands[2])); 6042 return "sub{w}\t{%2, %0|%0, %2}"; 6043 } 6044 return "add{w}\t{%2, %0|%0, %2}"; 6045 } 6046} 6047 [(set (attr "type") 6048 (if_then_else (match_operand:HI 2 "incdec_operand" "") 6049 (const_string "incdec") 6050 (const_string "alu"))) 6051 (set_attr "mode" "HI")]) 6052 6053(define_expand "addqi3" 6054 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") 6055 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "") 6056 (match_operand:QI 2 "general_operand" ""))) 6057 (clobber (reg:CC FLAGS_REG))])] 6058 "TARGET_QIMODE_MATH" 6059 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;") 6060 6061;; %%% Potential partial reg stall on alternative 2. What to do? 6062(define_insn "*addqi_1_lea" 6063 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r") 6064 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r") 6065 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln"))) 6066 (clobber (reg:CC FLAGS_REG))] 6067 "!TARGET_PARTIAL_REG_STALL 6068 && ix86_binary_operator_ok (PLUS, QImode, operands)" 6069{ 6070 int widen = (which_alternative == 2); 6071 switch (get_attr_type (insn)) 6072 { 6073 case TYPE_LEA: 6074 return "#"; 6075 case TYPE_INCDEC: 6076 if (operands[2] == const1_rtx) 6077 return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; 6078 else 6079 { 6080 gcc_assert (operands[2] == constm1_rtx); 6081 return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; 6082 } 6083 6084 default: 6085 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 6086 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 6087 if (GET_CODE (operands[2]) == CONST_INT 6088 && (INTVAL (operands[2]) == 128 6089 || (INTVAL (operands[2]) < 0 6090 && INTVAL (operands[2]) != -128))) 6091 { 6092 operands[2] = GEN_INT (-INTVAL (operands[2])); 6093 if (widen) 6094 return "sub{l}\t{%2, %k0|%k0, %2}"; 6095 else 6096 return "sub{b}\t{%2, %0|%0, %2}"; 6097 } 6098 if (widen) 6099 return "add{l}\t{%k2, %k0|%k0, %k2}"; 6100 else 6101 return "add{b}\t{%2, %0|%0, %2}"; 6102 } 6103} 6104 [(set (attr "type") 6105 (if_then_else (eq_attr "alternative" "3") 6106 (const_string "lea") 6107 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6108 (const_string "incdec") 6109 (const_string "alu")))) 6110 (set_attr "mode" "QI,QI,SI,SI")]) 6111 6112(define_insn "*addqi_1" 6113 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 6114 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 6115 (match_operand:QI 2 "general_operand" "qn,qmn,rn"))) 6116 (clobber (reg:CC FLAGS_REG))] 6117 "TARGET_PARTIAL_REG_STALL 6118 && ix86_binary_operator_ok (PLUS, QImode, operands)" 6119{ 6120 int widen = (which_alternative == 2); 6121 switch (get_attr_type (insn)) 6122 { 6123 case TYPE_INCDEC: 6124 if (operands[2] == const1_rtx) 6125 return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; 6126 else 6127 { 6128 gcc_assert (operands[2] == constm1_rtx); 6129 return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; 6130 } 6131 6132 default: 6133 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. 6134 Exceptions: -128 encodes smaller than 128, so swap sign and op. */ 6135 if (GET_CODE (operands[2]) == CONST_INT 6136 && (INTVAL (operands[2]) == 128 6137 || (INTVAL (operands[2]) < 0 6138 && INTVAL (operands[2]) != -128))) 6139 { 6140 operands[2] = GEN_INT (-INTVAL (operands[2])); 6141 if (widen) 6142 return "sub{l}\t{%2, %k0|%k0, %2}"; 6143 else 6144 return "sub{b}\t{%2, %0|%0, %2}"; 6145 } 6146 if (widen) 6147 return "add{l}\t{%k2, %k0|%k0, %k2}"; 6148 else 6149 return "add{b}\t{%2, %0|%0, %2}"; 6150 } 6151} 6152 [(set (attr "type") 6153 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6154 (const_string "incdec") 6155 (const_string "alu"))) 6156 (set_attr "mode" "QI,QI,SI")]) 6157 6158(define_insn "*addqi_1_slp" 6159 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 6160 (plus:QI (match_dup 0) 6161 (match_operand:QI 1 "general_operand" "qn,qnm"))) 6162 (clobber (reg:CC FLAGS_REG))] 6163 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 6164 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 6165{ 6166 switch (get_attr_type (insn)) 6167 { 6168 case TYPE_INCDEC: 6169 if (operands[1] == const1_rtx) 6170 return "inc{b}\t%0"; 6171 else 6172 { 6173 gcc_assert (operands[1] == constm1_rtx); 6174 return "dec{b}\t%0"; 6175 } 6176 6177 default: 6178 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */ 6179 if (GET_CODE (operands[1]) == CONST_INT 6180 && INTVAL (operands[1]) < 0) 6181 { 6182 operands[1] = GEN_INT (-INTVAL (operands[1])); 6183 return "sub{b}\t{%1, %0|%0, %1}"; 6184 } 6185 return "add{b}\t{%1, %0|%0, %1}"; 6186 } 6187} 6188 [(set (attr "type") 6189 (if_then_else (match_operand:QI 1 "incdec_operand" "") 6190 (const_string "incdec") 6191 (const_string "alu1"))) 6192 (set (attr "memory") 6193 (if_then_else (match_operand 1 "memory_operand" "") 6194 (const_string "load") 6195 (const_string "none"))) 6196 (set_attr "mode" "QI")]) 6197 6198(define_insn "*addqi_2" 6199 [(set (reg FLAGS_REG) 6200 (compare 6201 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 6202 (match_operand:QI 2 "general_operand" "qmni,qni")) 6203 (const_int 0))) 6204 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 6205 (plus:QI (match_dup 1) (match_dup 2)))] 6206 "ix86_match_ccmode (insn, CCGOCmode) 6207 && ix86_binary_operator_ok (PLUS, QImode, operands)" 6208{ 6209 switch (get_attr_type (insn)) 6210 { 6211 case TYPE_INCDEC: 6212 if (operands[2] == const1_rtx) 6213 return "inc{b}\t%0"; 6214 else 6215 { 6216 gcc_assert (operands[2] == constm1_rtx 6217 || (GET_CODE (operands[2]) == CONST_INT 6218 && INTVAL (operands[2]) == 255)); 6219 return "dec{b}\t%0"; 6220 } 6221 6222 default: 6223 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ 6224 if (GET_CODE (operands[2]) == CONST_INT 6225 && INTVAL (operands[2]) < 0) 6226 { 6227 operands[2] = GEN_INT (-INTVAL (operands[2])); 6228 return "sub{b}\t{%2, %0|%0, %2}"; 6229 } 6230 return "add{b}\t{%2, %0|%0, %2}"; 6231 } 6232} 6233 [(set (attr "type") 6234 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6235 (const_string "incdec") 6236 (const_string "alu"))) 6237 (set_attr "mode" "QI")]) 6238 6239(define_insn "*addqi_3" 6240 [(set (reg FLAGS_REG) 6241 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni")) 6242 (match_operand:QI 1 "nonimmediate_operand" "%0"))) 6243 (clobber (match_scratch:QI 0 "=q"))] 6244 "ix86_match_ccmode (insn, CCZmode) 6245 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6246{ 6247 switch (get_attr_type (insn)) 6248 { 6249 case TYPE_INCDEC: 6250 if (operands[2] == const1_rtx) 6251 return "inc{b}\t%0"; 6252 else 6253 { 6254 gcc_assert (operands[2] == constm1_rtx 6255 || (GET_CODE (operands[2]) == CONST_INT 6256 && INTVAL (operands[2]) == 255)); 6257 return "dec{b}\t%0"; 6258 } 6259 6260 default: 6261 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ 6262 if (GET_CODE (operands[2]) == CONST_INT 6263 && INTVAL (operands[2]) < 0) 6264 { 6265 operands[2] = GEN_INT (-INTVAL (operands[2])); 6266 return "sub{b}\t{%2, %0|%0, %2}"; 6267 } 6268 return "add{b}\t{%2, %0|%0, %2}"; 6269 } 6270} 6271 [(set (attr "type") 6272 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6273 (const_string "incdec") 6274 (const_string "alu"))) 6275 (set_attr "mode" "QI")]) 6276 6277; See comments above addsi_4 for details. 6278(define_insn "*addqi_4" 6279 [(set (reg FLAGS_REG) 6280 (compare (match_operand:QI 1 "nonimmediate_operand" "0") 6281 (match_operand:QI 2 "const_int_operand" "n"))) 6282 (clobber (match_scratch:QI 0 "=qm"))] 6283 "ix86_match_ccmode (insn, CCGCmode) 6284 && (INTVAL (operands[2]) & 0xff) != 0x80" 6285{ 6286 switch (get_attr_type (insn)) 6287 { 6288 case TYPE_INCDEC: 6289 if (operands[2] == constm1_rtx 6290 || (GET_CODE (operands[2]) == CONST_INT 6291 && INTVAL (operands[2]) == 255)) 6292 return "inc{b}\t%0"; 6293 else 6294 { 6295 gcc_assert (operands[2] == const1_rtx); 6296 return "dec{b}\t%0"; 6297 } 6298 6299 default: 6300 gcc_assert (rtx_equal_p (operands[0], operands[1])); 6301 if (INTVAL (operands[2]) < 0) 6302 { 6303 operands[2] = GEN_INT (-INTVAL (operands[2])); 6304 return "add{b}\t{%2, %0|%0, %2}"; 6305 } 6306 return "sub{b}\t{%2, %0|%0, %2}"; 6307 } 6308} 6309 [(set (attr "type") 6310 (if_then_else (match_operand:HI 2 "incdec_operand" "") 6311 (const_string "incdec") 6312 (const_string "alu"))) 6313 (set_attr "mode" "QI")]) 6314 6315 6316(define_insn "*addqi_5" 6317 [(set (reg FLAGS_REG) 6318 (compare 6319 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 6320 (match_operand:QI 2 "general_operand" "qmni")) 6321 (const_int 0))) 6322 (clobber (match_scratch:QI 0 "=q"))] 6323 "ix86_match_ccmode (insn, CCGOCmode) 6324 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6325{ 6326 switch (get_attr_type (insn)) 6327 { 6328 case TYPE_INCDEC: 6329 if (operands[2] == const1_rtx) 6330 return "inc{b}\t%0"; 6331 else 6332 { 6333 gcc_assert (operands[2] == constm1_rtx 6334 || (GET_CODE (operands[2]) == CONST_INT 6335 && INTVAL (operands[2]) == 255)); 6336 return "dec{b}\t%0"; 6337 } 6338 6339 default: 6340 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */ 6341 if (GET_CODE (operands[2]) == CONST_INT 6342 && INTVAL (operands[2]) < 0) 6343 { 6344 operands[2] = GEN_INT (-INTVAL (operands[2])); 6345 return "sub{b}\t{%2, %0|%0, %2}"; 6346 } 6347 return "add{b}\t{%2, %0|%0, %2}"; 6348 } 6349} 6350 [(set (attr "type") 6351 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6352 (const_string "incdec") 6353 (const_string "alu"))) 6354 (set_attr "mode" "QI")]) 6355 6356 6357(define_insn "addqi_ext_1" 6358 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6359 (const_int 8) 6360 (const_int 8)) 6361 (plus:SI 6362 (zero_extract:SI 6363 (match_operand 1 "ext_register_operand" "0") 6364 (const_int 8) 6365 (const_int 8)) 6366 (match_operand:QI 2 "general_operand" "Qmn"))) 6367 (clobber (reg:CC FLAGS_REG))] 6368 "!TARGET_64BIT" 6369{ 6370 switch (get_attr_type (insn)) 6371 { 6372 case TYPE_INCDEC: 6373 if (operands[2] == const1_rtx) 6374 return "inc{b}\t%h0"; 6375 else 6376 { 6377 gcc_assert (operands[2] == constm1_rtx 6378 || (GET_CODE (operands[2]) == CONST_INT 6379 && INTVAL (operands[2]) == 255)); 6380 return "dec{b}\t%h0"; 6381 } 6382 6383 default: 6384 return "add{b}\t{%2, %h0|%h0, %2}"; 6385 } 6386} 6387 [(set (attr "type") 6388 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6389 (const_string "incdec") 6390 (const_string "alu"))) 6391 (set_attr "mode" "QI")]) 6392 6393(define_insn "*addqi_ext_1_rex64" 6394 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6395 (const_int 8) 6396 (const_int 8)) 6397 (plus:SI 6398 (zero_extract:SI 6399 (match_operand 1 "ext_register_operand" "0") 6400 (const_int 8) 6401 (const_int 8)) 6402 (match_operand:QI 2 "nonmemory_operand" "Qn"))) 6403 (clobber (reg:CC FLAGS_REG))] 6404 "TARGET_64BIT" 6405{ 6406 switch (get_attr_type (insn)) 6407 { 6408 case TYPE_INCDEC: 6409 if (operands[2] == const1_rtx) 6410 return "inc{b}\t%h0"; 6411 else 6412 { 6413 gcc_assert (operands[2] == constm1_rtx 6414 || (GET_CODE (operands[2]) == CONST_INT 6415 && INTVAL (operands[2]) == 255)); 6416 return "dec{b}\t%h0"; 6417 } 6418 6419 default: 6420 return "add{b}\t{%2, %h0|%h0, %2}"; 6421 } 6422} 6423 [(set (attr "type") 6424 (if_then_else (match_operand:QI 2 "incdec_operand" "") 6425 (const_string "incdec") 6426 (const_string "alu"))) 6427 (set_attr "mode" "QI")]) 6428 6429(define_insn "*addqi_ext_2" 6430 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 6431 (const_int 8) 6432 (const_int 8)) 6433 (plus:SI 6434 (zero_extract:SI 6435 (match_operand 1 "ext_register_operand" "%0") 6436 (const_int 8) 6437 (const_int 8)) 6438 (zero_extract:SI 6439 (match_operand 2 "ext_register_operand" "Q") 6440 (const_int 8) 6441 (const_int 8)))) 6442 (clobber (reg:CC FLAGS_REG))] 6443 "" 6444 "add{b}\t{%h2, %h0|%h0, %h2}" 6445 [(set_attr "type" "alu") 6446 (set_attr "mode" "QI")]) 6447 6448;; The patterns that match these are at the end of this file. 6449 6450(define_expand "addxf3" 6451 [(set (match_operand:XF 0 "register_operand" "") 6452 (plus:XF (match_operand:XF 1 "register_operand" "") 6453 (match_operand:XF 2 "register_operand" "")))] 6454 "TARGET_80387" 6455 "") 6456 6457(define_expand "adddf3" 6458 [(set (match_operand:DF 0 "register_operand" "") 6459 (plus:DF (match_operand:DF 1 "register_operand" "") 6460 (match_operand:DF 2 "nonimmediate_operand" "")))] 6461 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 6462 "") 6463 6464(define_expand "addsf3" 6465 [(set (match_operand:SF 0 "register_operand" "") 6466 (plus:SF (match_operand:SF 1 "register_operand" "") 6467 (match_operand:SF 2 "nonimmediate_operand" "")))] 6468 "TARGET_80387 || TARGET_SSE_MATH" 6469 "") 6470 6471;; Subtract instructions 6472 6473;; %%% splits for subditi3 6474 6475(define_expand "subti3" 6476 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "") 6477 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "") 6478 (match_operand:TI 2 "x86_64_general_operand" ""))) 6479 (clobber (reg:CC FLAGS_REG))])] 6480 "TARGET_64BIT" 6481 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;") 6482 6483(define_insn "*subti3_1" 6484 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o") 6485 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0") 6486 (match_operand:TI 2 "x86_64_general_operand" "roe,re"))) 6487 (clobber (reg:CC FLAGS_REG))] 6488 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)" 6489 "#") 6490 6491(define_split 6492 [(set (match_operand:TI 0 "nonimmediate_operand" "") 6493 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "") 6494 (match_operand:TI 2 "x86_64_general_operand" ""))) 6495 (clobber (reg:CC FLAGS_REG))] 6496 "TARGET_64BIT && reload_completed" 6497 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2))) 6498 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))]) 6499 (parallel [(set (match_dup 3) 6500 (minus:DI (match_dup 4) 6501 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) 6502 (match_dup 5)))) 6503 (clobber (reg:CC FLAGS_REG))])] 6504 "split_ti (operands+0, 1, operands+0, operands+3); 6505 split_ti (operands+1, 1, operands+1, operands+4); 6506 split_ti (operands+2, 1, operands+2, operands+5);") 6507 6508;; %%% splits for subsidi3 6509 6510(define_expand "subdi3" 6511 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 6512 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "") 6513 (match_operand:DI 2 "x86_64_general_operand" ""))) 6514 (clobber (reg:CC FLAGS_REG))])] 6515 "" 6516 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;") 6517 6518(define_insn "*subdi3_1" 6519 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o") 6520 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6521 (match_operand:DI 2 "general_operand" "roiF,riF"))) 6522 (clobber (reg:CC FLAGS_REG))] 6523 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" 6524 "#") 6525 6526(define_split 6527 [(set (match_operand:DI 0 "nonimmediate_operand" "") 6528 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "") 6529 (match_operand:DI 2 "general_operand" ""))) 6530 (clobber (reg:CC FLAGS_REG))] 6531 "!TARGET_64BIT && reload_completed" 6532 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2))) 6533 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 6534 (parallel [(set (match_dup 3) 6535 (minus:SI (match_dup 4) 6536 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) 6537 (match_dup 5)))) 6538 (clobber (reg:CC FLAGS_REG))])] 6539 "split_di (operands+0, 1, operands+0, operands+3); 6540 split_di (operands+1, 1, operands+1, operands+4); 6541 split_di (operands+2, 1, operands+2, operands+5);") 6542 6543(define_insn "subdi3_carry_rex64" 6544 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6545 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6546 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "") 6547 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))) 6548 (clobber (reg:CC FLAGS_REG))] 6549 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" 6550 "sbb{q}\t{%2, %0|%0, %2}" 6551 [(set_attr "type" "alu") 6552 (set_attr "pent_pair" "pu") 6553 (set_attr "mode" "DI")]) 6554 6555(define_insn "*subdi_1_rex64" 6556 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6557 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6558 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 6559 (clobber (reg:CC FLAGS_REG))] 6560 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)" 6561 "sub{q}\t{%2, %0|%0, %2}" 6562 [(set_attr "type" "alu") 6563 (set_attr "mode" "DI")]) 6564 6565(define_insn "*subdi_2_rex64" 6566 [(set (reg FLAGS_REG) 6567 (compare 6568 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 6569 (match_operand:DI 2 "x86_64_general_operand" "re,rm")) 6570 (const_int 0))) 6571 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6572 (minus:DI (match_dup 1) (match_dup 2)))] 6573 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 6574 && ix86_binary_operator_ok (MINUS, DImode, operands)" 6575 "sub{q}\t{%2, %0|%0, %2}" 6576 [(set_attr "type" "alu") 6577 (set_attr "mode" "DI")]) 6578 6579(define_insn "*subdi_3_rex63" 6580 [(set (reg FLAGS_REG) 6581 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0") 6582 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 6583 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 6584 (minus:DI (match_dup 1) (match_dup 2)))] 6585 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 6586 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6587 "sub{q}\t{%2, %0|%0, %2}" 6588 [(set_attr "type" "alu") 6589 (set_attr "mode" "DI")]) 6590 6591(define_insn "subqi3_carry" 6592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 6593 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 6594 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "") 6595 (match_operand:QI 2 "general_operand" "qi,qm")))) 6596 (clobber (reg:CC FLAGS_REG))] 6597 "ix86_binary_operator_ok (MINUS, QImode, operands)" 6598 "sbb{b}\t{%2, %0|%0, %2}" 6599 [(set_attr "type" "alu") 6600 (set_attr "pent_pair" "pu") 6601 (set_attr "mode" "QI")]) 6602 6603(define_insn "subhi3_carry" 6604 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6605 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 6606 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "") 6607 (match_operand:HI 2 "general_operand" "ri,rm")))) 6608 (clobber (reg:CC FLAGS_REG))] 6609 "ix86_binary_operator_ok (MINUS, HImode, operands)" 6610 "sbb{w}\t{%2, %0|%0, %2}" 6611 [(set_attr "type" "alu") 6612 (set_attr "pent_pair" "pu") 6613 (set_attr "mode" "HI")]) 6614 6615(define_insn "subsi3_carry" 6616 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6617 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6618 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 6619 (match_operand:SI 2 "general_operand" "ri,rm")))) 6620 (clobber (reg:CC FLAGS_REG))] 6621 "ix86_binary_operator_ok (MINUS, SImode, operands)" 6622 "sbb{l}\t{%2, %0|%0, %2}" 6623 [(set_attr "type" "alu") 6624 (set_attr "pent_pair" "pu") 6625 (set_attr "mode" "SI")]) 6626 6627(define_insn "subsi3_carry_zext" 6628 [(set (match_operand:DI 0 "register_operand" "=rm,r") 6629 (zero_extend:DI 6630 (minus:SI (match_operand:SI 1 "register_operand" "0,0") 6631 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "") 6632 (match_operand:SI 2 "general_operand" "ri,rm"))))) 6633 (clobber (reg:CC FLAGS_REG))] 6634 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6635 "sbb{l}\t{%2, %k0|%k0, %2}" 6636 [(set_attr "type" "alu") 6637 (set_attr "pent_pair" "pu") 6638 (set_attr "mode" "SI")]) 6639 6640(define_expand "subsi3" 6641 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 6642 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "") 6643 (match_operand:SI 2 "general_operand" ""))) 6644 (clobber (reg:CC FLAGS_REG))])] 6645 "" 6646 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;") 6647 6648(define_insn "*subsi_1" 6649 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6650 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6651 (match_operand:SI 2 "general_operand" "ri,rm"))) 6652 (clobber (reg:CC FLAGS_REG))] 6653 "ix86_binary_operator_ok (MINUS, SImode, operands)" 6654 "sub{l}\t{%2, %0|%0, %2}" 6655 [(set_attr "type" "alu") 6656 (set_attr "mode" "SI")]) 6657 6658(define_insn "*subsi_1_zext" 6659 [(set (match_operand:DI 0 "register_operand" "=r") 6660 (zero_extend:DI 6661 (minus:SI (match_operand:SI 1 "register_operand" "0") 6662 (match_operand:SI 2 "general_operand" "rim")))) 6663 (clobber (reg:CC FLAGS_REG))] 6664 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6665 "sub{l}\t{%2, %k0|%k0, %2}" 6666 [(set_attr "type" "alu") 6667 (set_attr "mode" "SI")]) 6668 6669(define_insn "*subsi_2" 6670 [(set (reg FLAGS_REG) 6671 (compare 6672 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6673 (match_operand:SI 2 "general_operand" "ri,rm")) 6674 (const_int 0))) 6675 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6676 (minus:SI (match_dup 1) (match_dup 2)))] 6677 "ix86_match_ccmode (insn, CCGOCmode) 6678 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6679 "sub{l}\t{%2, %0|%0, %2}" 6680 [(set_attr "type" "alu") 6681 (set_attr "mode" "SI")]) 6682 6683(define_insn "*subsi_2_zext" 6684 [(set (reg FLAGS_REG) 6685 (compare 6686 (minus:SI (match_operand:SI 1 "register_operand" "0") 6687 (match_operand:SI 2 "general_operand" "rim")) 6688 (const_int 0))) 6689 (set (match_operand:DI 0 "register_operand" "=r") 6690 (zero_extend:DI 6691 (minus:SI (match_dup 1) 6692 (match_dup 2))))] 6693 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 6694 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6695 "sub{l}\t{%2, %k0|%k0, %2}" 6696 [(set_attr "type" "alu") 6697 (set_attr "mode" "SI")]) 6698 6699(define_insn "*subsi_3" 6700 [(set (reg FLAGS_REG) 6701 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0") 6702 (match_operand:SI 2 "general_operand" "ri,rm"))) 6703 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 6704 (minus:SI (match_dup 1) (match_dup 2)))] 6705 "ix86_match_ccmode (insn, CCmode) 6706 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6707 "sub{l}\t{%2, %0|%0, %2}" 6708 [(set_attr "type" "alu") 6709 (set_attr "mode" "SI")]) 6710 6711(define_insn "*subsi_3_zext" 6712 [(set (reg FLAGS_REG) 6713 (compare (match_operand:SI 1 "register_operand" "0") 6714 (match_operand:SI 2 "general_operand" "rim"))) 6715 (set (match_operand:DI 0 "register_operand" "=r") 6716 (zero_extend:DI 6717 (minus:SI (match_dup 1) 6718 (match_dup 2))))] 6719 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 6720 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6721 "sub{l}\t{%2, %1|%1, %2}" 6722 [(set_attr "type" "alu") 6723 (set_attr "mode" "DI")]) 6724 6725(define_expand "subhi3" 6726 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 6727 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "") 6728 (match_operand:HI 2 "general_operand" ""))) 6729 (clobber (reg:CC FLAGS_REG))])] 6730 "TARGET_HIMODE_MATH" 6731 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;") 6732 6733(define_insn "*subhi_1" 6734 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6735 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 6736 (match_operand:HI 2 "general_operand" "ri,rm"))) 6737 (clobber (reg:CC FLAGS_REG))] 6738 "ix86_binary_operator_ok (MINUS, HImode, operands)" 6739 "sub{w}\t{%2, %0|%0, %2}" 6740 [(set_attr "type" "alu") 6741 (set_attr "mode" "HI")]) 6742 6743(define_insn "*subhi_2" 6744 [(set (reg FLAGS_REG) 6745 (compare 6746 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 6747 (match_operand:HI 2 "general_operand" "ri,rm")) 6748 (const_int 0))) 6749 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6750 (minus:HI (match_dup 1) (match_dup 2)))] 6751 "ix86_match_ccmode (insn, CCGOCmode) 6752 && ix86_binary_operator_ok (MINUS, HImode, operands)" 6753 "sub{w}\t{%2, %0|%0, %2}" 6754 [(set_attr "type" "alu") 6755 (set_attr "mode" "HI")]) 6756 6757(define_insn "*subhi_3" 6758 [(set (reg FLAGS_REG) 6759 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0") 6760 (match_operand:HI 2 "general_operand" "ri,rm"))) 6761 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 6762 (minus:HI (match_dup 1) (match_dup 2)))] 6763 "ix86_match_ccmode (insn, CCmode) 6764 && ix86_binary_operator_ok (MINUS, HImode, operands)" 6765 "sub{w}\t{%2, %0|%0, %2}" 6766 [(set_attr "type" "alu") 6767 (set_attr "mode" "HI")]) 6768 6769(define_expand "subqi3" 6770 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") 6771 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "") 6772 (match_operand:QI 2 "general_operand" ""))) 6773 (clobber (reg:CC FLAGS_REG))])] 6774 "TARGET_QIMODE_MATH" 6775 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;") 6776 6777(define_insn "*subqi_1" 6778 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 6779 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 6780 (match_operand:QI 2 "general_operand" "qn,qmn"))) 6781 (clobber (reg:CC FLAGS_REG))] 6782 "ix86_binary_operator_ok (MINUS, QImode, operands)" 6783 "sub{b}\t{%2, %0|%0, %2}" 6784 [(set_attr "type" "alu") 6785 (set_attr "mode" "QI")]) 6786 6787(define_insn "*subqi_1_slp" 6788 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 6789 (minus:QI (match_dup 0) 6790 (match_operand:QI 1 "general_operand" "qn,qmn"))) 6791 (clobber (reg:CC FLAGS_REG))] 6792 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 6793 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 6794 "sub{b}\t{%1, %0|%0, %1}" 6795 [(set_attr "type" "alu1") 6796 (set_attr "mode" "QI")]) 6797 6798(define_insn "*subqi_2" 6799 [(set (reg FLAGS_REG) 6800 (compare 6801 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 6802 (match_operand:QI 2 "general_operand" "qi,qm")) 6803 (const_int 0))) 6804 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q") 6805 (minus:HI (match_dup 1) (match_dup 2)))] 6806 "ix86_match_ccmode (insn, CCGOCmode) 6807 && ix86_binary_operator_ok (MINUS, QImode, operands)" 6808 "sub{b}\t{%2, %0|%0, %2}" 6809 [(set_attr "type" "alu") 6810 (set_attr "mode" "QI")]) 6811 6812(define_insn "*subqi_3" 6813 [(set (reg FLAGS_REG) 6814 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0") 6815 (match_operand:QI 2 "general_operand" "qi,qm"))) 6816 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q") 6817 (minus:HI (match_dup 1) (match_dup 2)))] 6818 "ix86_match_ccmode (insn, CCmode) 6819 && ix86_binary_operator_ok (MINUS, QImode, operands)" 6820 "sub{b}\t{%2, %0|%0, %2}" 6821 [(set_attr "type" "alu") 6822 (set_attr "mode" "QI")]) 6823 6824;; The patterns that match these are at the end of this file. 6825 6826(define_expand "subxf3" 6827 [(set (match_operand:XF 0 "register_operand" "") 6828 (minus:XF (match_operand:XF 1 "register_operand" "") 6829 (match_operand:XF 2 "register_operand" "")))] 6830 "TARGET_80387" 6831 "") 6832 6833(define_expand "subdf3" 6834 [(set (match_operand:DF 0 "register_operand" "") 6835 (minus:DF (match_operand:DF 1 "register_operand" "") 6836 (match_operand:DF 2 "nonimmediate_operand" "")))] 6837 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 6838 "") 6839 6840(define_expand "subsf3" 6841 [(set (match_operand:SF 0 "register_operand" "") 6842 (minus:SF (match_operand:SF 1 "register_operand" "") 6843 (match_operand:SF 2 "nonimmediate_operand" "")))] 6844 "TARGET_80387 || TARGET_SSE_MATH" 6845 "") 6846 6847;; Multiply instructions 6848 6849(define_expand "muldi3" 6850 [(parallel [(set (match_operand:DI 0 "register_operand" "") 6851 (mult:DI (match_operand:DI 1 "register_operand" "") 6852 (match_operand:DI 2 "x86_64_general_operand" ""))) 6853 (clobber (reg:CC FLAGS_REG))])] 6854 "TARGET_64BIT" 6855 "") 6856 6857(define_insn "*muldi3_1_rex64" 6858 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 6859 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0") 6860 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr"))) 6861 (clobber (reg:CC FLAGS_REG))] 6862 "TARGET_64BIT 6863 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6864 "@ 6865 imul{q}\t{%2, %1, %0|%0, %1, %2} 6866 imul{q}\t{%2, %1, %0|%0, %1, %2} 6867 imul{q}\t{%2, %0|%0, %2}" 6868 [(set_attr "type" "imul") 6869 (set_attr "prefix_0f" "0,0,1") 6870 (set (attr "athlon_decode") 6871 (cond [(eq_attr "cpu" "athlon") 6872 (const_string "vector") 6873 (eq_attr "alternative" "1") 6874 (const_string "vector") 6875 (and (eq_attr "alternative" "2") 6876 (match_operand 1 "memory_operand" "")) 6877 (const_string "vector")] 6878 (const_string "direct"))) 6879 (set_attr "mode" "DI")]) 6880 6881(define_expand "mulsi3" 6882 [(parallel [(set (match_operand:SI 0 "register_operand" "") 6883 (mult:SI (match_operand:SI 1 "register_operand" "") 6884 (match_operand:SI 2 "general_operand" ""))) 6885 (clobber (reg:CC FLAGS_REG))])] 6886 "" 6887 "") 6888 6889(define_insn "*mulsi3_1" 6890 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 6891 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") 6892 (match_operand:SI 2 "general_operand" "K,i,mr"))) 6893 (clobber (reg:CC FLAGS_REG))] 6894 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 6895 "@ 6896 imul{l}\t{%2, %1, %0|%0, %1, %2} 6897 imul{l}\t{%2, %1, %0|%0, %1, %2} 6898 imul{l}\t{%2, %0|%0, %2}" 6899 [(set_attr "type" "imul") 6900 (set_attr "prefix_0f" "0,0,1") 6901 (set (attr "athlon_decode") 6902 (cond [(eq_attr "cpu" "athlon") 6903 (const_string "vector") 6904 (eq_attr "alternative" "1") 6905 (const_string "vector") 6906 (and (eq_attr "alternative" "2") 6907 (match_operand 1 "memory_operand" "")) 6908 (const_string "vector")] 6909 (const_string "direct"))) 6910 (set_attr "mode" "SI")]) 6911 6912(define_insn "*mulsi3_1_zext" 6913 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 6914 (zero_extend:DI 6915 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") 6916 (match_operand:SI 2 "general_operand" "K,i,mr")))) 6917 (clobber (reg:CC FLAGS_REG))] 6918 "TARGET_64BIT 6919 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6920 "@ 6921 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6922 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6923 imul{l}\t{%2, %k0|%k0, %2}" 6924 [(set_attr "type" "imul") 6925 (set_attr "prefix_0f" "0,0,1") 6926 (set (attr "athlon_decode") 6927 (cond [(eq_attr "cpu" "athlon") 6928 (const_string "vector") 6929 (eq_attr "alternative" "1") 6930 (const_string "vector") 6931 (and (eq_attr "alternative" "2") 6932 (match_operand 1 "memory_operand" "")) 6933 (const_string "vector")] 6934 (const_string "direct"))) 6935 (set_attr "mode" "SI")]) 6936 6937(define_expand "mulhi3" 6938 [(parallel [(set (match_operand:HI 0 "register_operand" "") 6939 (mult:HI (match_operand:HI 1 "register_operand" "") 6940 (match_operand:HI 2 "general_operand" ""))) 6941 (clobber (reg:CC FLAGS_REG))])] 6942 "TARGET_HIMODE_MATH" 6943 "") 6944 6945(define_insn "*mulhi3_1" 6946 [(set (match_operand:HI 0 "register_operand" "=r,r,r") 6947 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0") 6948 (match_operand:HI 2 "general_operand" "K,i,mr"))) 6949 (clobber (reg:CC FLAGS_REG))] 6950 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 6951 "@ 6952 imul{w}\t{%2, %1, %0|%0, %1, %2} 6953 imul{w}\t{%2, %1, %0|%0, %1, %2} 6954 imul{w}\t{%2, %0|%0, %2}" 6955 [(set_attr "type" "imul") 6956 (set_attr "prefix_0f" "0,0,1") 6957 (set (attr "athlon_decode") 6958 (cond [(eq_attr "cpu" "athlon") 6959 (const_string "vector") 6960 (eq_attr "alternative" "1,2") 6961 (const_string "vector")] 6962 (const_string "direct"))) 6963 (set_attr "mode" "HI")]) 6964 6965(define_expand "mulqi3" 6966 [(parallel [(set (match_operand:QI 0 "register_operand" "") 6967 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "") 6968 (match_operand:QI 2 "register_operand" ""))) 6969 (clobber (reg:CC FLAGS_REG))])] 6970 "TARGET_QIMODE_MATH" 6971 "") 6972 6973(define_insn "*mulqi3_1" 6974 [(set (match_operand:QI 0 "register_operand" "=a") 6975 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 6976 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 6977 (clobber (reg:CC FLAGS_REG))] 6978 "TARGET_QIMODE_MATH 6979 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 6980 "mul{b}\t%2" 6981 [(set_attr "type" "imul") 6982 (set_attr "length_immediate" "0") 6983 (set (attr "athlon_decode") 6984 (if_then_else (eq_attr "cpu" "athlon") 6985 (const_string "vector") 6986 (const_string "direct"))) 6987 (set_attr "mode" "QI")]) 6988 6989(define_expand "umulqihi3" 6990 [(parallel [(set (match_operand:HI 0 "register_operand" "") 6991 (mult:HI (zero_extend:HI 6992 (match_operand:QI 1 "nonimmediate_operand" "")) 6993 (zero_extend:HI 6994 (match_operand:QI 2 "register_operand" "")))) 6995 (clobber (reg:CC FLAGS_REG))])] 6996 "TARGET_QIMODE_MATH" 6997 "") 6998 6999(define_insn "*umulqihi3_1" 7000 [(set (match_operand:HI 0 "register_operand" "=a") 7001 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0")) 7002 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm")))) 7003 (clobber (reg:CC FLAGS_REG))] 7004 "TARGET_QIMODE_MATH 7005 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7006 "mul{b}\t%2" 7007 [(set_attr "type" "imul") 7008 (set_attr "length_immediate" "0") 7009 (set (attr "athlon_decode") 7010 (if_then_else (eq_attr "cpu" "athlon") 7011 (const_string "vector") 7012 (const_string "direct"))) 7013 (set_attr "mode" "QI")]) 7014 7015(define_expand "mulqihi3" 7016 [(parallel [(set (match_operand:HI 0 "register_operand" "") 7017 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")) 7018 (sign_extend:HI (match_operand:QI 2 "register_operand" "")))) 7019 (clobber (reg:CC FLAGS_REG))])] 7020 "TARGET_QIMODE_MATH" 7021 "") 7022 7023(define_insn "*mulqihi3_insn" 7024 [(set (match_operand:HI 0 "register_operand" "=a") 7025 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0")) 7026 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm")))) 7027 (clobber (reg:CC FLAGS_REG))] 7028 "TARGET_QIMODE_MATH 7029 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7030 "imul{b}\t%2" 7031 [(set_attr "type" "imul") 7032 (set_attr "length_immediate" "0") 7033 (set (attr "athlon_decode") 7034 (if_then_else (eq_attr "cpu" "athlon") 7035 (const_string "vector") 7036 (const_string "direct"))) 7037 (set_attr "mode" "QI")]) 7038 7039(define_expand "umulditi3" 7040 [(parallel [(set (match_operand:TI 0 "register_operand" "") 7041 (mult:TI (zero_extend:TI 7042 (match_operand:DI 1 "nonimmediate_operand" "")) 7043 (zero_extend:TI 7044 (match_operand:DI 2 "register_operand" "")))) 7045 (clobber (reg:CC FLAGS_REG))])] 7046 "TARGET_64BIT" 7047 "") 7048 7049(define_insn "*umulditi3_insn" 7050 [(set (match_operand:TI 0 "register_operand" "=A") 7051 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0")) 7052 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm")))) 7053 (clobber (reg:CC FLAGS_REG))] 7054 "TARGET_64BIT 7055 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7056 "mul{q}\t%2" 7057 [(set_attr "type" "imul") 7058 (set_attr "length_immediate" "0") 7059 (set (attr "athlon_decode") 7060 (if_then_else (eq_attr "cpu" "athlon") 7061 (const_string "vector") 7062 (const_string "double"))) 7063 (set_attr "mode" "DI")]) 7064 7065;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers 7066(define_expand "umulsidi3" 7067 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7068 (mult:DI (zero_extend:DI 7069 (match_operand:SI 1 "nonimmediate_operand" "")) 7070 (zero_extend:DI 7071 (match_operand:SI 2 "register_operand" "")))) 7072 (clobber (reg:CC FLAGS_REG))])] 7073 "!TARGET_64BIT" 7074 "") 7075 7076(define_insn "*umulsidi3_insn" 7077 [(set (match_operand:DI 0 "register_operand" "=A") 7078 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0")) 7079 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))) 7080 (clobber (reg:CC FLAGS_REG))] 7081 "!TARGET_64BIT 7082 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7083 "mul{l}\t%2" 7084 [(set_attr "type" "imul") 7085 (set_attr "length_immediate" "0") 7086 (set (attr "athlon_decode") 7087 (if_then_else (eq_attr "cpu" "athlon") 7088 (const_string "vector") 7089 (const_string "double"))) 7090 (set_attr "mode" "SI")]) 7091 7092(define_expand "mulditi3" 7093 [(parallel [(set (match_operand:TI 0 "register_operand" "") 7094 (mult:TI (sign_extend:TI 7095 (match_operand:DI 1 "nonimmediate_operand" "")) 7096 (sign_extend:TI 7097 (match_operand:DI 2 "register_operand" "")))) 7098 (clobber (reg:CC FLAGS_REG))])] 7099 "TARGET_64BIT" 7100 "") 7101 7102(define_insn "*mulditi3_insn" 7103 [(set (match_operand:TI 0 "register_operand" "=A") 7104 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0")) 7105 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm")))) 7106 (clobber (reg:CC FLAGS_REG))] 7107 "TARGET_64BIT 7108 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7109 "imul{q}\t%2" 7110 [(set_attr "type" "imul") 7111 (set_attr "length_immediate" "0") 7112 (set (attr "athlon_decode") 7113 (if_then_else (eq_attr "cpu" "athlon") 7114 (const_string "vector") 7115 (const_string "double"))) 7116 (set_attr "mode" "DI")]) 7117 7118(define_expand "mulsidi3" 7119 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7120 (mult:DI (sign_extend:DI 7121 (match_operand:SI 1 "nonimmediate_operand" "")) 7122 (sign_extend:DI 7123 (match_operand:SI 2 "register_operand" "")))) 7124 (clobber (reg:CC FLAGS_REG))])] 7125 "!TARGET_64BIT" 7126 "") 7127 7128(define_insn "*mulsidi3_insn" 7129 [(set (match_operand:DI 0 "register_operand" "=A") 7130 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0")) 7131 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm")))) 7132 (clobber (reg:CC FLAGS_REG))] 7133 "!TARGET_64BIT 7134 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7135 "imul{l}\t%2" 7136 [(set_attr "type" "imul") 7137 (set_attr "length_immediate" "0") 7138 (set (attr "athlon_decode") 7139 (if_then_else (eq_attr "cpu" "athlon") 7140 (const_string "vector") 7141 (const_string "double"))) 7142 (set_attr "mode" "SI")]) 7143 7144(define_expand "umuldi3_highpart" 7145 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7146 (truncate:DI 7147 (lshiftrt:TI 7148 (mult:TI (zero_extend:TI 7149 (match_operand:DI 1 "nonimmediate_operand" "")) 7150 (zero_extend:TI 7151 (match_operand:DI 2 "register_operand" ""))) 7152 (const_int 64)))) 7153 (clobber (match_scratch:DI 3 "")) 7154 (clobber (reg:CC FLAGS_REG))])] 7155 "TARGET_64BIT" 7156 "") 7157 7158(define_insn "*umuldi3_highpart_rex64" 7159 [(set (match_operand:DI 0 "register_operand" "=d") 7160 (truncate:DI 7161 (lshiftrt:TI 7162 (mult:TI (zero_extend:TI 7163 (match_operand:DI 1 "nonimmediate_operand" "%a")) 7164 (zero_extend:TI 7165 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7166 (const_int 64)))) 7167 (clobber (match_scratch:DI 3 "=1")) 7168 (clobber (reg:CC FLAGS_REG))] 7169 "TARGET_64BIT 7170 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7171 "mul{q}\t%2" 7172 [(set_attr "type" "imul") 7173 (set_attr "length_immediate" "0") 7174 (set (attr "athlon_decode") 7175 (if_then_else (eq_attr "cpu" "athlon") 7176 (const_string "vector") 7177 (const_string "double"))) 7178 (set_attr "mode" "DI")]) 7179 7180(define_expand "umulsi3_highpart" 7181 [(parallel [(set (match_operand:SI 0 "register_operand" "") 7182 (truncate:SI 7183 (lshiftrt:DI 7184 (mult:DI (zero_extend:DI 7185 (match_operand:SI 1 "nonimmediate_operand" "")) 7186 (zero_extend:DI 7187 (match_operand:SI 2 "register_operand" ""))) 7188 (const_int 32)))) 7189 (clobber (match_scratch:SI 3 "")) 7190 (clobber (reg:CC FLAGS_REG))])] 7191 "" 7192 "") 7193 7194(define_insn "*umulsi3_highpart_insn" 7195 [(set (match_operand:SI 0 "register_operand" "=d") 7196 (truncate:SI 7197 (lshiftrt:DI 7198 (mult:DI (zero_extend:DI 7199 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7200 (zero_extend:DI 7201 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7202 (const_int 32)))) 7203 (clobber (match_scratch:SI 3 "=1")) 7204 (clobber (reg:CC FLAGS_REG))] 7205 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 7206 "mul{l}\t%2" 7207 [(set_attr "type" "imul") 7208 (set_attr "length_immediate" "0") 7209 (set (attr "athlon_decode") 7210 (if_then_else (eq_attr "cpu" "athlon") 7211 (const_string "vector") 7212 (const_string "double"))) 7213 (set_attr "mode" "SI")]) 7214 7215(define_insn "*umulsi3_highpart_zext" 7216 [(set (match_operand:DI 0 "register_operand" "=d") 7217 (zero_extend:DI (truncate:SI 7218 (lshiftrt:DI 7219 (mult:DI (zero_extend:DI 7220 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7221 (zero_extend:DI 7222 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7223 (const_int 32))))) 7224 (clobber (match_scratch:SI 3 "=1")) 7225 (clobber (reg:CC FLAGS_REG))] 7226 "TARGET_64BIT 7227 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7228 "mul{l}\t%2" 7229 [(set_attr "type" "imul") 7230 (set_attr "length_immediate" "0") 7231 (set (attr "athlon_decode") 7232 (if_then_else (eq_attr "cpu" "athlon") 7233 (const_string "vector") 7234 (const_string "double"))) 7235 (set_attr "mode" "SI")]) 7236 7237(define_expand "smuldi3_highpart" 7238 [(parallel [(set (match_operand:DI 0 "register_operand" "=d") 7239 (truncate:DI 7240 (lshiftrt:TI 7241 (mult:TI (sign_extend:TI 7242 (match_operand:DI 1 "nonimmediate_operand" "")) 7243 (sign_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 "*smuldi3_highpart_rex64" 7252 [(set (match_operand:DI 0 "register_operand" "=d") 7253 (truncate:DI 7254 (lshiftrt:TI 7255 (mult:TI (sign_extend:TI 7256 (match_operand:DI 1 "nonimmediate_operand" "%a")) 7257 (sign_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 "imul{q}\t%2" 7265 [(set_attr "type" "imul") 7266 (set (attr "athlon_decode") 7267 (if_then_else (eq_attr "cpu" "athlon") 7268 (const_string "vector") 7269 (const_string "double"))) 7270 (set_attr "mode" "DI")]) 7271 7272(define_expand "smulsi3_highpart" 7273 [(parallel [(set (match_operand:SI 0 "register_operand" "") 7274 (truncate:SI 7275 (lshiftrt:DI 7276 (mult:DI (sign_extend:DI 7277 (match_operand:SI 1 "nonimmediate_operand" "")) 7278 (sign_extend:DI 7279 (match_operand:SI 2 "register_operand" ""))) 7280 (const_int 32)))) 7281 (clobber (match_scratch:SI 3 "")) 7282 (clobber (reg:CC FLAGS_REG))])] 7283 "" 7284 "") 7285 7286(define_insn "*smulsi3_highpart_insn" 7287 [(set (match_operand:SI 0 "register_operand" "=d") 7288 (truncate:SI 7289 (lshiftrt:DI 7290 (mult:DI (sign_extend:DI 7291 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7292 (sign_extend:DI 7293 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7294 (const_int 32)))) 7295 (clobber (match_scratch:SI 3 "=1")) 7296 (clobber (reg:CC FLAGS_REG))] 7297 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM" 7298 "imul{l}\t%2" 7299 [(set_attr "type" "imul") 7300 (set (attr "athlon_decode") 7301 (if_then_else (eq_attr "cpu" "athlon") 7302 (const_string "vector") 7303 (const_string "double"))) 7304 (set_attr "mode" "SI")]) 7305 7306(define_insn "*smulsi3_highpart_zext" 7307 [(set (match_operand:DI 0 "register_operand" "=d") 7308 (zero_extend:DI (truncate:SI 7309 (lshiftrt:DI 7310 (mult:DI (sign_extend:DI 7311 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7312 (sign_extend:DI 7313 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7314 (const_int 32))))) 7315 (clobber (match_scratch:SI 3 "=1")) 7316 (clobber (reg:CC FLAGS_REG))] 7317 "TARGET_64BIT 7318 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 7319 "imul{l}\t%2" 7320 [(set_attr "type" "imul") 7321 (set (attr "athlon_decode") 7322 (if_then_else (eq_attr "cpu" "athlon") 7323 (const_string "vector") 7324 (const_string "double"))) 7325 (set_attr "mode" "SI")]) 7326 7327;; The patterns that match these are at the end of this file. 7328 7329(define_expand "mulxf3" 7330 [(set (match_operand:XF 0 "register_operand" "") 7331 (mult:XF (match_operand:XF 1 "register_operand" "") 7332 (match_operand:XF 2 "register_operand" "")))] 7333 "TARGET_80387" 7334 "") 7335 7336(define_expand "muldf3" 7337 [(set (match_operand:DF 0 "register_operand" "") 7338 (mult:DF (match_operand:DF 1 "register_operand" "") 7339 (match_operand:DF 2 "nonimmediate_operand" "")))] 7340 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 7341 "") 7342 7343(define_expand "mulsf3" 7344 [(set (match_operand:SF 0 "register_operand" "") 7345 (mult:SF (match_operand:SF 1 "register_operand" "") 7346 (match_operand:SF 2 "nonimmediate_operand" "")))] 7347 "TARGET_80387 || TARGET_SSE_MATH" 7348 "") 7349 7350;; Divide instructions 7351 7352(define_insn "divqi3" 7353 [(set (match_operand:QI 0 "register_operand" "=a") 7354 (div:QI (match_operand:HI 1 "register_operand" "0") 7355 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 7356 (clobber (reg:CC FLAGS_REG))] 7357 "TARGET_QIMODE_MATH" 7358 "idiv{b}\t%2" 7359 [(set_attr "type" "idiv") 7360 (set_attr "mode" "QI")]) 7361 7362(define_insn "udivqi3" 7363 [(set (match_operand:QI 0 "register_operand" "=a") 7364 (udiv:QI (match_operand:HI 1 "register_operand" "0") 7365 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 7366 (clobber (reg:CC FLAGS_REG))] 7367 "TARGET_QIMODE_MATH" 7368 "div{b}\t%2" 7369 [(set_attr "type" "idiv") 7370 (set_attr "mode" "QI")]) 7371 7372;; The patterns that match these are at the end of this file. 7373 7374(define_expand "divxf3" 7375 [(set (match_operand:XF 0 "register_operand" "") 7376 (div:XF (match_operand:XF 1 "register_operand" "") 7377 (match_operand:XF 2 "register_operand" "")))] 7378 "TARGET_80387" 7379 "") 7380 7381(define_expand "divdf3" 7382 [(set (match_operand:DF 0 "register_operand" "") 7383 (div:DF (match_operand:DF 1 "register_operand" "") 7384 (match_operand:DF 2 "nonimmediate_operand" "")))] 7385 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 7386 "") 7387 7388(define_expand "divsf3" 7389 [(set (match_operand:SF 0 "register_operand" "") 7390 (div:SF (match_operand:SF 1 "register_operand" "") 7391 (match_operand:SF 2 "nonimmediate_operand" "")))] 7392 "TARGET_80387 || TARGET_SSE_MATH" 7393 "") 7394 7395;; Remainder instructions. 7396 7397(define_expand "divmoddi4" 7398 [(parallel [(set (match_operand:DI 0 "register_operand" "") 7399 (div:DI (match_operand:DI 1 "register_operand" "") 7400 (match_operand:DI 2 "nonimmediate_operand" ""))) 7401 (set (match_operand:DI 3 "register_operand" "") 7402 (mod:DI (match_dup 1) (match_dup 2))) 7403 (clobber (reg:CC FLAGS_REG))])] 7404 "TARGET_64BIT" 7405 "") 7406 7407;; Allow to come the parameter in eax or edx to avoid extra moves. 7408;; Penalize eax case slightly because it results in worse scheduling 7409;; of code. 7410(define_insn "*divmoddi4_nocltd_rex64" 7411 [(set (match_operand:DI 0 "register_operand" "=&a,?a") 7412 (div:DI (match_operand:DI 2 "register_operand" "1,0") 7413 (match_operand:DI 3 "nonimmediate_operand" "rm,rm"))) 7414 (set (match_operand:DI 1 "register_operand" "=&d,&d") 7415 (mod:DI (match_dup 2) (match_dup 3))) 7416 (clobber (reg:CC FLAGS_REG))] 7417 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD" 7418 "#" 7419 [(set_attr "type" "multi")]) 7420 7421(define_insn "*divmoddi4_cltd_rex64" 7422 [(set (match_operand:DI 0 "register_operand" "=a") 7423 (div:DI (match_operand:DI 2 "register_operand" "a") 7424 (match_operand:DI 3 "nonimmediate_operand" "rm"))) 7425 (set (match_operand:DI 1 "register_operand" "=&d") 7426 (mod:DI (match_dup 2) (match_dup 3))) 7427 (clobber (reg:CC FLAGS_REG))] 7428 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)" 7429 "#" 7430 [(set_attr "type" "multi")]) 7431 7432(define_insn "*divmoddi_noext_rex64" 7433 [(set (match_operand:DI 0 "register_operand" "=a") 7434 (div:DI (match_operand:DI 1 "register_operand" "0") 7435 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7436 (set (match_operand:DI 3 "register_operand" "=d") 7437 (mod:DI (match_dup 1) (match_dup 2))) 7438 (use (match_operand:DI 4 "register_operand" "3")) 7439 (clobber (reg:CC FLAGS_REG))] 7440 "TARGET_64BIT" 7441 "idiv{q}\t%2" 7442 [(set_attr "type" "idiv") 7443 (set_attr "mode" "DI")]) 7444 7445(define_split 7446 [(set (match_operand:DI 0 "register_operand" "") 7447 (div:DI (match_operand:DI 1 "register_operand" "") 7448 (match_operand:DI 2 "nonimmediate_operand" ""))) 7449 (set (match_operand:DI 3 "register_operand" "") 7450 (mod:DI (match_dup 1) (match_dup 2))) 7451 (clobber (reg:CC FLAGS_REG))] 7452 "TARGET_64BIT && reload_completed" 7453 [(parallel [(set (match_dup 3) 7454 (ashiftrt:DI (match_dup 4) (const_int 63))) 7455 (clobber (reg:CC FLAGS_REG))]) 7456 (parallel [(set (match_dup 0) 7457 (div:DI (reg:DI 0) (match_dup 2))) 7458 (set (match_dup 3) 7459 (mod:DI (reg:DI 0) (match_dup 2))) 7460 (use (match_dup 3)) 7461 (clobber (reg:CC FLAGS_REG))])] 7462{ 7463 /* Avoid use of cltd in favor of a mov+shift. */ 7464 if (!TARGET_USE_CLTD && !optimize_size) 7465 { 7466 if (true_regnum (operands[1])) 7467 emit_move_insn (operands[0], operands[1]); 7468 else 7469 emit_move_insn (operands[3], operands[1]); 7470 operands[4] = operands[3]; 7471 } 7472 else 7473 { 7474 gcc_assert (!true_regnum (operands[1])); 7475 operands[4] = operands[1]; 7476 } 7477}) 7478 7479 7480(define_expand "divmodsi4" 7481 [(parallel [(set (match_operand:SI 0 "register_operand" "") 7482 (div:SI (match_operand:SI 1 "register_operand" "") 7483 (match_operand:SI 2 "nonimmediate_operand" ""))) 7484 (set (match_operand:SI 3 "register_operand" "") 7485 (mod:SI (match_dup 1) (match_dup 2))) 7486 (clobber (reg:CC FLAGS_REG))])] 7487 "" 7488 "") 7489 7490;; Allow to come the parameter in eax or edx to avoid extra moves. 7491;; Penalize eax case slightly because it results in worse scheduling 7492;; of code. 7493(define_insn "*divmodsi4_nocltd" 7494 [(set (match_operand:SI 0 "register_operand" "=&a,?a") 7495 (div:SI (match_operand:SI 2 "register_operand" "1,0") 7496 (match_operand:SI 3 "nonimmediate_operand" "rm,rm"))) 7497 (set (match_operand:SI 1 "register_operand" "=&d,&d") 7498 (mod:SI (match_dup 2) (match_dup 3))) 7499 (clobber (reg:CC FLAGS_REG))] 7500 "!optimize_size && !TARGET_USE_CLTD" 7501 "#" 7502 [(set_attr "type" "multi")]) 7503 7504(define_insn "*divmodsi4_cltd" 7505 [(set (match_operand:SI 0 "register_operand" "=a") 7506 (div:SI (match_operand:SI 2 "register_operand" "a") 7507 (match_operand:SI 3 "nonimmediate_operand" "rm"))) 7508 (set (match_operand:SI 1 "register_operand" "=&d") 7509 (mod:SI (match_dup 2) (match_dup 3))) 7510 (clobber (reg:CC FLAGS_REG))] 7511 "optimize_size || TARGET_USE_CLTD" 7512 "#" 7513 [(set_attr "type" "multi")]) 7514 7515(define_insn "*divmodsi_noext" 7516 [(set (match_operand:SI 0 "register_operand" "=a") 7517 (div:SI (match_operand:SI 1 "register_operand" "0") 7518 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7519 (set (match_operand:SI 3 "register_operand" "=d") 7520 (mod:SI (match_dup 1) (match_dup 2))) 7521 (use (match_operand:SI 4 "register_operand" "3")) 7522 (clobber (reg:CC FLAGS_REG))] 7523 "" 7524 "idiv{l}\t%2" 7525 [(set_attr "type" "idiv") 7526 (set_attr "mode" "SI")]) 7527 7528(define_split 7529 [(set (match_operand:SI 0 "register_operand" "") 7530 (div:SI (match_operand:SI 1 "register_operand" "") 7531 (match_operand:SI 2 "nonimmediate_operand" ""))) 7532 (set (match_operand:SI 3 "register_operand" "") 7533 (mod:SI (match_dup 1) (match_dup 2))) 7534 (clobber (reg:CC FLAGS_REG))] 7535 "reload_completed" 7536 [(parallel [(set (match_dup 3) 7537 (ashiftrt:SI (match_dup 4) (const_int 31))) 7538 (clobber (reg:CC FLAGS_REG))]) 7539 (parallel [(set (match_dup 0) 7540 (div:SI (reg:SI 0) (match_dup 2))) 7541 (set (match_dup 3) 7542 (mod:SI (reg:SI 0) (match_dup 2))) 7543 (use (match_dup 3)) 7544 (clobber (reg:CC FLAGS_REG))])] 7545{ 7546 /* Avoid use of cltd in favor of a mov+shift. */ 7547 if (!TARGET_USE_CLTD && !optimize_size) 7548 { 7549 if (true_regnum (operands[1])) 7550 emit_move_insn (operands[0], operands[1]); 7551 else 7552 emit_move_insn (operands[3], operands[1]); 7553 operands[4] = operands[3]; 7554 } 7555 else 7556 { 7557 gcc_assert (!true_regnum (operands[1])); 7558 operands[4] = operands[1]; 7559 } 7560}) 7561;; %%% Split me. 7562(define_insn "divmodhi4" 7563 [(set (match_operand:HI 0 "register_operand" "=a") 7564 (div:HI (match_operand:HI 1 "register_operand" "0") 7565 (match_operand:HI 2 "nonimmediate_operand" "rm"))) 7566 (set (match_operand:HI 3 "register_operand" "=&d") 7567 (mod:HI (match_dup 1) (match_dup 2))) 7568 (clobber (reg:CC FLAGS_REG))] 7569 "TARGET_HIMODE_MATH" 7570 "cwtd\;idiv{w}\t%2" 7571 [(set_attr "type" "multi") 7572 (set_attr "length_immediate" "0") 7573 (set_attr "mode" "SI")]) 7574 7575(define_insn "udivmoddi4" 7576 [(set (match_operand:DI 0 "register_operand" "=a") 7577 (udiv:DI (match_operand:DI 1 "register_operand" "0") 7578 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7579 (set (match_operand:DI 3 "register_operand" "=&d") 7580 (umod:DI (match_dup 1) (match_dup 2))) 7581 (clobber (reg:CC FLAGS_REG))] 7582 "TARGET_64BIT" 7583 "xor{q}\t%3, %3\;div{q}\t%2" 7584 [(set_attr "type" "multi") 7585 (set_attr "length_immediate" "0") 7586 (set_attr "mode" "DI")]) 7587 7588(define_insn "*udivmoddi4_noext" 7589 [(set (match_operand:DI 0 "register_operand" "=a") 7590 (udiv:DI (match_operand:DI 1 "register_operand" "0") 7591 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7592 (set (match_operand:DI 3 "register_operand" "=d") 7593 (umod:DI (match_dup 1) (match_dup 2))) 7594 (use (match_dup 3)) 7595 (clobber (reg:CC FLAGS_REG))] 7596 "TARGET_64BIT" 7597 "div{q}\t%2" 7598 [(set_attr "type" "idiv") 7599 (set_attr "mode" "DI")]) 7600 7601(define_split 7602 [(set (match_operand:DI 0 "register_operand" "") 7603 (udiv:DI (match_operand:DI 1 "register_operand" "") 7604 (match_operand:DI 2 "nonimmediate_operand" ""))) 7605 (set (match_operand:DI 3 "register_operand" "") 7606 (umod:DI (match_dup 1) (match_dup 2))) 7607 (clobber (reg:CC FLAGS_REG))] 7608 "TARGET_64BIT && reload_completed" 7609 [(set (match_dup 3) (const_int 0)) 7610 (parallel [(set (match_dup 0) 7611 (udiv:DI (match_dup 1) (match_dup 2))) 7612 (set (match_dup 3) 7613 (umod:DI (match_dup 1) (match_dup 2))) 7614 (use (match_dup 3)) 7615 (clobber (reg:CC FLAGS_REG))])] 7616 "") 7617 7618(define_insn "udivmodsi4" 7619 [(set (match_operand:SI 0 "register_operand" "=a") 7620 (udiv:SI (match_operand:SI 1 "register_operand" "0") 7621 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7622 (set (match_operand:SI 3 "register_operand" "=&d") 7623 (umod:SI (match_dup 1) (match_dup 2))) 7624 (clobber (reg:CC FLAGS_REG))] 7625 "" 7626 "xor{l}\t%3, %3\;div{l}\t%2" 7627 [(set_attr "type" "multi") 7628 (set_attr "length_immediate" "0") 7629 (set_attr "mode" "SI")]) 7630 7631(define_insn "*udivmodsi4_noext" 7632 [(set (match_operand:SI 0 "register_operand" "=a") 7633 (udiv:SI (match_operand:SI 1 "register_operand" "0") 7634 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7635 (set (match_operand:SI 3 "register_operand" "=d") 7636 (umod:SI (match_dup 1) (match_dup 2))) 7637 (use (match_dup 3)) 7638 (clobber (reg:CC FLAGS_REG))] 7639 "" 7640 "div{l}\t%2" 7641 [(set_attr "type" "idiv") 7642 (set_attr "mode" "SI")]) 7643 7644(define_split 7645 [(set (match_operand:SI 0 "register_operand" "") 7646 (udiv:SI (match_operand:SI 1 "register_operand" "") 7647 (match_operand:SI 2 "nonimmediate_operand" ""))) 7648 (set (match_operand:SI 3 "register_operand" "") 7649 (umod:SI (match_dup 1) (match_dup 2))) 7650 (clobber (reg:CC FLAGS_REG))] 7651 "reload_completed" 7652 [(set (match_dup 3) (const_int 0)) 7653 (parallel [(set (match_dup 0) 7654 (udiv:SI (match_dup 1) (match_dup 2))) 7655 (set (match_dup 3) 7656 (umod:SI (match_dup 1) (match_dup 2))) 7657 (use (match_dup 3)) 7658 (clobber (reg:CC FLAGS_REG))])] 7659 "") 7660 7661(define_expand "udivmodhi4" 7662 [(set (match_dup 4) (const_int 0)) 7663 (parallel [(set (match_operand:HI 0 "register_operand" "") 7664 (udiv:HI (match_operand:HI 1 "register_operand" "") 7665 (match_operand:HI 2 "nonimmediate_operand" ""))) 7666 (set (match_operand:HI 3 "register_operand" "") 7667 (umod:HI (match_dup 1) (match_dup 2))) 7668 (use (match_dup 4)) 7669 (clobber (reg:CC FLAGS_REG))])] 7670 "TARGET_HIMODE_MATH" 7671 "operands[4] = gen_reg_rtx (HImode);") 7672 7673(define_insn "*udivmodhi_noext" 7674 [(set (match_operand:HI 0 "register_operand" "=a") 7675 (udiv:HI (match_operand:HI 1 "register_operand" "0") 7676 (match_operand:HI 2 "nonimmediate_operand" "rm"))) 7677 (set (match_operand:HI 3 "register_operand" "=d") 7678 (umod:HI (match_dup 1) (match_dup 2))) 7679 (use (match_operand:HI 4 "register_operand" "3")) 7680 (clobber (reg:CC FLAGS_REG))] 7681 "" 7682 "div{w}\t%2" 7683 [(set_attr "type" "idiv") 7684 (set_attr "mode" "HI")]) 7685 7686;; We cannot use div/idiv for double division, because it causes 7687;; "division by zero" on the overflow and that's not what we expect 7688;; from truncate. Because true (non truncating) double division is 7689;; never generated, we can't create this insn anyway. 7690; 7691;(define_insn "" 7692; [(set (match_operand:SI 0 "register_operand" "=a") 7693; (truncate:SI 7694; (udiv:DI (match_operand:DI 1 "register_operand" "A") 7695; (zero_extend:DI 7696; (match_operand:SI 2 "nonimmediate_operand" "rm"))))) 7697; (set (match_operand:SI 3 "register_operand" "=d") 7698; (truncate:SI 7699; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2))))) 7700; (clobber (reg:CC FLAGS_REG))] 7701; "" 7702; "div{l}\t{%2, %0|%0, %2}" 7703; [(set_attr "type" "idiv")]) 7704 7705;;- Logical AND instructions 7706 7707;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al. 7708;; Note that this excludes ah. 7709 7710(define_insn "*testdi_1_rex64" 7711 [(set (reg FLAGS_REG) 7712 (compare 7713 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm") 7714 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re")) 7715 (const_int 0)))] 7716 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7717 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7718 "@ 7719 test{l}\t{%k1, %k0|%k0, %k1} 7720 test{l}\t{%k1, %k0|%k0, %k1} 7721 test{q}\t{%1, %0|%0, %1} 7722 test{q}\t{%1, %0|%0, %1} 7723 test{q}\t{%1, %0|%0, %1}" 7724 [(set_attr "type" "test") 7725 (set_attr "modrm" "0,1,0,1,1") 7726 (set_attr "mode" "SI,SI,DI,DI,DI") 7727 (set_attr "pent_pair" "uv,np,uv,np,uv")]) 7728 7729(define_insn "testsi_1" 7730 [(set (reg FLAGS_REG) 7731 (compare 7732 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm") 7733 (match_operand:SI 1 "general_operand" "in,in,rin")) 7734 (const_int 0)))] 7735 "ix86_match_ccmode (insn, CCNOmode) 7736 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7737 "test{l}\t{%1, %0|%0, %1}" 7738 [(set_attr "type" "test") 7739 (set_attr "modrm" "0,1,1") 7740 (set_attr "mode" "SI") 7741 (set_attr "pent_pair" "uv,np,uv")]) 7742 7743(define_expand "testsi_ccno_1" 7744 [(set (reg:CCNO FLAGS_REG) 7745 (compare:CCNO 7746 (and:SI (match_operand:SI 0 "nonimmediate_operand" "") 7747 (match_operand:SI 1 "nonmemory_operand" "")) 7748 (const_int 0)))] 7749 "" 7750 "") 7751 7752(define_insn "*testhi_1" 7753 [(set (reg FLAGS_REG) 7754 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm") 7755 (match_operand:HI 1 "general_operand" "n,n,rn")) 7756 (const_int 0)))] 7757 "ix86_match_ccmode (insn, CCNOmode) 7758 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7759 "test{w}\t{%1, %0|%0, %1}" 7760 [(set_attr "type" "test") 7761 (set_attr "modrm" "0,1,1") 7762 (set_attr "mode" "HI") 7763 (set_attr "pent_pair" "uv,np,uv")]) 7764 7765(define_expand "testqi_ccz_1" 7766 [(set (reg:CCZ FLAGS_REG) 7767 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "") 7768 (match_operand:QI 1 "nonmemory_operand" "")) 7769 (const_int 0)))] 7770 "" 7771 "") 7772 7773(define_insn "*testqi_1_maybe_si" 7774 [(set (reg FLAGS_REG) 7775 (compare 7776 (and:QI 7777 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r") 7778 (match_operand:QI 1 "general_operand" "n,n,qn,n")) 7779 (const_int 0)))] 7780 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 7781 && ix86_match_ccmode (insn, 7782 GET_CODE (operands[1]) == CONST_INT 7783 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)" 7784{ 7785 if (which_alternative == 3) 7786 { 7787 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0) 7788 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); 7789 return "test{l}\t{%1, %k0|%k0, %1}"; 7790 } 7791 return "test{b}\t{%1, %0|%0, %1}"; 7792} 7793 [(set_attr "type" "test") 7794 (set_attr "modrm" "0,1,1,1") 7795 (set_attr "mode" "QI,QI,QI,SI") 7796 (set_attr "pent_pair" "uv,np,uv,np")]) 7797 7798(define_insn "*testqi_1" 7799 [(set (reg FLAGS_REG) 7800 (compare 7801 (and:QI 7802 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm") 7803 (match_operand:QI 1 "general_operand" "n,n,qn")) 7804 (const_int 0)))] 7805 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 7806 && ix86_match_ccmode (insn, CCNOmode)" 7807 "test{b}\t{%1, %0|%0, %1}" 7808 [(set_attr "type" "test") 7809 (set_attr "modrm" "0,1,1") 7810 (set_attr "mode" "QI") 7811 (set_attr "pent_pair" "uv,np,uv")]) 7812 7813(define_expand "testqi_ext_ccno_0" 7814 [(set (reg:CCNO FLAGS_REG) 7815 (compare:CCNO 7816 (and:SI 7817 (zero_extract:SI 7818 (match_operand 0 "ext_register_operand" "") 7819 (const_int 8) 7820 (const_int 8)) 7821 (match_operand 1 "const_int_operand" "")) 7822 (const_int 0)))] 7823 "" 7824 "") 7825 7826(define_insn "*testqi_ext_0" 7827 [(set (reg FLAGS_REG) 7828 (compare 7829 (and:SI 7830 (zero_extract:SI 7831 (match_operand 0 "ext_register_operand" "Q") 7832 (const_int 8) 7833 (const_int 8)) 7834 (match_operand 1 "const_int_operand" "n")) 7835 (const_int 0)))] 7836 "ix86_match_ccmode (insn, CCNOmode)" 7837 "test{b}\t{%1, %h0|%h0, %1}" 7838 [(set_attr "type" "test") 7839 (set_attr "mode" "QI") 7840 (set_attr "length_immediate" "1") 7841 (set_attr "pent_pair" "np")]) 7842 7843(define_insn "*testqi_ext_1" 7844 [(set (reg FLAGS_REG) 7845 (compare 7846 (and:SI 7847 (zero_extract:SI 7848 (match_operand 0 "ext_register_operand" "Q") 7849 (const_int 8) 7850 (const_int 8)) 7851 (zero_extend:SI 7852 (match_operand:QI 1 "general_operand" "Qm"))) 7853 (const_int 0)))] 7854 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7855 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 7856 "test{b}\t{%1, %h0|%h0, %1}" 7857 [(set_attr "type" "test") 7858 (set_attr "mode" "QI")]) 7859 7860(define_insn "*testqi_ext_1_rex64" 7861 [(set (reg FLAGS_REG) 7862 (compare 7863 (and:SI 7864 (zero_extract:SI 7865 (match_operand 0 "ext_register_operand" "Q") 7866 (const_int 8) 7867 (const_int 8)) 7868 (zero_extend:SI 7869 (match_operand:QI 1 "register_operand" "Q"))) 7870 (const_int 0)))] 7871 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 7872 "test{b}\t{%1, %h0|%h0, %1}" 7873 [(set_attr "type" "test") 7874 (set_attr "mode" "QI")]) 7875 7876(define_insn "*testqi_ext_2" 7877 [(set (reg FLAGS_REG) 7878 (compare 7879 (and:SI 7880 (zero_extract:SI 7881 (match_operand 0 "ext_register_operand" "Q") 7882 (const_int 8) 7883 (const_int 8)) 7884 (zero_extract:SI 7885 (match_operand 1 "ext_register_operand" "Q") 7886 (const_int 8) 7887 (const_int 8))) 7888 (const_int 0)))] 7889 "ix86_match_ccmode (insn, CCNOmode)" 7890 "test{b}\t{%h1, %h0|%h0, %h1}" 7891 [(set_attr "type" "test") 7892 (set_attr "mode" "QI")]) 7893 7894;; Combine likes to form bit extractions for some tests. Humor it. 7895(define_insn "*testqi_ext_3" 7896 [(set (reg FLAGS_REG) 7897 (compare (zero_extract:SI 7898 (match_operand 0 "nonimmediate_operand" "rm") 7899 (match_operand:SI 1 "const_int_operand" "") 7900 (match_operand:SI 2 "const_int_operand" "")) 7901 (const_int 0)))] 7902 "ix86_match_ccmode (insn, CCNOmode) 7903 && INTVAL (operands[1]) > 0 7904 && INTVAL (operands[2]) >= 0 7905 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 7906 && (GET_MODE (operands[0]) == SImode 7907 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode) 7908 || GET_MODE (operands[0]) == HImode 7909 || GET_MODE (operands[0]) == QImode)" 7910 "#") 7911 7912(define_insn "*testqi_ext_3_rex64" 7913 [(set (reg FLAGS_REG) 7914 (compare (zero_extract:DI 7915 (match_operand 0 "nonimmediate_operand" "rm") 7916 (match_operand:DI 1 "const_int_operand" "") 7917 (match_operand:DI 2 "const_int_operand" "")) 7918 (const_int 0)))] 7919 "TARGET_64BIT 7920 && ix86_match_ccmode (insn, CCNOmode) 7921 && INTVAL (operands[1]) > 0 7922 && INTVAL (operands[2]) >= 0 7923 /* Ensure that resulting mask is zero or sign extended operand. */ 7924 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 7925 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64 7926 && INTVAL (operands[1]) > 32)) 7927 && (GET_MODE (operands[0]) == SImode 7928 || GET_MODE (operands[0]) == DImode 7929 || GET_MODE (operands[0]) == HImode 7930 || GET_MODE (operands[0]) == QImode)" 7931 "#") 7932 7933(define_split 7934 [(set (match_operand 0 "flags_reg_operand" "") 7935 (match_operator 1 "compare_operator" 7936 [(zero_extract 7937 (match_operand 2 "nonimmediate_operand" "") 7938 (match_operand 3 "const_int_operand" "") 7939 (match_operand 4 "const_int_operand" "")) 7940 (const_int 0)]))] 7941 "ix86_match_ccmode (insn, CCNOmode)" 7942 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))] 7943{ 7944 rtx val = operands[2]; 7945 HOST_WIDE_INT len = INTVAL (operands[3]); 7946 HOST_WIDE_INT pos = INTVAL (operands[4]); 7947 HOST_WIDE_INT mask; 7948 enum machine_mode mode, submode; 7949 7950 mode = GET_MODE (val); 7951 if (GET_CODE (val) == MEM) 7952 { 7953 /* ??? Combine likes to put non-volatile mem extractions in QImode 7954 no matter the size of the test. So find a mode that works. */ 7955 if (! MEM_VOLATILE_P (val)) 7956 { 7957 mode = smallest_mode_for_size (pos + len, MODE_INT); 7958 val = adjust_address (val, mode, 0); 7959 } 7960 } 7961 else if (GET_CODE (val) == SUBREG 7962 && (submode = GET_MODE (SUBREG_REG (val)), 7963 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)) 7964 && pos + len <= GET_MODE_BITSIZE (submode)) 7965 { 7966 /* Narrow a paradoxical subreg to prevent partial register stalls. */ 7967 mode = submode; 7968 val = SUBREG_REG (val); 7969 } 7970 else if (mode == HImode && pos + len <= 8) 7971 { 7972 /* Small HImode tests can be converted to QImode. */ 7973 mode = QImode; 7974 val = gen_lowpart (QImode, val); 7975 } 7976 7977 if (len == HOST_BITS_PER_WIDE_INT) 7978 mask = -1; 7979 else 7980 mask = ((HOST_WIDE_INT)1 << len) - 1; 7981 mask <<= pos; 7982 7983 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode)); 7984}) 7985 7986;; Convert HImode/SImode test instructions with immediate to QImode ones. 7987;; i386 does not allow to encode test with 8bit sign extended immediate, so 7988;; this is relatively important trick. 7989;; Do the conversion only post-reload to avoid limiting of the register class 7990;; to QI regs. 7991(define_split 7992 [(set (match_operand 0 "flags_reg_operand" "") 7993 (match_operator 1 "compare_operator" 7994 [(and (match_operand 2 "register_operand" "") 7995 (match_operand 3 "const_int_operand" "")) 7996 (const_int 0)]))] 7997 "reload_completed 7998 && QI_REG_P (operands[2]) 7999 && GET_MODE (operands[2]) != QImode 8000 && ((ix86_match_ccmode (insn, CCZmode) 8001 && !(INTVAL (operands[3]) & ~(255 << 8))) 8002 || (ix86_match_ccmode (insn, CCNOmode) 8003 && !(INTVAL (operands[3]) & ~(127 << 8))))" 8004 [(set (match_dup 0) 8005 (match_op_dup 1 8006 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8)) 8007 (match_dup 3)) 8008 (const_int 0)]))] 8009 "operands[2] = gen_lowpart (SImode, operands[2]); 8010 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);") 8011 8012(define_split 8013 [(set (match_operand 0 "flags_reg_operand" "") 8014 (match_operator 1 "compare_operator" 8015 [(and (match_operand 2 "nonimmediate_operand" "") 8016 (match_operand 3 "const_int_operand" "")) 8017 (const_int 0)]))] 8018 "reload_completed 8019 && GET_MODE (operands[2]) != QImode 8020 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2])) 8021 && ((ix86_match_ccmode (insn, CCZmode) 8022 && !(INTVAL (operands[3]) & ~255)) 8023 || (ix86_match_ccmode (insn, CCNOmode) 8024 && !(INTVAL (operands[3]) & ~127)))" 8025 [(set (match_dup 0) 8026 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 8027 (const_int 0)]))] 8028 "operands[2] = gen_lowpart (QImode, operands[2]); 8029 operands[3] = gen_lowpart (QImode, operands[3]);") 8030 8031 8032;; %%% This used to optimize known byte-wide and operations to memory, 8033;; and sometimes to QImode registers. If this is considered useful, 8034;; it should be done with splitters. 8035 8036(define_expand "anddi3" 8037 [(set (match_operand:DI 0 "nonimmediate_operand" "") 8038 (and:DI (match_operand:DI 1 "nonimmediate_operand" "") 8039 (match_operand:DI 2 "x86_64_szext_general_operand" ""))) 8040 (clobber (reg:CC FLAGS_REG))] 8041 "TARGET_64BIT" 8042 "ix86_expand_binary_operator (AND, DImode, operands); DONE;") 8043 8044(define_insn "*anddi_1_rex64" 8045 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r") 8046 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm") 8047 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L"))) 8048 (clobber (reg:CC FLAGS_REG))] 8049 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)" 8050{ 8051 switch (get_attr_type (insn)) 8052 { 8053 case TYPE_IMOVX: 8054 { 8055 enum machine_mode mode; 8056 8057 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 8058 if (INTVAL (operands[2]) == 0xff) 8059 mode = QImode; 8060 else 8061 { 8062 gcc_assert (INTVAL (operands[2]) == 0xffff); 8063 mode = HImode; 8064 } 8065 8066 operands[1] = gen_lowpart (mode, operands[1]); 8067 if (mode == QImode) 8068 return "movz{bq|x}\t{%1,%0|%0, %1}"; 8069 else 8070 return "movz{wq|x}\t{%1,%0|%0, %1}"; 8071 } 8072 8073 default: 8074 gcc_assert (rtx_equal_p (operands[0], operands[1])); 8075 if (get_attr_mode (insn) == MODE_SI) 8076 return "and{l}\t{%k2, %k0|%k0, %k2}"; 8077 else 8078 return "and{q}\t{%2, %0|%0, %2}"; 8079 } 8080} 8081 [(set_attr "type" "alu,alu,alu,imovx") 8082 (set_attr "length_immediate" "*,*,*,0") 8083 (set_attr "mode" "SI,DI,DI,DI")]) 8084 8085(define_insn "*anddi_2" 8086 [(set (reg FLAGS_REG) 8087 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") 8088 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re")) 8089 (const_int 0))) 8090 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm") 8091 (and:DI (match_dup 1) (match_dup 2)))] 8092 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8093 && ix86_binary_operator_ok (AND, DImode, operands)" 8094 "@ 8095 and{l}\t{%k2, %k0|%k0, %k2} 8096 and{q}\t{%2, %0|%0, %2} 8097 and{q}\t{%2, %0|%0, %2}" 8098 [(set_attr "type" "alu") 8099 (set_attr "mode" "SI,DI,DI")]) 8100 8101(define_expand "andsi3" 8102 [(set (match_operand:SI 0 "nonimmediate_operand" "") 8103 (and:SI (match_operand:SI 1 "nonimmediate_operand" "") 8104 (match_operand:SI 2 "general_operand" ""))) 8105 (clobber (reg:CC FLAGS_REG))] 8106 "" 8107 "ix86_expand_binary_operator (AND, SImode, operands); DONE;") 8108 8109(define_insn "*andsi_1" 8110 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r") 8111 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm") 8112 (match_operand:SI 2 "general_operand" "ri,rm,L"))) 8113 (clobber (reg:CC FLAGS_REG))] 8114 "ix86_binary_operator_ok (AND, SImode, operands)" 8115{ 8116 switch (get_attr_type (insn)) 8117 { 8118 case TYPE_IMOVX: 8119 { 8120 enum machine_mode mode; 8121 8122 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 8123 if (INTVAL (operands[2]) == 0xff) 8124 mode = QImode; 8125 else 8126 { 8127 gcc_assert (INTVAL (operands[2]) == 0xffff); 8128 mode = HImode; 8129 } 8130 8131 operands[1] = gen_lowpart (mode, operands[1]); 8132 if (mode == QImode) 8133 return "movz{bl|x}\t{%1,%0|%0, %1}"; 8134 else 8135 return "movz{wl|x}\t{%1,%0|%0, %1}"; 8136 } 8137 8138 default: 8139 gcc_assert (rtx_equal_p (operands[0], operands[1])); 8140 return "and{l}\t{%2, %0|%0, %2}"; 8141 } 8142} 8143 [(set_attr "type" "alu,alu,imovx") 8144 (set_attr "length_immediate" "*,*,0") 8145 (set_attr "mode" "SI")]) 8146 8147(define_split 8148 [(set (match_operand 0 "register_operand" "") 8149 (and (match_dup 0) 8150 (const_int -65536))) 8151 (clobber (reg:CC FLAGS_REG))] 8152 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)" 8153 [(set (strict_low_part (match_dup 1)) (const_int 0))] 8154 "operands[1] = gen_lowpart (HImode, operands[0]);") 8155 8156(define_split 8157 [(set (match_operand 0 "ext_register_operand" "") 8158 (and (match_dup 0) 8159 (const_int -256))) 8160 (clobber (reg:CC FLAGS_REG))] 8161 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed" 8162 [(set (strict_low_part (match_dup 1)) (const_int 0))] 8163 "operands[1] = gen_lowpart (QImode, operands[0]);") 8164 8165(define_split 8166 [(set (match_operand 0 "ext_register_operand" "") 8167 (and (match_dup 0) 8168 (const_int -65281))) 8169 (clobber (reg:CC FLAGS_REG))] 8170 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed" 8171 [(parallel [(set (zero_extract:SI (match_dup 0) 8172 (const_int 8) 8173 (const_int 8)) 8174 (xor:SI 8175 (zero_extract:SI (match_dup 0) 8176 (const_int 8) 8177 (const_int 8)) 8178 (zero_extract:SI (match_dup 0) 8179 (const_int 8) 8180 (const_int 8)))) 8181 (clobber (reg:CC FLAGS_REG))])] 8182 "operands[0] = gen_lowpart (SImode, operands[0]);") 8183 8184;; See comment for addsi_1_zext why we do use nonimmediate_operand 8185(define_insn "*andsi_1_zext" 8186 [(set (match_operand:DI 0 "register_operand" "=r") 8187 (zero_extend:DI 8188 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8189 (match_operand:SI 2 "general_operand" "rim")))) 8190 (clobber (reg:CC FLAGS_REG))] 8191 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" 8192 "and{l}\t{%2, %k0|%k0, %2}" 8193 [(set_attr "type" "alu") 8194 (set_attr "mode" "SI")]) 8195 8196(define_insn "*andsi_2" 8197 [(set (reg FLAGS_REG) 8198 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8199 (match_operand:SI 2 "general_operand" "rim,ri")) 8200 (const_int 0))) 8201 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 8202 (and:SI (match_dup 1) (match_dup 2)))] 8203 "ix86_match_ccmode (insn, CCNOmode) 8204 && ix86_binary_operator_ok (AND, SImode, operands)" 8205 "and{l}\t{%2, %0|%0, %2}" 8206 [(set_attr "type" "alu") 8207 (set_attr "mode" "SI")]) 8208 8209;; See comment for addsi_1_zext why we do use nonimmediate_operand 8210(define_insn "*andsi_2_zext" 8211 [(set (reg FLAGS_REG) 8212 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8213 (match_operand:SI 2 "general_operand" "rim")) 8214 (const_int 0))) 8215 (set (match_operand:DI 0 "register_operand" "=r") 8216 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] 8217 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8218 && ix86_binary_operator_ok (AND, SImode, operands)" 8219 "and{l}\t{%2, %k0|%k0, %2}" 8220 [(set_attr "type" "alu") 8221 (set_attr "mode" "SI")]) 8222 8223(define_expand "andhi3" 8224 [(set (match_operand:HI 0 "nonimmediate_operand" "") 8225 (and:HI (match_operand:HI 1 "nonimmediate_operand" "") 8226 (match_operand:HI 2 "general_operand" ""))) 8227 (clobber (reg:CC FLAGS_REG))] 8228 "TARGET_HIMODE_MATH" 8229 "ix86_expand_binary_operator (AND, HImode, operands); DONE;") 8230 8231(define_insn "*andhi_1" 8232 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r") 8233 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm") 8234 (match_operand:HI 2 "general_operand" "ri,rm,L"))) 8235 (clobber (reg:CC FLAGS_REG))] 8236 "ix86_binary_operator_ok (AND, HImode, operands)" 8237{ 8238 switch (get_attr_type (insn)) 8239 { 8240 case TYPE_IMOVX: 8241 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 8242 gcc_assert (INTVAL (operands[2]) == 0xff); 8243 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}"; 8244 8245 default: 8246 gcc_assert (rtx_equal_p (operands[0], operands[1])); 8247 8248 return "and{w}\t{%2, %0|%0, %2}"; 8249 } 8250} 8251 [(set_attr "type" "alu,alu,imovx") 8252 (set_attr "length_immediate" "*,*,0") 8253 (set_attr "mode" "HI,HI,SI")]) 8254 8255(define_insn "*andhi_2" 8256 [(set (reg FLAGS_REG) 8257 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 8258 (match_operand:HI 2 "general_operand" "rim,ri")) 8259 (const_int 0))) 8260 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 8261 (and:HI (match_dup 1) (match_dup 2)))] 8262 "ix86_match_ccmode (insn, CCNOmode) 8263 && ix86_binary_operator_ok (AND, HImode, operands)" 8264 "and{w}\t{%2, %0|%0, %2}" 8265 [(set_attr "type" "alu") 8266 (set_attr "mode" "HI")]) 8267 8268(define_expand "andqi3" 8269 [(set (match_operand:QI 0 "nonimmediate_operand" "") 8270 (and:QI (match_operand:QI 1 "nonimmediate_operand" "") 8271 (match_operand:QI 2 "general_operand" ""))) 8272 (clobber (reg:CC FLAGS_REG))] 8273 "TARGET_QIMODE_MATH" 8274 "ix86_expand_binary_operator (AND, QImode, operands); DONE;") 8275 8276;; %%% Potential partial reg stall on alternative 2. What to do? 8277(define_insn "*andqi_1" 8278 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 8279 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8280 (match_operand:QI 2 "general_operand" "qi,qmi,ri"))) 8281 (clobber (reg:CC FLAGS_REG))] 8282 "ix86_binary_operator_ok (AND, QImode, operands)" 8283 "@ 8284 and{b}\t{%2, %0|%0, %2} 8285 and{b}\t{%2, %0|%0, %2} 8286 and{l}\t{%k2, %k0|%k0, %k2}" 8287 [(set_attr "type" "alu") 8288 (set_attr "mode" "QI,QI,SI")]) 8289 8290(define_insn "*andqi_1_slp" 8291 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 8292 (and:QI (match_dup 0) 8293 (match_operand:QI 1 "general_operand" "qi,qmi"))) 8294 (clobber (reg:CC FLAGS_REG))] 8295 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8296 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8297 "and{b}\t{%1, %0|%0, %1}" 8298 [(set_attr "type" "alu1") 8299 (set_attr "mode" "QI")]) 8300 8301(define_insn "*andqi_2_maybe_si" 8302 [(set (reg FLAGS_REG) 8303 (compare (and:QI 8304 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8305 (match_operand:QI 2 "general_operand" "qim,qi,i")) 8306 (const_int 0))) 8307 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r") 8308 (and:QI (match_dup 1) (match_dup 2)))] 8309 "ix86_binary_operator_ok (AND, QImode, operands) 8310 && ix86_match_ccmode (insn, 8311 GET_CODE (operands[2]) == CONST_INT 8312 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)" 8313{ 8314 if (which_alternative == 2) 8315 { 8316 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) 8317 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); 8318 return "and{l}\t{%2, %k0|%k0, %2}"; 8319 } 8320 return "and{b}\t{%2, %0|%0, %2}"; 8321} 8322 [(set_attr "type" "alu") 8323 (set_attr "mode" "QI,QI,SI")]) 8324 8325(define_insn "*andqi_2" 8326 [(set (reg FLAGS_REG) 8327 (compare (and:QI 8328 (match_operand:QI 1 "nonimmediate_operand" "%0,0") 8329 (match_operand:QI 2 "general_operand" "qim,qi")) 8330 (const_int 0))) 8331 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 8332 (and:QI (match_dup 1) (match_dup 2)))] 8333 "ix86_match_ccmode (insn, CCNOmode) 8334 && ix86_binary_operator_ok (AND, QImode, operands)" 8335 "and{b}\t{%2, %0|%0, %2}" 8336 [(set_attr "type" "alu") 8337 (set_attr "mode" "QI")]) 8338 8339(define_insn "*andqi_2_slp" 8340 [(set (reg FLAGS_REG) 8341 (compare (and:QI 8342 (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 8343 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi")) 8344 (const_int 0))) 8345 (set (strict_low_part (match_dup 0)) 8346 (and:QI (match_dup 0) (match_dup 1)))] 8347 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8348 && ix86_match_ccmode (insn, CCNOmode) 8349 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8350 "and{b}\t{%1, %0|%0, %1}" 8351 [(set_attr "type" "alu1") 8352 (set_attr "mode" "QI")]) 8353 8354;; ??? A bug in recog prevents it from recognizing a const_int as an 8355;; operand to zero_extend in andqi_ext_1. It was checking explicitly 8356;; for a QImode operand, which of course failed. 8357 8358(define_insn "andqi_ext_0" 8359 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8360 (const_int 8) 8361 (const_int 8)) 8362 (and:SI 8363 (zero_extract:SI 8364 (match_operand 1 "ext_register_operand" "0") 8365 (const_int 8) 8366 (const_int 8)) 8367 (match_operand 2 "const_int_operand" "n"))) 8368 (clobber (reg:CC FLAGS_REG))] 8369 "" 8370 "and{b}\t{%2, %h0|%h0, %2}" 8371 [(set_attr "type" "alu") 8372 (set_attr "length_immediate" "1") 8373 (set_attr "mode" "QI")]) 8374 8375;; Generated by peephole translating test to and. This shows up 8376;; often in fp comparisons. 8377 8378(define_insn "*andqi_ext_0_cc" 8379 [(set (reg FLAGS_REG) 8380 (compare 8381 (and:SI 8382 (zero_extract:SI 8383 (match_operand 1 "ext_register_operand" "0") 8384 (const_int 8) 8385 (const_int 8)) 8386 (match_operand 2 "const_int_operand" "n")) 8387 (const_int 0))) 8388 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8389 (const_int 8) 8390 (const_int 8)) 8391 (and:SI 8392 (zero_extract:SI 8393 (match_dup 1) 8394 (const_int 8) 8395 (const_int 8)) 8396 (match_dup 2)))] 8397 "ix86_match_ccmode (insn, CCNOmode)" 8398 "and{b}\t{%2, %h0|%h0, %2}" 8399 [(set_attr "type" "alu") 8400 (set_attr "length_immediate" "1") 8401 (set_attr "mode" "QI")]) 8402 8403(define_insn "*andqi_ext_1" 8404 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8405 (const_int 8) 8406 (const_int 8)) 8407 (and:SI 8408 (zero_extract:SI 8409 (match_operand 1 "ext_register_operand" "0") 8410 (const_int 8) 8411 (const_int 8)) 8412 (zero_extend:SI 8413 (match_operand:QI 2 "general_operand" "Qm")))) 8414 (clobber (reg:CC FLAGS_REG))] 8415 "!TARGET_64BIT" 8416 "and{b}\t{%2, %h0|%h0, %2}" 8417 [(set_attr "type" "alu") 8418 (set_attr "length_immediate" "0") 8419 (set_attr "mode" "QI")]) 8420 8421(define_insn "*andqi_ext_1_rex64" 8422 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8423 (const_int 8) 8424 (const_int 8)) 8425 (and:SI 8426 (zero_extract:SI 8427 (match_operand 1 "ext_register_operand" "0") 8428 (const_int 8) 8429 (const_int 8)) 8430 (zero_extend:SI 8431 (match_operand 2 "ext_register_operand" "Q")))) 8432 (clobber (reg:CC FLAGS_REG))] 8433 "TARGET_64BIT" 8434 "and{b}\t{%2, %h0|%h0, %2}" 8435 [(set_attr "type" "alu") 8436 (set_attr "length_immediate" "0") 8437 (set_attr "mode" "QI")]) 8438 8439(define_insn "*andqi_ext_2" 8440 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8441 (const_int 8) 8442 (const_int 8)) 8443 (and:SI 8444 (zero_extract:SI 8445 (match_operand 1 "ext_register_operand" "%0") 8446 (const_int 8) 8447 (const_int 8)) 8448 (zero_extract:SI 8449 (match_operand 2 "ext_register_operand" "Q") 8450 (const_int 8) 8451 (const_int 8)))) 8452 (clobber (reg:CC FLAGS_REG))] 8453 "" 8454 "and{b}\t{%h2, %h0|%h0, %h2}" 8455 [(set_attr "type" "alu") 8456 (set_attr "length_immediate" "0") 8457 (set_attr "mode" "QI")]) 8458 8459;; Convert wide AND instructions with immediate operand to shorter QImode 8460;; equivalents when possible. 8461;; Don't do the splitting with memory operands, since it introduces risk 8462;; of memory mismatch stalls. We may want to do the splitting for optimizing 8463;; for size, but that can (should?) be handled by generic code instead. 8464(define_split 8465 [(set (match_operand 0 "register_operand" "") 8466 (and (match_operand 1 "register_operand" "") 8467 (match_operand 2 "const_int_operand" ""))) 8468 (clobber (reg:CC FLAGS_REG))] 8469 "reload_completed 8470 && QI_REG_P (operands[0]) 8471 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8472 && !(~INTVAL (operands[2]) & ~(255 << 8)) 8473 && GET_MODE (operands[0]) != QImode" 8474 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8475 (and:SI (zero_extract:SI (match_dup 1) 8476 (const_int 8) (const_int 8)) 8477 (match_dup 2))) 8478 (clobber (reg:CC FLAGS_REG))])] 8479 "operands[0] = gen_lowpart (SImode, operands[0]); 8480 operands[1] = gen_lowpart (SImode, operands[1]); 8481 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") 8482 8483;; Since AND can be encoded with sign extended immediate, this is only 8484;; profitable when 7th bit is not set. 8485(define_split 8486 [(set (match_operand 0 "register_operand" "") 8487 (and (match_operand 1 "general_operand" "") 8488 (match_operand 2 "const_int_operand" ""))) 8489 (clobber (reg:CC FLAGS_REG))] 8490 "reload_completed 8491 && ANY_QI_REG_P (operands[0]) 8492 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8493 && !(~INTVAL (operands[2]) & ~255) 8494 && !(INTVAL (operands[2]) & 128) 8495 && GET_MODE (operands[0]) != QImode" 8496 [(parallel [(set (strict_low_part (match_dup 0)) 8497 (and:QI (match_dup 1) 8498 (match_dup 2))) 8499 (clobber (reg:CC FLAGS_REG))])] 8500 "operands[0] = gen_lowpart (QImode, operands[0]); 8501 operands[1] = gen_lowpart (QImode, operands[1]); 8502 operands[2] = gen_lowpart (QImode, operands[2]);") 8503 8504;; Logical inclusive OR instructions 8505 8506;; %%% This used to optimize known byte-wide and operations to memory. 8507;; If this is considered useful, it should be done with splitters. 8508 8509(define_expand "iordi3" 8510 [(set (match_operand:DI 0 "nonimmediate_operand" "") 8511 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "") 8512 (match_operand:DI 2 "x86_64_general_operand" ""))) 8513 (clobber (reg:CC FLAGS_REG))] 8514 "TARGET_64BIT" 8515 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;") 8516 8517(define_insn "*iordi_1_rex64" 8518 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 8519 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8520 (match_operand:DI 2 "x86_64_general_operand" "re,rme"))) 8521 (clobber (reg:CC FLAGS_REG))] 8522 "TARGET_64BIT 8523 && ix86_binary_operator_ok (IOR, DImode, operands)" 8524 "or{q}\t{%2, %0|%0, %2}" 8525 [(set_attr "type" "alu") 8526 (set_attr "mode" "DI")]) 8527 8528(define_insn "*iordi_2_rex64" 8529 [(set (reg FLAGS_REG) 8530 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8531 (match_operand:DI 2 "x86_64_general_operand" "rem,re")) 8532 (const_int 0))) 8533 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") 8534 (ior:DI (match_dup 1) (match_dup 2)))] 8535 "TARGET_64BIT 8536 && ix86_match_ccmode (insn, CCNOmode) 8537 && ix86_binary_operator_ok (IOR, DImode, operands)" 8538 "or{q}\t{%2, %0|%0, %2}" 8539 [(set_attr "type" "alu") 8540 (set_attr "mode" "DI")]) 8541 8542(define_insn "*iordi_3_rex64" 8543 [(set (reg FLAGS_REG) 8544 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0") 8545 (match_operand:DI 2 "x86_64_general_operand" "rem")) 8546 (const_int 0))) 8547 (clobber (match_scratch:DI 0 "=r"))] 8548 "TARGET_64BIT 8549 && ix86_match_ccmode (insn, CCNOmode) 8550 && ix86_binary_operator_ok (IOR, DImode, operands)" 8551 "or{q}\t{%2, %0|%0, %2}" 8552 [(set_attr "type" "alu") 8553 (set_attr "mode" "DI")]) 8554 8555 8556(define_expand "iorsi3" 8557 [(set (match_operand:SI 0 "nonimmediate_operand" "") 8558 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "") 8559 (match_operand:SI 2 "general_operand" ""))) 8560 (clobber (reg:CC FLAGS_REG))] 8561 "" 8562 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;") 8563 8564(define_insn "*iorsi_1" 8565 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 8566 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8567 (match_operand:SI 2 "general_operand" "ri,rmi"))) 8568 (clobber (reg:CC FLAGS_REG))] 8569 "ix86_binary_operator_ok (IOR, SImode, operands)" 8570 "or{l}\t{%2, %0|%0, %2}" 8571 [(set_attr "type" "alu") 8572 (set_attr "mode" "SI")]) 8573 8574;; See comment for addsi_1_zext why we do use nonimmediate_operand 8575(define_insn "*iorsi_1_zext" 8576 [(set (match_operand:DI 0 "register_operand" "=rm") 8577 (zero_extend:DI 8578 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8579 (match_operand:SI 2 "general_operand" "rim")))) 8580 (clobber (reg:CC FLAGS_REG))] 8581 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)" 8582 "or{l}\t{%2, %k0|%k0, %2}" 8583 [(set_attr "type" "alu") 8584 (set_attr "mode" "SI")]) 8585 8586(define_insn "*iorsi_1_zext_imm" 8587 [(set (match_operand:DI 0 "register_operand" "=rm") 8588 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 8589 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 8590 (clobber (reg:CC FLAGS_REG))] 8591 "TARGET_64BIT" 8592 "or{l}\t{%2, %k0|%k0, %2}" 8593 [(set_attr "type" "alu") 8594 (set_attr "mode" "SI")]) 8595 8596(define_insn "*iorsi_2" 8597 [(set (reg FLAGS_REG) 8598 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8599 (match_operand:SI 2 "general_operand" "rim,ri")) 8600 (const_int 0))) 8601 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 8602 (ior:SI (match_dup 1) (match_dup 2)))] 8603 "ix86_match_ccmode (insn, CCNOmode) 8604 && ix86_binary_operator_ok (IOR, SImode, operands)" 8605 "or{l}\t{%2, %0|%0, %2}" 8606 [(set_attr "type" "alu") 8607 (set_attr "mode" "SI")]) 8608 8609;; See comment for addsi_1_zext why we do use nonimmediate_operand 8610;; ??? Special case for immediate operand is missing - it is tricky. 8611(define_insn "*iorsi_2_zext" 8612 [(set (reg FLAGS_REG) 8613 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8614 (match_operand:SI 2 "general_operand" "rim")) 8615 (const_int 0))) 8616 (set (match_operand:DI 0 "register_operand" "=r") 8617 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))] 8618 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8619 && ix86_binary_operator_ok (IOR, SImode, operands)" 8620 "or{l}\t{%2, %k0|%k0, %2}" 8621 [(set_attr "type" "alu") 8622 (set_attr "mode" "SI")]) 8623 8624(define_insn "*iorsi_2_zext_imm" 8625 [(set (reg FLAGS_REG) 8626 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8627 (match_operand 2 "x86_64_zext_immediate_operand" "Z")) 8628 (const_int 0))) 8629 (set (match_operand:DI 0 "register_operand" "=r") 8630 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 8631 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8632 && ix86_binary_operator_ok (IOR, SImode, operands)" 8633 "or{l}\t{%2, %k0|%k0, %2}" 8634 [(set_attr "type" "alu") 8635 (set_attr "mode" "SI")]) 8636 8637(define_insn "*iorsi_3" 8638 [(set (reg FLAGS_REG) 8639 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8640 (match_operand:SI 2 "general_operand" "rim")) 8641 (const_int 0))) 8642 (clobber (match_scratch:SI 0 "=r"))] 8643 "ix86_match_ccmode (insn, CCNOmode) 8644 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 8645 "or{l}\t{%2, %0|%0, %2}" 8646 [(set_attr "type" "alu") 8647 (set_attr "mode" "SI")]) 8648 8649(define_expand "iorhi3" 8650 [(set (match_operand:HI 0 "nonimmediate_operand" "") 8651 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "") 8652 (match_operand:HI 2 "general_operand" ""))) 8653 (clobber (reg:CC FLAGS_REG))] 8654 "TARGET_HIMODE_MATH" 8655 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;") 8656 8657(define_insn "*iorhi_1" 8658 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m") 8659 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 8660 (match_operand:HI 2 "general_operand" "rmi,ri"))) 8661 (clobber (reg:CC FLAGS_REG))] 8662 "ix86_binary_operator_ok (IOR, HImode, operands)" 8663 "or{w}\t{%2, %0|%0, %2}" 8664 [(set_attr "type" "alu") 8665 (set_attr "mode" "HI")]) 8666 8667(define_insn "*iorhi_2" 8668 [(set (reg FLAGS_REG) 8669 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 8670 (match_operand:HI 2 "general_operand" "rim,ri")) 8671 (const_int 0))) 8672 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 8673 (ior:HI (match_dup 1) (match_dup 2)))] 8674 "ix86_match_ccmode (insn, CCNOmode) 8675 && ix86_binary_operator_ok (IOR, HImode, operands)" 8676 "or{w}\t{%2, %0|%0, %2}" 8677 [(set_attr "type" "alu") 8678 (set_attr "mode" "HI")]) 8679 8680(define_insn "*iorhi_3" 8681 [(set (reg FLAGS_REG) 8682 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0") 8683 (match_operand:HI 2 "general_operand" "rim")) 8684 (const_int 0))) 8685 (clobber (match_scratch:HI 0 "=r"))] 8686 "ix86_match_ccmode (insn, CCNOmode) 8687 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 8688 "or{w}\t{%2, %0|%0, %2}" 8689 [(set_attr "type" "alu") 8690 (set_attr "mode" "HI")]) 8691 8692(define_expand "iorqi3" 8693 [(set (match_operand:QI 0 "nonimmediate_operand" "") 8694 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "") 8695 (match_operand:QI 2 "general_operand" ""))) 8696 (clobber (reg:CC FLAGS_REG))] 8697 "TARGET_QIMODE_MATH" 8698 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;") 8699 8700;; %%% Potential partial reg stall on alternative 2. What to do? 8701(define_insn "*iorqi_1" 8702 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") 8703 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8704 (match_operand:QI 2 "general_operand" "qmi,qi,ri"))) 8705 (clobber (reg:CC FLAGS_REG))] 8706 "ix86_binary_operator_ok (IOR, QImode, operands)" 8707 "@ 8708 or{b}\t{%2, %0|%0, %2} 8709 or{b}\t{%2, %0|%0, %2} 8710 or{l}\t{%k2, %k0|%k0, %k2}" 8711 [(set_attr "type" "alu") 8712 (set_attr "mode" "QI,QI,SI")]) 8713 8714(define_insn "*iorqi_1_slp" 8715 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m")) 8716 (ior:QI (match_dup 0) 8717 (match_operand:QI 1 "general_operand" "qmi,qi"))) 8718 (clobber (reg:CC FLAGS_REG))] 8719 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8720 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8721 "or{b}\t{%1, %0|%0, %1}" 8722 [(set_attr "type" "alu1") 8723 (set_attr "mode" "QI")]) 8724 8725(define_insn "*iorqi_2" 8726 [(set (reg FLAGS_REG) 8727 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 8728 (match_operand:QI 2 "general_operand" "qim,qi")) 8729 (const_int 0))) 8730 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 8731 (ior:QI (match_dup 1) (match_dup 2)))] 8732 "ix86_match_ccmode (insn, CCNOmode) 8733 && ix86_binary_operator_ok (IOR, QImode, operands)" 8734 "or{b}\t{%2, %0|%0, %2}" 8735 [(set_attr "type" "alu") 8736 (set_attr "mode" "QI")]) 8737 8738(define_insn "*iorqi_2_slp" 8739 [(set (reg FLAGS_REG) 8740 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 8741 (match_operand:QI 1 "general_operand" "qim,qi")) 8742 (const_int 0))) 8743 (set (strict_low_part (match_dup 0)) 8744 (ior:QI (match_dup 0) (match_dup 1)))] 8745 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 8746 && ix86_match_ccmode (insn, CCNOmode) 8747 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 8748 "or{b}\t{%1, %0|%0, %1}" 8749 [(set_attr "type" "alu1") 8750 (set_attr "mode" "QI")]) 8751 8752(define_insn "*iorqi_3" 8753 [(set (reg FLAGS_REG) 8754 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 8755 (match_operand:QI 2 "general_operand" "qim")) 8756 (const_int 0))) 8757 (clobber (match_scratch:QI 0 "=q"))] 8758 "ix86_match_ccmode (insn, CCNOmode) 8759 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 8760 "or{b}\t{%2, %0|%0, %2}" 8761 [(set_attr "type" "alu") 8762 (set_attr "mode" "QI")]) 8763 8764(define_insn "iorqi_ext_0" 8765 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8766 (const_int 8) 8767 (const_int 8)) 8768 (ior:SI 8769 (zero_extract:SI 8770 (match_operand 1 "ext_register_operand" "0") 8771 (const_int 8) 8772 (const_int 8)) 8773 (match_operand 2 "const_int_operand" "n"))) 8774 (clobber (reg:CC FLAGS_REG))] 8775 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 8776 "or{b}\t{%2, %h0|%h0, %2}" 8777 [(set_attr "type" "alu") 8778 (set_attr "length_immediate" "1") 8779 (set_attr "mode" "QI")]) 8780 8781(define_insn "*iorqi_ext_1" 8782 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8783 (const_int 8) 8784 (const_int 8)) 8785 (ior:SI 8786 (zero_extract:SI 8787 (match_operand 1 "ext_register_operand" "0") 8788 (const_int 8) 8789 (const_int 8)) 8790 (zero_extend:SI 8791 (match_operand:QI 2 "general_operand" "Qm")))) 8792 (clobber (reg:CC FLAGS_REG))] 8793 "!TARGET_64BIT 8794 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 8795 "or{b}\t{%2, %h0|%h0, %2}" 8796 [(set_attr "type" "alu") 8797 (set_attr "length_immediate" "0") 8798 (set_attr "mode" "QI")]) 8799 8800(define_insn "*iorqi_ext_1_rex64" 8801 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8802 (const_int 8) 8803 (const_int 8)) 8804 (ior:SI 8805 (zero_extract:SI 8806 (match_operand 1 "ext_register_operand" "0") 8807 (const_int 8) 8808 (const_int 8)) 8809 (zero_extend:SI 8810 (match_operand 2 "ext_register_operand" "Q")))) 8811 (clobber (reg:CC FLAGS_REG))] 8812 "TARGET_64BIT 8813 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 8814 "or{b}\t{%2, %h0|%h0, %2}" 8815 [(set_attr "type" "alu") 8816 (set_attr "length_immediate" "0") 8817 (set_attr "mode" "QI")]) 8818 8819(define_insn "*iorqi_ext_2" 8820 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8821 (const_int 8) 8822 (const_int 8)) 8823 (ior:SI 8824 (zero_extract:SI (match_operand 1 "ext_register_operand" "0") 8825 (const_int 8) 8826 (const_int 8)) 8827 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 8828 (const_int 8) 8829 (const_int 8)))) 8830 (clobber (reg:CC FLAGS_REG))] 8831 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 8832 "ior{b}\t{%h2, %h0|%h0, %h2}" 8833 [(set_attr "type" "alu") 8834 (set_attr "length_immediate" "0") 8835 (set_attr "mode" "QI")]) 8836 8837(define_split 8838 [(set (match_operand 0 "register_operand" "") 8839 (ior (match_operand 1 "register_operand" "") 8840 (match_operand 2 "const_int_operand" ""))) 8841 (clobber (reg:CC FLAGS_REG))] 8842 "reload_completed 8843 && QI_REG_P (operands[0]) 8844 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8845 && !(INTVAL (operands[2]) & ~(255 << 8)) 8846 && GET_MODE (operands[0]) != QImode" 8847 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8848 (ior:SI (zero_extract:SI (match_dup 1) 8849 (const_int 8) (const_int 8)) 8850 (match_dup 2))) 8851 (clobber (reg:CC FLAGS_REG))])] 8852 "operands[0] = gen_lowpart (SImode, operands[0]); 8853 operands[1] = gen_lowpart (SImode, operands[1]); 8854 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") 8855 8856;; Since OR can be encoded with sign extended immediate, this is only 8857;; profitable when 7th bit is set. 8858(define_split 8859 [(set (match_operand 0 "register_operand" "") 8860 (ior (match_operand 1 "general_operand" "") 8861 (match_operand 2 "const_int_operand" ""))) 8862 (clobber (reg:CC FLAGS_REG))] 8863 "reload_completed 8864 && ANY_QI_REG_P (operands[0]) 8865 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 8866 && !(INTVAL (operands[2]) & ~255) 8867 && (INTVAL (operands[2]) & 128) 8868 && GET_MODE (operands[0]) != QImode" 8869 [(parallel [(set (strict_low_part (match_dup 0)) 8870 (ior:QI (match_dup 1) 8871 (match_dup 2))) 8872 (clobber (reg:CC FLAGS_REG))])] 8873 "operands[0] = gen_lowpart (QImode, operands[0]); 8874 operands[1] = gen_lowpart (QImode, operands[1]); 8875 operands[2] = gen_lowpart (QImode, operands[2]);") 8876 8877;; Logical XOR instructions 8878 8879;; %%% This used to optimize known byte-wide and operations to memory. 8880;; If this is considered useful, it should be done with splitters. 8881 8882(define_expand "xordi3" 8883 [(set (match_operand:DI 0 "nonimmediate_operand" "") 8884 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "") 8885 (match_operand:DI 2 "x86_64_general_operand" ""))) 8886 (clobber (reg:CC FLAGS_REG))] 8887 "TARGET_64BIT" 8888 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;") 8889 8890(define_insn "*xordi_1_rex64" 8891 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 8892 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8893 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))) 8894 (clobber (reg:CC FLAGS_REG))] 8895 "TARGET_64BIT 8896 && ix86_binary_operator_ok (XOR, DImode, operands)" 8897 "@ 8898 xor{q}\t{%2, %0|%0, %2} 8899 xor{q}\t{%2, %0|%0, %2}" 8900 [(set_attr "type" "alu") 8901 (set_attr "mode" "DI,DI")]) 8902 8903(define_insn "*xordi_2_rex64" 8904 [(set (reg FLAGS_REG) 8905 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") 8906 (match_operand:DI 2 "x86_64_general_operand" "rem,re")) 8907 (const_int 0))) 8908 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm") 8909 (xor:DI (match_dup 1) (match_dup 2)))] 8910 "TARGET_64BIT 8911 && ix86_match_ccmode (insn, CCNOmode) 8912 && ix86_binary_operator_ok (XOR, DImode, operands)" 8913 "@ 8914 xor{q}\t{%2, %0|%0, %2} 8915 xor{q}\t{%2, %0|%0, %2}" 8916 [(set_attr "type" "alu") 8917 (set_attr "mode" "DI,DI")]) 8918 8919(define_insn "*xordi_3_rex64" 8920 [(set (reg FLAGS_REG) 8921 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0") 8922 (match_operand:DI 2 "x86_64_general_operand" "rem")) 8923 (const_int 0))) 8924 (clobber (match_scratch:DI 0 "=r"))] 8925 "TARGET_64BIT 8926 && ix86_match_ccmode (insn, CCNOmode) 8927 && ix86_binary_operator_ok (XOR, DImode, operands)" 8928 "xor{q}\t{%2, %0|%0, %2}" 8929 [(set_attr "type" "alu") 8930 (set_attr "mode" "DI")]) 8931 8932(define_expand "xorsi3" 8933 [(set (match_operand:SI 0 "nonimmediate_operand" "") 8934 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "") 8935 (match_operand:SI 2 "general_operand" ""))) 8936 (clobber (reg:CC FLAGS_REG))] 8937 "" 8938 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;") 8939 8940(define_insn "*xorsi_1" 8941 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 8942 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8943 (match_operand:SI 2 "general_operand" "ri,rm"))) 8944 (clobber (reg:CC FLAGS_REG))] 8945 "ix86_binary_operator_ok (XOR, SImode, operands)" 8946 "xor{l}\t{%2, %0|%0, %2}" 8947 [(set_attr "type" "alu") 8948 (set_attr "mode" "SI")]) 8949 8950;; See comment for addsi_1_zext why we do use nonimmediate_operand 8951;; Add speccase for immediates 8952(define_insn "*xorsi_1_zext" 8953 [(set (match_operand:DI 0 "register_operand" "=r") 8954 (zero_extend:DI 8955 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8956 (match_operand:SI 2 "general_operand" "rim")))) 8957 (clobber (reg:CC FLAGS_REG))] 8958 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)" 8959 "xor{l}\t{%2, %k0|%k0, %2}" 8960 [(set_attr "type" "alu") 8961 (set_attr "mode" "SI")]) 8962 8963(define_insn "*xorsi_1_zext_imm" 8964 [(set (match_operand:DI 0 "register_operand" "=r") 8965 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 8966 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 8967 (clobber (reg:CC FLAGS_REG))] 8968 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)" 8969 "xor{l}\t{%2, %k0|%k0, %2}" 8970 [(set_attr "type" "alu") 8971 (set_attr "mode" "SI")]) 8972 8973(define_insn "*xorsi_2" 8974 [(set (reg FLAGS_REG) 8975 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 8976 (match_operand:SI 2 "general_operand" "rim,ri")) 8977 (const_int 0))) 8978 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") 8979 (xor:SI (match_dup 1) (match_dup 2)))] 8980 "ix86_match_ccmode (insn, CCNOmode) 8981 && ix86_binary_operator_ok (XOR, SImode, operands)" 8982 "xor{l}\t{%2, %0|%0, %2}" 8983 [(set_attr "type" "alu") 8984 (set_attr "mode" "SI")]) 8985 8986;; See comment for addsi_1_zext why we do use nonimmediate_operand 8987;; ??? Special case for immediate operand is missing - it is tricky. 8988(define_insn "*xorsi_2_zext" 8989 [(set (reg FLAGS_REG) 8990 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8991 (match_operand:SI 2 "general_operand" "rim")) 8992 (const_int 0))) 8993 (set (match_operand:DI 0 "register_operand" "=r") 8994 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))] 8995 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8996 && ix86_binary_operator_ok (XOR, SImode, operands)" 8997 "xor{l}\t{%2, %k0|%k0, %2}" 8998 [(set_attr "type" "alu") 8999 (set_attr "mode" "SI")]) 9000 9001(define_insn "*xorsi_2_zext_imm" 9002 [(set (reg FLAGS_REG) 9003 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9004 (match_operand 2 "x86_64_zext_immediate_operand" "Z")) 9005 (const_int 0))) 9006 (set (match_operand:DI 0 "register_operand" "=r") 9007 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 9008 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9009 && ix86_binary_operator_ok (XOR, SImode, operands)" 9010 "xor{l}\t{%2, %k0|%k0, %2}" 9011 [(set_attr "type" "alu") 9012 (set_attr "mode" "SI")]) 9013 9014(define_insn "*xorsi_3" 9015 [(set (reg FLAGS_REG) 9016 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9017 (match_operand:SI 2 "general_operand" "rim")) 9018 (const_int 0))) 9019 (clobber (match_scratch:SI 0 "=r"))] 9020 "ix86_match_ccmode (insn, CCNOmode) 9021 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 9022 "xor{l}\t{%2, %0|%0, %2}" 9023 [(set_attr "type" "alu") 9024 (set_attr "mode" "SI")]) 9025 9026(define_expand "xorhi3" 9027 [(set (match_operand:HI 0 "nonimmediate_operand" "") 9028 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "") 9029 (match_operand:HI 2 "general_operand" ""))) 9030 (clobber (reg:CC FLAGS_REG))] 9031 "TARGET_HIMODE_MATH" 9032 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;") 9033 9034(define_insn "*xorhi_1" 9035 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m") 9036 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 9037 (match_operand:HI 2 "general_operand" "rmi,ri"))) 9038 (clobber (reg:CC FLAGS_REG))] 9039 "ix86_binary_operator_ok (XOR, HImode, operands)" 9040 "xor{w}\t{%2, %0|%0, %2}" 9041 [(set_attr "type" "alu") 9042 (set_attr "mode" "HI")]) 9043 9044(define_insn "*xorhi_2" 9045 [(set (reg FLAGS_REG) 9046 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 9047 (match_operand:HI 2 "general_operand" "rim,ri")) 9048 (const_int 0))) 9049 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm") 9050 (xor:HI (match_dup 1) (match_dup 2)))] 9051 "ix86_match_ccmode (insn, CCNOmode) 9052 && ix86_binary_operator_ok (XOR, HImode, operands)" 9053 "xor{w}\t{%2, %0|%0, %2}" 9054 [(set_attr "type" "alu") 9055 (set_attr "mode" "HI")]) 9056 9057(define_insn "*xorhi_3" 9058 [(set (reg FLAGS_REG) 9059 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0") 9060 (match_operand:HI 2 "general_operand" "rim")) 9061 (const_int 0))) 9062 (clobber (match_scratch:HI 0 "=r"))] 9063 "ix86_match_ccmode (insn, CCNOmode) 9064 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 9065 "xor{w}\t{%2, %0|%0, %2}" 9066 [(set_attr "type" "alu") 9067 (set_attr "mode" "HI")]) 9068 9069(define_expand "xorqi3" 9070 [(set (match_operand:QI 0 "nonimmediate_operand" "") 9071 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "") 9072 (match_operand:QI 2 "general_operand" ""))) 9073 (clobber (reg:CC FLAGS_REG))] 9074 "TARGET_QIMODE_MATH" 9075 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;") 9076 9077;; %%% Potential partial reg stall on alternative 2. What to do? 9078(define_insn "*xorqi_1" 9079 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") 9080 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 9081 (match_operand:QI 2 "general_operand" "qmi,qi,ri"))) 9082 (clobber (reg:CC FLAGS_REG))] 9083 "ix86_binary_operator_ok (XOR, QImode, operands)" 9084 "@ 9085 xor{b}\t{%2, %0|%0, %2} 9086 xor{b}\t{%2, %0|%0, %2} 9087 xor{l}\t{%k2, %k0|%k0, %k2}" 9088 [(set_attr "type" "alu") 9089 (set_attr "mode" "QI,QI,SI")]) 9090 9091(define_insn "*xorqi_1_slp" 9092 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 9093 (xor:QI (match_dup 0) 9094 (match_operand:QI 1 "general_operand" "qi,qmi"))) 9095 (clobber (reg:CC FLAGS_REG))] 9096 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 9097 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 9098 "xor{b}\t{%1, %0|%0, %1}" 9099 [(set_attr "type" "alu1") 9100 (set_attr "mode" "QI")]) 9101 9102(define_insn "xorqi_ext_0" 9103 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9104 (const_int 8) 9105 (const_int 8)) 9106 (xor:SI 9107 (zero_extract:SI 9108 (match_operand 1 "ext_register_operand" "0") 9109 (const_int 8) 9110 (const_int 8)) 9111 (match_operand 2 "const_int_operand" "n"))) 9112 (clobber (reg:CC FLAGS_REG))] 9113 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 9114 "xor{b}\t{%2, %h0|%h0, %2}" 9115 [(set_attr "type" "alu") 9116 (set_attr "length_immediate" "1") 9117 (set_attr "mode" "QI")]) 9118 9119(define_insn "*xorqi_ext_1" 9120 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9121 (const_int 8) 9122 (const_int 8)) 9123 (xor:SI 9124 (zero_extract:SI 9125 (match_operand 1 "ext_register_operand" "0") 9126 (const_int 8) 9127 (const_int 8)) 9128 (zero_extend:SI 9129 (match_operand:QI 2 "general_operand" "Qm")))) 9130 (clobber (reg:CC FLAGS_REG))] 9131 "!TARGET_64BIT 9132 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 9133 "xor{b}\t{%2, %h0|%h0, %2}" 9134 [(set_attr "type" "alu") 9135 (set_attr "length_immediate" "0") 9136 (set_attr "mode" "QI")]) 9137 9138(define_insn "*xorqi_ext_1_rex64" 9139 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9140 (const_int 8) 9141 (const_int 8)) 9142 (xor:SI 9143 (zero_extract:SI 9144 (match_operand 1 "ext_register_operand" "0") 9145 (const_int 8) 9146 (const_int 8)) 9147 (zero_extend:SI 9148 (match_operand 2 "ext_register_operand" "Q")))) 9149 (clobber (reg:CC FLAGS_REG))] 9150 "TARGET_64BIT 9151 && (!TARGET_PARTIAL_REG_STALL || optimize_size)" 9152 "xor{b}\t{%2, %h0|%h0, %2}" 9153 [(set_attr "type" "alu") 9154 (set_attr "length_immediate" "0") 9155 (set_attr "mode" "QI")]) 9156 9157(define_insn "*xorqi_ext_2" 9158 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9159 (const_int 8) 9160 (const_int 8)) 9161 (xor:SI 9162 (zero_extract:SI (match_operand 1 "ext_register_operand" "0") 9163 (const_int 8) 9164 (const_int 8)) 9165 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 9166 (const_int 8) 9167 (const_int 8)))) 9168 (clobber (reg:CC FLAGS_REG))] 9169 "(!TARGET_PARTIAL_REG_STALL || optimize_size)" 9170 "xor{b}\t{%h2, %h0|%h0, %h2}" 9171 [(set_attr "type" "alu") 9172 (set_attr "length_immediate" "0") 9173 (set_attr "mode" "QI")]) 9174 9175(define_insn "*xorqi_cc_1" 9176 [(set (reg FLAGS_REG) 9177 (compare 9178 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 9179 (match_operand:QI 2 "general_operand" "qim,qi")) 9180 (const_int 0))) 9181 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm") 9182 (xor:QI (match_dup 1) (match_dup 2)))] 9183 "ix86_match_ccmode (insn, CCNOmode) 9184 && ix86_binary_operator_ok (XOR, QImode, operands)" 9185 "xor{b}\t{%2, %0|%0, %2}" 9186 [(set_attr "type" "alu") 9187 (set_attr "mode" "QI")]) 9188 9189(define_insn "*xorqi_2_slp" 9190 [(set (reg FLAGS_REG) 9191 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 9192 (match_operand:QI 1 "general_operand" "qim,qi")) 9193 (const_int 0))) 9194 (set (strict_low_part (match_dup 0)) 9195 (xor:QI (match_dup 0) (match_dup 1)))] 9196 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 9197 && ix86_match_ccmode (insn, CCNOmode) 9198 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 9199 "xor{b}\t{%1, %0|%0, %1}" 9200 [(set_attr "type" "alu1") 9201 (set_attr "mode" "QI")]) 9202 9203(define_insn "*xorqi_cc_2" 9204 [(set (reg FLAGS_REG) 9205 (compare 9206 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 9207 (match_operand:QI 2 "general_operand" "qim")) 9208 (const_int 0))) 9209 (clobber (match_scratch:QI 0 "=q"))] 9210 "ix86_match_ccmode (insn, CCNOmode) 9211 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 9212 "xor{b}\t{%2, %0|%0, %2}" 9213 [(set_attr "type" "alu") 9214 (set_attr "mode" "QI")]) 9215 9216(define_insn "*xorqi_cc_ext_1" 9217 [(set (reg FLAGS_REG) 9218 (compare 9219 (xor:SI 9220 (zero_extract:SI 9221 (match_operand 1 "ext_register_operand" "0") 9222 (const_int 8) 9223 (const_int 8)) 9224 (match_operand:QI 2 "general_operand" "qmn")) 9225 (const_int 0))) 9226 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q") 9227 (const_int 8) 9228 (const_int 8)) 9229 (xor:SI 9230 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) 9231 (match_dup 2)))] 9232 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 9233 "xor{b}\t{%2, %h0|%h0, %2}" 9234 [(set_attr "type" "alu") 9235 (set_attr "mode" "QI")]) 9236 9237(define_insn "*xorqi_cc_ext_1_rex64" 9238 [(set (reg FLAGS_REG) 9239 (compare 9240 (xor:SI 9241 (zero_extract:SI 9242 (match_operand 1 "ext_register_operand" "0") 9243 (const_int 8) 9244 (const_int 8)) 9245 (match_operand:QI 2 "nonmemory_operand" "Qn")) 9246 (const_int 0))) 9247 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 9248 (const_int 8) 9249 (const_int 8)) 9250 (xor:SI 9251 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) 9252 (match_dup 2)))] 9253 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 9254 "xor{b}\t{%2, %h0|%h0, %2}" 9255 [(set_attr "type" "alu") 9256 (set_attr "mode" "QI")]) 9257 9258(define_expand "xorqi_cc_ext_1" 9259 [(parallel [ 9260 (set (reg:CCNO FLAGS_REG) 9261 (compare:CCNO 9262 (xor:SI 9263 (zero_extract:SI 9264 (match_operand 1 "ext_register_operand" "") 9265 (const_int 8) 9266 (const_int 8)) 9267 (match_operand:QI 2 "general_operand" "")) 9268 (const_int 0))) 9269 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "") 9270 (const_int 8) 9271 (const_int 8)) 9272 (xor:SI 9273 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8)) 9274 (match_dup 2)))])] 9275 "" 9276 "") 9277 9278(define_split 9279 [(set (match_operand 0 "register_operand" "") 9280 (xor (match_operand 1 "register_operand" "") 9281 (match_operand 2 "const_int_operand" ""))) 9282 (clobber (reg:CC FLAGS_REG))] 9283 "reload_completed 9284 && QI_REG_P (operands[0]) 9285 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 9286 && !(INTVAL (operands[2]) & ~(255 << 8)) 9287 && GET_MODE (operands[0]) != QImode" 9288 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 9289 (xor:SI (zero_extract:SI (match_dup 1) 9290 (const_int 8) (const_int 8)) 9291 (match_dup 2))) 9292 (clobber (reg:CC FLAGS_REG))])] 9293 "operands[0] = gen_lowpart (SImode, operands[0]); 9294 operands[1] = gen_lowpart (SImode, operands[1]); 9295 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);") 9296 9297;; Since XOR can be encoded with sign extended immediate, this is only 9298;; profitable when 7th bit is set. 9299(define_split 9300 [(set (match_operand 0 "register_operand" "") 9301 (xor (match_operand 1 "general_operand" "") 9302 (match_operand 2 "const_int_operand" ""))) 9303 (clobber (reg:CC FLAGS_REG))] 9304 "reload_completed 9305 && ANY_QI_REG_P (operands[0]) 9306 && (!TARGET_PARTIAL_REG_STALL || optimize_size) 9307 && !(INTVAL (operands[2]) & ~255) 9308 && (INTVAL (operands[2]) & 128) 9309 && GET_MODE (operands[0]) != QImode" 9310 [(parallel [(set (strict_low_part (match_dup 0)) 9311 (xor:QI (match_dup 1) 9312 (match_dup 2))) 9313 (clobber (reg:CC FLAGS_REG))])] 9314 "operands[0] = gen_lowpart (QImode, operands[0]); 9315 operands[1] = gen_lowpart (QImode, operands[1]); 9316 operands[2] = gen_lowpart (QImode, operands[2]);") 9317 9318;; Negation instructions 9319 9320(define_expand "negti2" 9321 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "") 9322 (neg:TI (match_operand:TI 1 "nonimmediate_operand" ""))) 9323 (clobber (reg:CC FLAGS_REG))])] 9324 "TARGET_64BIT" 9325 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;") 9326 9327(define_insn "*negti2_1" 9328 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro") 9329 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0"))) 9330 (clobber (reg:CC FLAGS_REG))] 9331 "TARGET_64BIT 9332 && ix86_unary_operator_ok (NEG, TImode, operands)" 9333 "#") 9334 9335(define_split 9336 [(set (match_operand:TI 0 "nonimmediate_operand" "") 9337 (neg:TI (match_operand:TI 1 "nonimmediate_operand" ""))) 9338 (clobber (reg:CC FLAGS_REG))] 9339 "TARGET_64BIT && reload_completed" 9340 [(parallel 9341 [(set (reg:CCZ FLAGS_REG) 9342 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0))) 9343 (set (match_dup 0) (neg:DI (match_dup 2)))]) 9344 (parallel 9345 [(set (match_dup 1) 9346 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0)) 9347 (match_dup 3)) 9348 (const_int 0))) 9349 (clobber (reg:CC FLAGS_REG))]) 9350 (parallel 9351 [(set (match_dup 1) 9352 (neg:DI (match_dup 1))) 9353 (clobber (reg:CC FLAGS_REG))])] 9354 "split_ti (operands+1, 1, operands+2, operands+3); 9355 split_ti (operands+0, 1, operands+0, operands+1);") 9356 9357(define_expand "negdi2" 9358 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 9359 (neg:DI (match_operand:DI 1 "nonimmediate_operand" ""))) 9360 (clobber (reg:CC FLAGS_REG))])] 9361 "" 9362 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;") 9363 9364(define_insn "*negdi2_1" 9365 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro") 9366 (neg:DI (match_operand:DI 1 "general_operand" "0"))) 9367 (clobber (reg:CC FLAGS_REG))] 9368 "!TARGET_64BIT 9369 && ix86_unary_operator_ok (NEG, DImode, operands)" 9370 "#") 9371 9372(define_split 9373 [(set (match_operand:DI 0 "nonimmediate_operand" "") 9374 (neg:DI (match_operand:DI 1 "general_operand" ""))) 9375 (clobber (reg:CC FLAGS_REG))] 9376 "!TARGET_64BIT && reload_completed" 9377 [(parallel 9378 [(set (reg:CCZ FLAGS_REG) 9379 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0))) 9380 (set (match_dup 0) (neg:SI (match_dup 2)))]) 9381 (parallel 9382 [(set (match_dup 1) 9383 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0)) 9384 (match_dup 3)) 9385 (const_int 0))) 9386 (clobber (reg:CC FLAGS_REG))]) 9387 (parallel 9388 [(set (match_dup 1) 9389 (neg:SI (match_dup 1))) 9390 (clobber (reg:CC FLAGS_REG))])] 9391 "split_di (operands+1, 1, operands+2, operands+3); 9392 split_di (operands+0, 1, operands+0, operands+1);") 9393 9394(define_insn "*negdi2_1_rex64" 9395 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9396 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))) 9397 (clobber (reg:CC FLAGS_REG))] 9398 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)" 9399 "neg{q}\t%0" 9400 [(set_attr "type" "negnot") 9401 (set_attr "mode" "DI")]) 9402 9403;; The problem with neg is that it does not perform (compare x 0), 9404;; it really performs (compare 0 x), which leaves us with the zero 9405;; flag being the only useful item. 9406 9407(define_insn "*negdi2_cmpz_rex64" 9408 [(set (reg:CCZ FLAGS_REG) 9409 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")) 9410 (const_int 0))) 9411 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9412 (neg:DI (match_dup 1)))] 9413 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)" 9414 "neg{q}\t%0" 9415 [(set_attr "type" "negnot") 9416 (set_attr "mode" "DI")]) 9417 9418 9419(define_expand "negsi2" 9420 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 9421 (neg:SI (match_operand:SI 1 "nonimmediate_operand" ""))) 9422 (clobber (reg:CC FLAGS_REG))])] 9423 "" 9424 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;") 9425 9426(define_insn "*negsi2_1" 9427 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 9428 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))) 9429 (clobber (reg:CC FLAGS_REG))] 9430 "ix86_unary_operator_ok (NEG, SImode, operands)" 9431 "neg{l}\t%0" 9432 [(set_attr "type" "negnot") 9433 (set_attr "mode" "SI")]) 9434 9435;; Combine is quite creative about this pattern. 9436(define_insn "*negsi2_1_zext" 9437 [(set (match_operand:DI 0 "register_operand" "=r") 9438 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0") 9439 (const_int 32))) 9440 (const_int 32))) 9441 (clobber (reg:CC FLAGS_REG))] 9442 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9443 "neg{l}\t%k0" 9444 [(set_attr "type" "negnot") 9445 (set_attr "mode" "SI")]) 9446 9447;; The problem with neg is that it does not perform (compare x 0), 9448;; it really performs (compare 0 x), which leaves us with the zero 9449;; flag being the only useful item. 9450 9451(define_insn "*negsi2_cmpz" 9452 [(set (reg:CCZ FLAGS_REG) 9453 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")) 9454 (const_int 0))) 9455 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 9456 (neg:SI (match_dup 1)))] 9457 "ix86_unary_operator_ok (NEG, SImode, operands)" 9458 "neg{l}\t%0" 9459 [(set_attr "type" "negnot") 9460 (set_attr "mode" "SI")]) 9461 9462(define_insn "*negsi2_cmpz_zext" 9463 [(set (reg:CCZ FLAGS_REG) 9464 (compare:CCZ (lshiftrt:DI 9465 (neg:DI (ashift:DI 9466 (match_operand:DI 1 "register_operand" "0") 9467 (const_int 32))) 9468 (const_int 32)) 9469 (const_int 0))) 9470 (set (match_operand:DI 0 "register_operand" "=r") 9471 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1) 9472 (const_int 32))) 9473 (const_int 32)))] 9474 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9475 "neg{l}\t%k0" 9476 [(set_attr "type" "negnot") 9477 (set_attr "mode" "SI")]) 9478 9479(define_expand "neghi2" 9480 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") 9481 (neg:HI (match_operand:HI 1 "nonimmediate_operand" ""))) 9482 (clobber (reg:CC FLAGS_REG))])] 9483 "TARGET_HIMODE_MATH" 9484 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;") 9485 9486(define_insn "*neghi2_1" 9487 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 9488 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))) 9489 (clobber (reg:CC FLAGS_REG))] 9490 "ix86_unary_operator_ok (NEG, HImode, operands)" 9491 "neg{w}\t%0" 9492 [(set_attr "type" "negnot") 9493 (set_attr "mode" "HI")]) 9494 9495(define_insn "*neghi2_cmpz" 9496 [(set (reg:CCZ FLAGS_REG) 9497 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")) 9498 (const_int 0))) 9499 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 9500 (neg:HI (match_dup 1)))] 9501 "ix86_unary_operator_ok (NEG, HImode, operands)" 9502 "neg{w}\t%0" 9503 [(set_attr "type" "negnot") 9504 (set_attr "mode" "HI")]) 9505 9506(define_expand "negqi2" 9507 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "") 9508 (neg:QI (match_operand:QI 1 "nonimmediate_operand" ""))) 9509 (clobber (reg:CC FLAGS_REG))])] 9510 "TARGET_QIMODE_MATH" 9511 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;") 9512 9513(define_insn "*negqi2_1" 9514 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 9515 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))) 9516 (clobber (reg:CC FLAGS_REG))] 9517 "ix86_unary_operator_ok (NEG, QImode, operands)" 9518 "neg{b}\t%0" 9519 [(set_attr "type" "negnot") 9520 (set_attr "mode" "QI")]) 9521 9522(define_insn "*negqi2_cmpz" 9523 [(set (reg:CCZ FLAGS_REG) 9524 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")) 9525 (const_int 0))) 9526 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 9527 (neg:QI (match_dup 1)))] 9528 "ix86_unary_operator_ok (NEG, QImode, operands)" 9529 "neg{b}\t%0" 9530 [(set_attr "type" "negnot") 9531 (set_attr "mode" "QI")]) 9532 9533;; Changing of sign for FP values is doable using integer unit too. 9534 9535(define_expand "negsf2" 9536 [(set (match_operand:SF 0 "nonimmediate_operand" "") 9537 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))] 9538 "TARGET_80387 || TARGET_SSE_MATH" 9539 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;") 9540 9541(define_expand "abssf2" 9542 [(set (match_operand:SF 0 "nonimmediate_operand" "") 9543 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))] 9544 "TARGET_80387 || TARGET_SSE_MATH" 9545 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;") 9546 9547(define_insn "*absnegsf2_mixed" 9548 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm") 9549 (match_operator:SF 3 "absneg_operator" 9550 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")])) 9551 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X ")) 9552 (clobber (reg:CC FLAGS_REG))] 9553 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387 9554 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)" 9555 "#") 9556 9557(define_insn "*absnegsf2_sse" 9558 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm") 9559 (match_operator:SF 3 "absneg_operator" 9560 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")])) 9561 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X")) 9562 (clobber (reg:CC FLAGS_REG))] 9563 "TARGET_SSE_MATH 9564 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)" 9565 "#") 9566 9567(define_insn "*absnegsf2_i387" 9568 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm") 9569 (match_operator:SF 3 "absneg_operator" 9570 [(match_operand:SF 1 "nonimmediate_operand" "0,0")])) 9571 (use (match_operand 2 "" "")) 9572 (clobber (reg:CC FLAGS_REG))] 9573 "TARGET_80387 && !TARGET_SSE_MATH 9574 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)" 9575 "#") 9576 9577(define_expand "copysignsf3" 9578 [(match_operand:SF 0 "register_operand" "") 9579 (match_operand:SF 1 "nonmemory_operand" "") 9580 (match_operand:SF 2 "register_operand" "")] 9581 "TARGET_SSE_MATH" 9582{ 9583 ix86_expand_copysign (operands); 9584 DONE; 9585}) 9586 9587(define_insn_and_split "copysignsf3_const" 9588 [(set (match_operand:SF 0 "register_operand" "=x") 9589 (unspec:SF 9590 [(match_operand:V4SF 1 "vector_move_operand" "xmC") 9591 (match_operand:SF 2 "register_operand" "0") 9592 (match_operand:V4SF 3 "nonimmediate_operand" "xm")] 9593 UNSPEC_COPYSIGN))] 9594 "TARGET_SSE_MATH" 9595 "#" 9596 "&& reload_completed" 9597 [(const_int 0)] 9598{ 9599 ix86_split_copysign_const (operands); 9600 DONE; 9601}) 9602 9603(define_insn "copysignsf3_var" 9604 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x") 9605 (unspec:SF 9606 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x") 9607 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x") 9608 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0") 9609 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")] 9610 UNSPEC_COPYSIGN)) 9611 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))] 9612 "TARGET_SSE_MATH" 9613 "#") 9614 9615(define_split 9616 [(set (match_operand:SF 0 "register_operand" "") 9617 (unspec:SF 9618 [(match_operand:SF 2 "register_operand" "") 9619 (match_operand:SF 3 "register_operand" "") 9620 (match_operand:V4SF 4 "" "") 9621 (match_operand:V4SF 5 "" "")] 9622 UNSPEC_COPYSIGN)) 9623 (clobber (match_scratch:V4SF 1 ""))] 9624 "TARGET_SSE_MATH && reload_completed" 9625 [(const_int 0)] 9626{ 9627 ix86_split_copysign_var (operands); 9628 DONE; 9629}) 9630 9631(define_expand "negdf2" 9632 [(set (match_operand:DF 0 "nonimmediate_operand" "") 9633 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))] 9634 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 9635 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;") 9636 9637(define_expand "absdf2" 9638 [(set (match_operand:DF 0 "nonimmediate_operand" "") 9639 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))] 9640 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 9641 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;") 9642 9643(define_insn "*absnegdf2_mixed" 9644 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm") 9645 (match_operator:DF 3 "absneg_operator" 9646 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")])) 9647 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X")) 9648 (clobber (reg:CC FLAGS_REG))] 9649 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387 9650 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)" 9651 "#") 9652 9653(define_insn "*absnegdf2_sse" 9654 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm") 9655 (match_operator:DF 3 "absneg_operator" 9656 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")])) 9657 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X ")) 9658 (clobber (reg:CC FLAGS_REG))] 9659 "TARGET_SSE2 && TARGET_SSE_MATH 9660 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)" 9661 "#") 9662 9663(define_insn "*absnegdf2_i387" 9664 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm") 9665 (match_operator:DF 3 "absneg_operator" 9666 [(match_operand:DF 1 "nonimmediate_operand" "0,0")])) 9667 (use (match_operand 2 "" "")) 9668 (clobber (reg:CC FLAGS_REG))] 9669 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH) 9670 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)" 9671 "#") 9672 9673(define_expand "copysigndf3" 9674 [(match_operand:DF 0 "register_operand" "") 9675 (match_operand:DF 1 "nonmemory_operand" "") 9676 (match_operand:DF 2 "register_operand" "")] 9677 "TARGET_SSE2 && TARGET_SSE_MATH" 9678{ 9679 ix86_expand_copysign (operands); 9680 DONE; 9681}) 9682 9683(define_insn_and_split "copysigndf3_const" 9684 [(set (match_operand:DF 0 "register_operand" "=x") 9685 (unspec:DF 9686 [(match_operand:V2DF 1 "vector_move_operand" "xmC") 9687 (match_operand:DF 2 "register_operand" "0") 9688 (match_operand:V2DF 3 "nonimmediate_operand" "xm")] 9689 UNSPEC_COPYSIGN))] 9690 "TARGET_SSE2 && TARGET_SSE_MATH" 9691 "#" 9692 "&& reload_completed" 9693 [(const_int 0)] 9694{ 9695 ix86_split_copysign_const (operands); 9696 DONE; 9697}) 9698 9699(define_insn "copysigndf3_var" 9700 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x") 9701 (unspec:DF 9702 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x") 9703 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x") 9704 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0") 9705 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")] 9706 UNSPEC_COPYSIGN)) 9707 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))] 9708 "TARGET_SSE2 && TARGET_SSE_MATH" 9709 "#") 9710 9711(define_split 9712 [(set (match_operand:DF 0 "register_operand" "") 9713 (unspec:DF 9714 [(match_operand:DF 2 "register_operand" "") 9715 (match_operand:DF 3 "register_operand" "") 9716 (match_operand:V2DF 4 "" "") 9717 (match_operand:V2DF 5 "" "")] 9718 UNSPEC_COPYSIGN)) 9719 (clobber (match_scratch:V2DF 1 ""))] 9720 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed" 9721 [(const_int 0)] 9722{ 9723 ix86_split_copysign_var (operands); 9724 DONE; 9725}) 9726 9727(define_expand "negxf2" 9728 [(set (match_operand:XF 0 "nonimmediate_operand" "") 9729 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))] 9730 "TARGET_80387" 9731 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;") 9732 9733(define_expand "absxf2" 9734 [(set (match_operand:XF 0 "nonimmediate_operand" "") 9735 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))] 9736 "TARGET_80387" 9737 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;") 9738 9739(define_insn "*absnegxf2_i387" 9740 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm") 9741 (match_operator:XF 3 "absneg_operator" 9742 [(match_operand:XF 1 "nonimmediate_operand" "0,0")])) 9743 (use (match_operand 2 "" "")) 9744 (clobber (reg:CC FLAGS_REG))] 9745 "TARGET_80387 9746 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)" 9747 "#") 9748 9749;; Splitters for fp abs and neg. 9750 9751(define_split 9752 [(set (match_operand 0 "fp_register_operand" "") 9753 (match_operator 1 "absneg_operator" [(match_dup 0)])) 9754 (use (match_operand 2 "" "")) 9755 (clobber (reg:CC FLAGS_REG))] 9756 "reload_completed" 9757 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))]) 9758 9759(define_split 9760 [(set (match_operand 0 "register_operand" "") 9761 (match_operator 3 "absneg_operator" 9762 [(match_operand 1 "register_operand" "")])) 9763 (use (match_operand 2 "nonimmediate_operand" "")) 9764 (clobber (reg:CC FLAGS_REG))] 9765 "reload_completed && SSE_REG_P (operands[0])" 9766 [(set (match_dup 0) (match_dup 3))] 9767{ 9768 enum machine_mode mode = GET_MODE (operands[0]); 9769 enum machine_mode vmode = GET_MODE (operands[2]); 9770 rtx tmp; 9771 9772 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0); 9773 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0); 9774 if (operands_match_p (operands[0], operands[2])) 9775 { 9776 tmp = operands[1]; 9777 operands[1] = operands[2]; 9778 operands[2] = tmp; 9779 } 9780 if (GET_CODE (operands[3]) == ABS) 9781 tmp = gen_rtx_AND (vmode, operands[1], operands[2]); 9782 else 9783 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]); 9784 operands[3] = tmp; 9785}) 9786 9787(define_split 9788 [(set (match_operand:SF 0 "register_operand" "") 9789 (match_operator:SF 1 "absneg_operator" [(match_dup 0)])) 9790 (use (match_operand:V4SF 2 "" "")) 9791 (clobber (reg:CC FLAGS_REG))] 9792 "reload_completed" 9793 [(parallel [(set (match_dup 0) (match_dup 1)) 9794 (clobber (reg:CC FLAGS_REG))])] 9795{ 9796 rtx tmp; 9797 operands[0] = gen_lowpart (SImode, operands[0]); 9798 if (GET_CODE (operands[1]) == ABS) 9799 { 9800 tmp = gen_int_mode (0x7fffffff, SImode); 9801 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9802 } 9803 else 9804 { 9805 tmp = gen_int_mode (0x80000000, SImode); 9806 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 9807 } 9808 operands[1] = tmp; 9809}) 9810 9811(define_split 9812 [(set (match_operand:DF 0 "register_operand" "") 9813 (match_operator:DF 1 "absneg_operator" [(match_dup 0)])) 9814 (use (match_operand 2 "" "")) 9815 (clobber (reg:CC FLAGS_REG))] 9816 "reload_completed" 9817 [(parallel [(set (match_dup 0) (match_dup 1)) 9818 (clobber (reg:CC FLAGS_REG))])] 9819{ 9820 rtx tmp; 9821 if (TARGET_64BIT) 9822 { 9823 tmp = gen_lowpart (DImode, operands[0]); 9824 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63)); 9825 operands[0] = tmp; 9826 9827 if (GET_CODE (operands[1]) == ABS) 9828 tmp = const0_rtx; 9829 else 9830 tmp = gen_rtx_NOT (DImode, tmp); 9831 } 9832 else 9833 { 9834 operands[0] = gen_highpart (SImode, operands[0]); 9835 if (GET_CODE (operands[1]) == ABS) 9836 { 9837 tmp = gen_int_mode (0x7fffffff, SImode); 9838 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9839 } 9840 else 9841 { 9842 tmp = gen_int_mode (0x80000000, SImode); 9843 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 9844 } 9845 } 9846 operands[1] = tmp; 9847}) 9848 9849(define_split 9850 [(set (match_operand:XF 0 "register_operand" "") 9851 (match_operator:XF 1 "absneg_operator" [(match_dup 0)])) 9852 (use (match_operand 2 "" "")) 9853 (clobber (reg:CC FLAGS_REG))] 9854 "reload_completed" 9855 [(parallel [(set (match_dup 0) (match_dup 1)) 9856 (clobber (reg:CC FLAGS_REG))])] 9857{ 9858 rtx tmp; 9859 operands[0] = gen_rtx_REG (SImode, 9860 true_regnum (operands[0]) 9861 + (TARGET_64BIT ? 1 : 2)); 9862 if (GET_CODE (operands[1]) == ABS) 9863 { 9864 tmp = GEN_INT (0x7fff); 9865 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9866 } 9867 else 9868 { 9869 tmp = GEN_INT (0x8000); 9870 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 9871 } 9872 operands[1] = tmp; 9873}) 9874 9875(define_split 9876 [(set (match_operand 0 "memory_operand" "") 9877 (match_operator 1 "absneg_operator" [(match_dup 0)])) 9878 (use (match_operand 2 "" "")) 9879 (clobber (reg:CC FLAGS_REG))] 9880 "reload_completed" 9881 [(parallel [(set (match_dup 0) (match_dup 1)) 9882 (clobber (reg:CC FLAGS_REG))])] 9883{ 9884 enum machine_mode mode = GET_MODE (operands[0]); 9885 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode); 9886 rtx tmp; 9887 9888 operands[0] = adjust_address (operands[0], QImode, size - 1); 9889 if (GET_CODE (operands[1]) == ABS) 9890 { 9891 tmp = gen_int_mode (0x7f, QImode); 9892 tmp = gen_rtx_AND (QImode, operands[0], tmp); 9893 } 9894 else 9895 { 9896 tmp = gen_int_mode (0x80, QImode); 9897 tmp = gen_rtx_XOR (QImode, operands[0], tmp); 9898 } 9899 operands[1] = tmp; 9900}) 9901 9902;; Conditionalize these after reload. If they match before reload, we 9903;; lose the clobber and ability to use integer instructions. 9904 9905(define_insn "*negsf2_1" 9906 [(set (match_operand:SF 0 "register_operand" "=f") 9907 (neg:SF (match_operand:SF 1 "register_operand" "0")))] 9908 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)" 9909 "fchs" 9910 [(set_attr "type" "fsgn") 9911 (set_attr "mode" "SF")]) 9912 9913(define_insn "*negdf2_1" 9914 [(set (match_operand:DF 0 "register_operand" "=f") 9915 (neg:DF (match_operand:DF 1 "register_operand" "0")))] 9916 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))" 9917 "fchs" 9918 [(set_attr "type" "fsgn") 9919 (set_attr "mode" "DF")]) 9920 9921(define_insn "*negxf2_1" 9922 [(set (match_operand:XF 0 "register_operand" "=f") 9923 (neg:XF (match_operand:XF 1 "register_operand" "0")))] 9924 "TARGET_80387" 9925 "fchs" 9926 [(set_attr "type" "fsgn") 9927 (set_attr "mode" "XF")]) 9928 9929(define_insn "*abssf2_1" 9930 [(set (match_operand:SF 0 "register_operand" "=f") 9931 (abs:SF (match_operand:SF 1 "register_operand" "0")))] 9932 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)" 9933 "fabs" 9934 [(set_attr "type" "fsgn") 9935 (set_attr "mode" "SF")]) 9936 9937(define_insn "*absdf2_1" 9938 [(set (match_operand:DF 0 "register_operand" "=f") 9939 (abs:DF (match_operand:DF 1 "register_operand" "0")))] 9940 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))" 9941 "fabs" 9942 [(set_attr "type" "fsgn") 9943 (set_attr "mode" "DF")]) 9944 9945(define_insn "*absxf2_1" 9946 [(set (match_operand:XF 0 "register_operand" "=f") 9947 (abs:XF (match_operand:XF 1 "register_operand" "0")))] 9948 "TARGET_80387" 9949 "fabs" 9950 [(set_attr "type" "fsgn") 9951 (set_attr "mode" "DF")]) 9952 9953(define_insn "*negextendsfdf2" 9954 [(set (match_operand:DF 0 "register_operand" "=f") 9955 (neg:DF (float_extend:DF 9956 (match_operand:SF 1 "register_operand" "0"))))] 9957 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 9958 "fchs" 9959 [(set_attr "type" "fsgn") 9960 (set_attr "mode" "DF")]) 9961 9962(define_insn "*negextenddfxf2" 9963 [(set (match_operand:XF 0 "register_operand" "=f") 9964 (neg:XF (float_extend:XF 9965 (match_operand:DF 1 "register_operand" "0"))))] 9966 "TARGET_80387" 9967 "fchs" 9968 [(set_attr "type" "fsgn") 9969 (set_attr "mode" "XF")]) 9970 9971(define_insn "*negextendsfxf2" 9972 [(set (match_operand:XF 0 "register_operand" "=f") 9973 (neg:XF (float_extend:XF 9974 (match_operand:SF 1 "register_operand" "0"))))] 9975 "TARGET_80387" 9976 "fchs" 9977 [(set_attr "type" "fsgn") 9978 (set_attr "mode" "XF")]) 9979 9980(define_insn "*absextendsfdf2" 9981 [(set (match_operand:DF 0 "register_operand" "=f") 9982 (abs:DF (float_extend:DF 9983 (match_operand:SF 1 "register_operand" "0"))))] 9984 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 9985 "fabs" 9986 [(set_attr "type" "fsgn") 9987 (set_attr "mode" "DF")]) 9988 9989(define_insn "*absextenddfxf2" 9990 [(set (match_operand:XF 0 "register_operand" "=f") 9991 (abs:XF (float_extend:XF 9992 (match_operand:DF 1 "register_operand" "0"))))] 9993 "TARGET_80387" 9994 "fabs" 9995 [(set_attr "type" "fsgn") 9996 (set_attr "mode" "XF")]) 9997 9998(define_insn "*absextendsfxf2" 9999 [(set (match_operand:XF 0 "register_operand" "=f") 10000 (abs:XF (float_extend:XF 10001 (match_operand:SF 1 "register_operand" "0"))))] 10002 "TARGET_80387" 10003 "fabs" 10004 [(set_attr "type" "fsgn") 10005 (set_attr "mode" "XF")]) 10006 10007;; One complement instructions 10008 10009(define_expand "one_cmpldi2" 10010 [(set (match_operand:DI 0 "nonimmediate_operand" "") 10011 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))] 10012 "TARGET_64BIT" 10013 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;") 10014 10015(define_insn "*one_cmpldi2_1_rex64" 10016 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 10017 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))] 10018 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)" 10019 "not{q}\t%0" 10020 [(set_attr "type" "negnot") 10021 (set_attr "mode" "DI")]) 10022 10023(define_insn "*one_cmpldi2_2_rex64" 10024 [(set (reg FLAGS_REG) 10025 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")) 10026 (const_int 0))) 10027 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 10028 (not:DI (match_dup 1)))] 10029 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 10030 && ix86_unary_operator_ok (NOT, DImode, operands)" 10031 "#" 10032 [(set_attr "type" "alu1") 10033 (set_attr "mode" "DI")]) 10034 10035(define_split 10036 [(set (match_operand 0 "flags_reg_operand" "") 10037 (match_operator 2 "compare_operator" 10038 [(not:DI (match_operand:DI 3 "nonimmediate_operand" "")) 10039 (const_int 0)])) 10040 (set (match_operand:DI 1 "nonimmediate_operand" "") 10041 (not:DI (match_dup 3)))] 10042 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)" 10043 [(parallel [(set (match_dup 0) 10044 (match_op_dup 2 10045 [(xor:DI (match_dup 3) (const_int -1)) 10046 (const_int 0)])) 10047 (set (match_dup 1) 10048 (xor:DI (match_dup 3) (const_int -1)))])] 10049 "") 10050 10051(define_expand "one_cmplsi2" 10052 [(set (match_operand:SI 0 "nonimmediate_operand" "") 10053 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))] 10054 "" 10055 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;") 10056 10057(define_insn "*one_cmplsi2_1" 10058 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 10059 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))] 10060 "ix86_unary_operator_ok (NOT, SImode, operands)" 10061 "not{l}\t%0" 10062 [(set_attr "type" "negnot") 10063 (set_attr "mode" "SI")]) 10064 10065;; ??? Currently never generated - xor is used instead. 10066(define_insn "*one_cmplsi2_1_zext" 10067 [(set (match_operand:DI 0 "register_operand" "=r") 10068 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))] 10069 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)" 10070 "not{l}\t%k0" 10071 [(set_attr "type" "negnot") 10072 (set_attr "mode" "SI")]) 10073 10074(define_insn "*one_cmplsi2_2" 10075 [(set (reg FLAGS_REG) 10076 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")) 10077 (const_int 0))) 10078 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 10079 (not:SI (match_dup 1)))] 10080 "ix86_match_ccmode (insn, CCNOmode) 10081 && ix86_unary_operator_ok (NOT, SImode, operands)" 10082 "#" 10083 [(set_attr "type" "alu1") 10084 (set_attr "mode" "SI")]) 10085 10086(define_split 10087 [(set (match_operand 0 "flags_reg_operand" "") 10088 (match_operator 2 "compare_operator" 10089 [(not:SI (match_operand:SI 3 "nonimmediate_operand" "")) 10090 (const_int 0)])) 10091 (set (match_operand:SI 1 "nonimmediate_operand" "") 10092 (not:SI (match_dup 3)))] 10093 "ix86_match_ccmode (insn, CCNOmode)" 10094 [(parallel [(set (match_dup 0) 10095 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 10096 (const_int 0)])) 10097 (set (match_dup 1) 10098 (xor:SI (match_dup 3) (const_int -1)))])] 10099 "") 10100 10101;; ??? Currently never generated - xor is used instead. 10102(define_insn "*one_cmplsi2_2_zext" 10103 [(set (reg FLAGS_REG) 10104 (compare (not:SI (match_operand:SI 1 "register_operand" "0")) 10105 (const_int 0))) 10106 (set (match_operand:DI 0 "register_operand" "=r") 10107 (zero_extend:DI (not:SI (match_dup 1))))] 10108 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 10109 && ix86_unary_operator_ok (NOT, SImode, operands)" 10110 "#" 10111 [(set_attr "type" "alu1") 10112 (set_attr "mode" "SI")]) 10113 10114(define_split 10115 [(set (match_operand 0 "flags_reg_operand" "") 10116 (match_operator 2 "compare_operator" 10117 [(not:SI (match_operand:SI 3 "register_operand" "")) 10118 (const_int 0)])) 10119 (set (match_operand:DI 1 "register_operand" "") 10120 (zero_extend:DI (not:SI (match_dup 3))))] 10121 "ix86_match_ccmode (insn, CCNOmode)" 10122 [(parallel [(set (match_dup 0) 10123 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 10124 (const_int 0)])) 10125 (set (match_dup 1) 10126 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])] 10127 "") 10128 10129(define_expand "one_cmplhi2" 10130 [(set (match_operand:HI 0 "nonimmediate_operand" "") 10131 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))] 10132 "TARGET_HIMODE_MATH" 10133 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;") 10134 10135(define_insn "*one_cmplhi2_1" 10136 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10137 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] 10138 "ix86_unary_operator_ok (NOT, HImode, operands)" 10139 "not{w}\t%0" 10140 [(set_attr "type" "negnot") 10141 (set_attr "mode" "HI")]) 10142 10143(define_insn "*one_cmplhi2_2" 10144 [(set (reg FLAGS_REG) 10145 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")) 10146 (const_int 0))) 10147 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10148 (not:HI (match_dup 1)))] 10149 "ix86_match_ccmode (insn, CCNOmode) 10150 && ix86_unary_operator_ok (NEG, HImode, operands)" 10151 "#" 10152 [(set_attr "type" "alu1") 10153 (set_attr "mode" "HI")]) 10154 10155(define_split 10156 [(set (match_operand 0 "flags_reg_operand" "") 10157 (match_operator 2 "compare_operator" 10158 [(not:HI (match_operand:HI 3 "nonimmediate_operand" "")) 10159 (const_int 0)])) 10160 (set (match_operand:HI 1 "nonimmediate_operand" "") 10161 (not:HI (match_dup 3)))] 10162 "ix86_match_ccmode (insn, CCNOmode)" 10163 [(parallel [(set (match_dup 0) 10164 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1)) 10165 (const_int 0)])) 10166 (set (match_dup 1) 10167 (xor:HI (match_dup 3) (const_int -1)))])] 10168 "") 10169 10170;; %%% Potential partial reg stall on alternative 1. What to do? 10171(define_expand "one_cmplqi2" 10172 [(set (match_operand:QI 0 "nonimmediate_operand" "") 10173 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))] 10174 "TARGET_QIMODE_MATH" 10175 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;") 10176 10177(define_insn "*one_cmplqi2_1" 10178 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") 10179 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] 10180 "ix86_unary_operator_ok (NOT, QImode, operands)" 10181 "@ 10182 not{b}\t%0 10183 not{l}\t%k0" 10184 [(set_attr "type" "negnot") 10185 (set_attr "mode" "QI,SI")]) 10186 10187(define_insn "*one_cmplqi2_2" 10188 [(set (reg FLAGS_REG) 10189 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")) 10190 (const_int 0))) 10191 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 10192 (not:QI (match_dup 1)))] 10193 "ix86_match_ccmode (insn, CCNOmode) 10194 && ix86_unary_operator_ok (NOT, QImode, operands)" 10195 "#" 10196 [(set_attr "type" "alu1") 10197 (set_attr "mode" "QI")]) 10198 10199(define_split 10200 [(set (match_operand 0 "flags_reg_operand" "") 10201 (match_operator 2 "compare_operator" 10202 [(not:QI (match_operand:QI 3 "nonimmediate_operand" "")) 10203 (const_int 0)])) 10204 (set (match_operand:QI 1 "nonimmediate_operand" "") 10205 (not:QI (match_dup 3)))] 10206 "ix86_match_ccmode (insn, CCNOmode)" 10207 [(parallel [(set (match_dup 0) 10208 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1)) 10209 (const_int 0)])) 10210 (set (match_dup 1) 10211 (xor:QI (match_dup 3) (const_int -1)))])] 10212 "") 10213 10214;; Arithmetic shift instructions 10215 10216;; DImode shifts are implemented using the i386 "shift double" opcode, 10217;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count 10218;; is variable, then the count is in %cl and the "imm" operand is dropped 10219;; from the assembler input. 10220;; 10221;; This instruction shifts the target reg/mem as usual, but instead of 10222;; shifting in zeros, bits are shifted in from reg operand. If the insn 10223;; is a left shift double, bits are taken from the high order bits of 10224;; reg, else if the insn is a shift right double, bits are taken from the 10225;; low order bits of reg. So if %eax is "1234" and %edx is "5678", 10226;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". 10227;; 10228;; Since sh[lr]d does not change the `reg' operand, that is done 10229;; separately, making all shifts emit pairs of shift double and normal 10230;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to 10231;; support a 63 bit shift, each shift where the count is in a reg expands 10232;; to a pair of shifts, a branch, a shift by 32 and a label. 10233;; 10234;; If the shift count is a constant, we need never emit more than one 10235;; shift pair, instead using moves and sign extension for counts greater 10236;; than 31. 10237 10238(define_expand "ashlti3" 10239 [(parallel [(set (match_operand:TI 0 "register_operand" "") 10240 (ashift:TI (match_operand:TI 1 "register_operand" "") 10241 (match_operand:QI 2 "nonmemory_operand" ""))) 10242 (clobber (reg:CC FLAGS_REG))])] 10243 "TARGET_64BIT" 10244{ 10245 if (! immediate_operand (operands[2], QImode)) 10246 { 10247 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2])); 10248 DONE; 10249 } 10250 ix86_expand_binary_operator (ASHIFT, TImode, operands); 10251 DONE; 10252}) 10253 10254(define_insn "ashlti3_1" 10255 [(set (match_operand:TI 0 "register_operand" "=r") 10256 (ashift:TI (match_operand:TI 1 "register_operand" "0") 10257 (match_operand:QI 2 "register_operand" "c"))) 10258 (clobber (match_scratch:DI 3 "=&r")) 10259 (clobber (reg:CC FLAGS_REG))] 10260 "TARGET_64BIT" 10261 "#" 10262 [(set_attr "type" "multi")]) 10263 10264(define_insn "*ashlti3_2" 10265 [(set (match_operand:TI 0 "register_operand" "=r") 10266 (ashift:TI (match_operand:TI 1 "register_operand" "0") 10267 (match_operand:QI 2 "immediate_operand" "O"))) 10268 (clobber (reg:CC FLAGS_REG))] 10269 "TARGET_64BIT" 10270 "#" 10271 [(set_attr "type" "multi")]) 10272 10273(define_split 10274 [(set (match_operand:TI 0 "register_operand" "") 10275 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "") 10276 (match_operand:QI 2 "register_operand" ""))) 10277 (clobber (match_scratch:DI 3 "")) 10278 (clobber (reg:CC FLAGS_REG))] 10279 "TARGET_64BIT && reload_completed" 10280 [(const_int 0)] 10281 "ix86_split_ashl (operands, operands[3], TImode); DONE;") 10282 10283(define_split 10284 [(set (match_operand:TI 0 "register_operand" "") 10285 (ashift:TI (match_operand:TI 1 "register_operand" "") 10286 (match_operand:QI 2 "immediate_operand" ""))) 10287 (clobber (reg:CC FLAGS_REG))] 10288 "TARGET_64BIT && reload_completed" 10289 [(const_int 0)] 10290 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;") 10291 10292(define_insn "x86_64_shld" 10293 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m") 10294 (ior:DI (ashift:DI (match_dup 0) 10295 (match_operand:QI 2 "nonmemory_operand" "J,c")) 10296 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r") 10297 (minus:QI (const_int 64) (match_dup 2))))) 10298 (clobber (reg:CC FLAGS_REG))] 10299 "TARGET_64BIT" 10300 "@ 10301 shld{q}\t{%2, %1, %0|%0, %1, %2} 10302 shld{q}\t{%s2%1, %0|%0, %1, %2}" 10303 [(set_attr "type" "ishift") 10304 (set_attr "prefix_0f" "1") 10305 (set_attr "mode" "DI") 10306 (set_attr "athlon_decode" "vector")]) 10307 10308(define_expand "x86_64_shift_adj" 10309 [(set (reg:CCZ FLAGS_REG) 10310 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "") 10311 (const_int 64)) 10312 (const_int 0))) 10313 (set (match_operand:DI 0 "register_operand" "") 10314 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10315 (match_operand:DI 1 "register_operand" "") 10316 (match_dup 0))) 10317 (set (match_dup 1) 10318 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10319 (match_operand:DI 3 "register_operand" "r") 10320 (match_dup 1)))] 10321 "TARGET_64BIT" 10322 "") 10323 10324(define_expand "ashldi3" 10325 [(set (match_operand:DI 0 "shiftdi_operand" "") 10326 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "") 10327 (match_operand:QI 2 "nonmemory_operand" "")))] 10328 "" 10329 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;") 10330 10331(define_insn "*ashldi3_1_rex64" 10332 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r") 10333 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l") 10334 (match_operand:QI 2 "nonmemory_operand" "cJ,M"))) 10335 (clobber (reg:CC FLAGS_REG))] 10336 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)" 10337{ 10338 switch (get_attr_type (insn)) 10339 { 10340 case TYPE_ALU: 10341 gcc_assert (operands[2] == const1_rtx); 10342 gcc_assert (rtx_equal_p (operands[0], operands[1])); 10343 return "add{q}\t{%0, %0|%0, %0}"; 10344 10345 case TYPE_LEA: 10346 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 10347 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3); 10348 operands[1] = gen_rtx_MULT (DImode, operands[1], 10349 GEN_INT (1 << INTVAL (operands[2]))); 10350 return "lea{q}\t{%a1, %0|%0, %a1}"; 10351 10352 default: 10353 if (REG_P (operands[2])) 10354 return "sal{q}\t{%b2, %0|%0, %b2}"; 10355 else if (operands[2] == const1_rtx 10356 && (TARGET_SHIFT1 || optimize_size)) 10357 return "sal{q}\t%0"; 10358 else 10359 return "sal{q}\t{%2, %0|%0, %2}"; 10360 } 10361} 10362 [(set (attr "type") 10363 (cond [(eq_attr "alternative" "1") 10364 (const_string "lea") 10365 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10366 (const_int 0)) 10367 (match_operand 0 "register_operand" "")) 10368 (match_operand 2 "const1_operand" "")) 10369 (const_string "alu") 10370 ] 10371 (const_string "ishift"))) 10372 (set_attr "mode" "DI")]) 10373 10374;; Convert lea to the lea pattern to avoid flags dependency. 10375(define_split 10376 [(set (match_operand:DI 0 "register_operand" "") 10377 (ashift:DI (match_operand:DI 1 "index_register_operand" "") 10378 (match_operand:QI 2 "immediate_operand" ""))) 10379 (clobber (reg:CC FLAGS_REG))] 10380 "TARGET_64BIT && reload_completed 10381 && true_regnum (operands[0]) != true_regnum (operands[1])" 10382 [(set (match_dup 0) 10383 (mult:DI (match_dup 1) 10384 (match_dup 2)))] 10385 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);") 10386 10387;; This pattern can't accept a variable shift count, since shifts by 10388;; zero don't affect the flags. We assume that shifts by constant 10389;; zero are optimized away. 10390(define_insn "*ashldi3_cmp_rex64" 10391 [(set (reg FLAGS_REG) 10392 (compare 10393 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0") 10394 (match_operand:QI 2 "immediate_operand" "e")) 10395 (const_int 0))) 10396 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 10397 (ashift:DI (match_dup 1) (match_dup 2)))] 10398 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 10399 && ix86_binary_operator_ok (ASHIFT, DImode, operands) 10400 && (optimize_size 10401 || !TARGET_PARTIAL_FLAG_REG_STALL 10402 || (operands[2] == const1_rtx 10403 && (TARGET_SHIFT1 10404 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 10405{ 10406 switch (get_attr_type (insn)) 10407 { 10408 case TYPE_ALU: 10409 gcc_assert (operands[2] == const1_rtx); 10410 return "add{q}\t{%0, %0|%0, %0}"; 10411 10412 default: 10413 if (REG_P (operands[2])) 10414 return "sal{q}\t{%b2, %0|%0, %b2}"; 10415 else if (operands[2] == const1_rtx 10416 && (TARGET_SHIFT1 || optimize_size)) 10417 return "sal{q}\t%0"; 10418 else 10419 return "sal{q}\t{%2, %0|%0, %2}"; 10420 } 10421} 10422 [(set (attr "type") 10423 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10424 (const_int 0)) 10425 (match_operand 0 "register_operand" "")) 10426 (match_operand 2 "const1_operand" "")) 10427 (const_string "alu") 10428 ] 10429 (const_string "ishift"))) 10430 (set_attr "mode" "DI")]) 10431 10432(define_insn "*ashldi3_cconly_rex64" 10433 [(set (reg FLAGS_REG) 10434 (compare 10435 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0") 10436 (match_operand:QI 2 "immediate_operand" "e")) 10437 (const_int 0))) 10438 (clobber (match_scratch:DI 0 "=r"))] 10439 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 10440 && ix86_binary_operator_ok (ASHIFT, DImode, operands) 10441 && (optimize_size 10442 || !TARGET_PARTIAL_FLAG_REG_STALL 10443 || (operands[2] == const1_rtx 10444 && (TARGET_SHIFT1 10445 || TARGET_DOUBLE_WITH_ADD)))" 10446{ 10447 switch (get_attr_type (insn)) 10448 { 10449 case TYPE_ALU: 10450 gcc_assert (operands[2] == const1_rtx); 10451 return "add{q}\t{%0, %0|%0, %0}"; 10452 10453 default: 10454 if (REG_P (operands[2])) 10455 return "sal{q}\t{%b2, %0|%0, %b2}"; 10456 else if (operands[2] == const1_rtx 10457 && (TARGET_SHIFT1 || optimize_size)) 10458 return "sal{q}\t%0"; 10459 else 10460 return "sal{q}\t{%2, %0|%0, %2}"; 10461 } 10462} 10463 [(set (attr "type") 10464 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10465 (const_int 0)) 10466 (match_operand 0 "register_operand" "")) 10467 (match_operand 2 "const1_operand" "")) 10468 (const_string "alu") 10469 ] 10470 (const_string "ishift"))) 10471 (set_attr "mode" "DI")]) 10472 10473(define_insn "*ashldi3_1" 10474 [(set (match_operand:DI 0 "register_operand" "=&r,r") 10475 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0") 10476 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc"))) 10477 (clobber (reg:CC FLAGS_REG))] 10478 "!TARGET_64BIT" 10479 "#" 10480 [(set_attr "type" "multi")]) 10481 10482;; By default we don't ask for a scratch register, because when DImode 10483;; values are manipulated, registers are already at a premium. But if 10484;; we have one handy, we won't turn it away. 10485(define_peephole2 10486 [(match_scratch:SI 3 "r") 10487 (parallel [(set (match_operand:DI 0 "register_operand" "") 10488 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "") 10489 (match_operand:QI 2 "nonmemory_operand" ""))) 10490 (clobber (reg:CC FLAGS_REG))]) 10491 (match_dup 3)] 10492 "!TARGET_64BIT && TARGET_CMOVE" 10493 [(const_int 0)] 10494 "ix86_split_ashl (operands, operands[3], DImode); DONE;") 10495 10496(define_split 10497 [(set (match_operand:DI 0 "register_operand" "") 10498 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "") 10499 (match_operand:QI 2 "nonmemory_operand" ""))) 10500 (clobber (reg:CC FLAGS_REG))] 10501 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) 10502 ? flow2_completed : reload_completed)" 10503 [(const_int 0)] 10504 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;") 10505 10506(define_insn "x86_shld_1" 10507 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m") 10508 (ior:SI (ashift:SI (match_dup 0) 10509 (match_operand:QI 2 "nonmemory_operand" "I,c")) 10510 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") 10511 (minus:QI (const_int 32) (match_dup 2))))) 10512 (clobber (reg:CC FLAGS_REG))] 10513 "" 10514 "@ 10515 shld{l}\t{%2, %1, %0|%0, %1, %2} 10516 shld{l}\t{%s2%1, %0|%0, %1, %2}" 10517 [(set_attr "type" "ishift") 10518 (set_attr "prefix_0f" "1") 10519 (set_attr "mode" "SI") 10520 (set_attr "pent_pair" "np") 10521 (set_attr "athlon_decode" "vector")]) 10522 10523(define_expand "x86_shift_adj_1" 10524 [(set (reg:CCZ FLAGS_REG) 10525 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "") 10526 (const_int 32)) 10527 (const_int 0))) 10528 (set (match_operand:SI 0 "register_operand" "") 10529 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10530 (match_operand:SI 1 "register_operand" "") 10531 (match_dup 0))) 10532 (set (match_dup 1) 10533 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10534 (match_operand:SI 3 "register_operand" "r") 10535 (match_dup 1)))] 10536 "TARGET_CMOVE" 10537 "") 10538 10539(define_expand "x86_shift_adj_2" 10540 [(use (match_operand:SI 0 "register_operand" "")) 10541 (use (match_operand:SI 1 "register_operand" "")) 10542 (use (match_operand:QI 2 "register_operand" ""))] 10543 "" 10544{ 10545 rtx label = gen_label_rtx (); 10546 rtx tmp; 10547 10548 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32))); 10549 10550 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 10551 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 10552 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 10553 gen_rtx_LABEL_REF (VOIDmode, label), 10554 pc_rtx); 10555 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 10556 JUMP_LABEL (tmp) = label; 10557 10558 emit_move_insn (operands[0], operands[1]); 10559 ix86_expand_clear (operands[1]); 10560 10561 emit_label (label); 10562 LABEL_NUSES (label) = 1; 10563 10564 DONE; 10565}) 10566 10567(define_expand "ashlsi3" 10568 [(set (match_operand:SI 0 "nonimmediate_operand" "") 10569 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "") 10570 (match_operand:QI 2 "nonmemory_operand" ""))) 10571 (clobber (reg:CC FLAGS_REG))] 10572 "" 10573 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;") 10574 10575(define_insn "*ashlsi3_1" 10576 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 10577 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l") 10578 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 10579 (clobber (reg:CC FLAGS_REG))] 10580 "ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10581{ 10582 switch (get_attr_type (insn)) 10583 { 10584 case TYPE_ALU: 10585 gcc_assert (operands[2] == const1_rtx); 10586 gcc_assert (rtx_equal_p (operands[0], operands[1])); 10587 return "add{l}\t{%0, %0|%0, %0}"; 10588 10589 case TYPE_LEA: 10590 return "#"; 10591 10592 default: 10593 if (REG_P (operands[2])) 10594 return "sal{l}\t{%b2, %0|%0, %b2}"; 10595 else if (operands[2] == const1_rtx 10596 && (TARGET_SHIFT1 || optimize_size)) 10597 return "sal{l}\t%0"; 10598 else 10599 return "sal{l}\t{%2, %0|%0, %2}"; 10600 } 10601} 10602 [(set (attr "type") 10603 (cond [(eq_attr "alternative" "1") 10604 (const_string "lea") 10605 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10606 (const_int 0)) 10607 (match_operand 0 "register_operand" "")) 10608 (match_operand 2 "const1_operand" "")) 10609 (const_string "alu") 10610 ] 10611 (const_string "ishift"))) 10612 (set_attr "mode" "SI")]) 10613 10614;; Convert lea to the lea pattern to avoid flags dependency. 10615(define_split 10616 [(set (match_operand 0 "register_operand" "") 10617 (ashift (match_operand 1 "index_register_operand" "") 10618 (match_operand:QI 2 "const_int_operand" ""))) 10619 (clobber (reg:CC FLAGS_REG))] 10620 "reload_completed 10621 && true_regnum (operands[0]) != true_regnum (operands[1]) 10622 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4" 10623 [(const_int 0)] 10624{ 10625 rtx pat; 10626 enum machine_mode mode = GET_MODE (operands[0]); 10627 10628 if (GET_MODE_SIZE (mode) < 4) 10629 operands[0] = gen_lowpart (SImode, operands[0]); 10630 if (mode != Pmode) 10631 operands[1] = gen_lowpart (Pmode, operands[1]); 10632 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode); 10633 10634 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]); 10635 if (Pmode != SImode) 10636 pat = gen_rtx_SUBREG (SImode, pat, 0); 10637 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 10638 DONE; 10639}) 10640 10641;; Rare case of shifting RSP is handled by generating move and shift 10642(define_split 10643 [(set (match_operand 0 "register_operand" "") 10644 (ashift (match_operand 1 "register_operand" "") 10645 (match_operand:QI 2 "const_int_operand" ""))) 10646 (clobber (reg:CC FLAGS_REG))] 10647 "reload_completed 10648 && true_regnum (operands[0]) != true_regnum (operands[1])" 10649 [(const_int 0)] 10650{ 10651 rtx pat, clob; 10652 emit_move_insn (operands[0], operands[1]); 10653 pat = gen_rtx_SET (VOIDmode, operands[0], 10654 gen_rtx_ASHIFT (GET_MODE (operands[0]), 10655 operands[0], operands[2])); 10656 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); 10657 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob))); 10658 DONE; 10659}) 10660 10661(define_insn "*ashlsi3_1_zext" 10662 [(set (match_operand:DI 0 "register_operand" "=r,r") 10663 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l") 10664 (match_operand:QI 2 "nonmemory_operand" "cI,M")))) 10665 (clobber (reg:CC FLAGS_REG))] 10666 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10667{ 10668 switch (get_attr_type (insn)) 10669 { 10670 case TYPE_ALU: 10671 gcc_assert (operands[2] == const1_rtx); 10672 return "add{l}\t{%k0, %k0|%k0, %k0}"; 10673 10674 case TYPE_LEA: 10675 return "#"; 10676 10677 default: 10678 if (REG_P (operands[2])) 10679 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 10680 else if (operands[2] == const1_rtx 10681 && (TARGET_SHIFT1 || optimize_size)) 10682 return "sal{l}\t%k0"; 10683 else 10684 return "sal{l}\t{%2, %k0|%k0, %2}"; 10685 } 10686} 10687 [(set (attr "type") 10688 (cond [(eq_attr "alternative" "1") 10689 (const_string "lea") 10690 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10691 (const_int 0)) 10692 (match_operand 2 "const1_operand" "")) 10693 (const_string "alu") 10694 ] 10695 (const_string "ishift"))) 10696 (set_attr "mode" "SI")]) 10697 10698;; Convert lea to the lea pattern to avoid flags dependency. 10699(define_split 10700 [(set (match_operand:DI 0 "register_operand" "") 10701 (zero_extend:DI (ashift (match_operand 1 "register_operand" "") 10702 (match_operand:QI 2 "const_int_operand" "")))) 10703 (clobber (reg:CC FLAGS_REG))] 10704 "TARGET_64BIT && reload_completed 10705 && true_regnum (operands[0]) != true_regnum (operands[1])" 10706 [(set (match_dup 0) (zero_extend:DI 10707 (subreg:SI (mult:SI (match_dup 1) 10708 (match_dup 2)) 0)))] 10709{ 10710 operands[1] = gen_lowpart (Pmode, operands[1]); 10711 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode); 10712}) 10713 10714;; This pattern can't accept a variable shift count, since shifts by 10715;; zero don't affect the flags. We assume that shifts by constant 10716;; zero are optimized away. 10717(define_insn "*ashlsi3_cmp" 10718 [(set (reg FLAGS_REG) 10719 (compare 10720 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0") 10721 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10722 (const_int 0))) 10723 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 10724 (ashift:SI (match_dup 1) (match_dup 2)))] 10725 "ix86_match_ccmode (insn, CCGOCmode) 10726 && ix86_binary_operator_ok (ASHIFT, SImode, operands) 10727 && (optimize_size 10728 || !TARGET_PARTIAL_FLAG_REG_STALL 10729 || (operands[2] == const1_rtx 10730 && (TARGET_SHIFT1 10731 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 10732{ 10733 switch (get_attr_type (insn)) 10734 { 10735 case TYPE_ALU: 10736 gcc_assert (operands[2] == const1_rtx); 10737 return "add{l}\t{%0, %0|%0, %0}"; 10738 10739 default: 10740 if (REG_P (operands[2])) 10741 return "sal{l}\t{%b2, %0|%0, %b2}"; 10742 else if (operands[2] == const1_rtx 10743 && (TARGET_SHIFT1 || optimize_size)) 10744 return "sal{l}\t%0"; 10745 else 10746 return "sal{l}\t{%2, %0|%0, %2}"; 10747 } 10748} 10749 [(set (attr "type") 10750 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10751 (const_int 0)) 10752 (match_operand 0 "register_operand" "")) 10753 (match_operand 2 "const1_operand" "")) 10754 (const_string "alu") 10755 ] 10756 (const_string "ishift"))) 10757 (set_attr "mode" "SI")]) 10758 10759(define_insn "*ashlsi3_cconly" 10760 [(set (reg FLAGS_REG) 10761 (compare 10762 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0") 10763 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10764 (const_int 0))) 10765 (clobber (match_scratch:SI 0 "=r"))] 10766 "ix86_match_ccmode (insn, CCGOCmode) 10767 && ix86_binary_operator_ok (ASHIFT, SImode, operands) 10768 && (optimize_size 10769 || !TARGET_PARTIAL_FLAG_REG_STALL 10770 || (operands[2] == const1_rtx 10771 && (TARGET_SHIFT1 10772 || TARGET_DOUBLE_WITH_ADD)))" 10773{ 10774 switch (get_attr_type (insn)) 10775 { 10776 case TYPE_ALU: 10777 gcc_assert (operands[2] == const1_rtx); 10778 return "add{l}\t{%0, %0|%0, %0}"; 10779 10780 default: 10781 if (REG_P (operands[2])) 10782 return "sal{l}\t{%b2, %0|%0, %b2}"; 10783 else if (operands[2] == const1_rtx 10784 && (TARGET_SHIFT1 || optimize_size)) 10785 return "sal{l}\t%0"; 10786 else 10787 return "sal{l}\t{%2, %0|%0, %2}"; 10788 } 10789} 10790 [(set (attr "type") 10791 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10792 (const_int 0)) 10793 (match_operand 0 "register_operand" "")) 10794 (match_operand 2 "const1_operand" "")) 10795 (const_string "alu") 10796 ] 10797 (const_string "ishift"))) 10798 (set_attr "mode" "SI")]) 10799 10800(define_insn "*ashlsi3_cmp_zext" 10801 [(set (reg FLAGS_REG) 10802 (compare 10803 (ashift:SI (match_operand:SI 1 "register_operand" "0") 10804 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10805 (const_int 0))) 10806 (set (match_operand:DI 0 "register_operand" "=r") 10807 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 10808 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 10809 && ix86_binary_operator_ok (ASHIFT, SImode, operands) 10810 && (optimize_size 10811 || !TARGET_PARTIAL_FLAG_REG_STALL 10812 || (operands[2] == const1_rtx 10813 && (TARGET_SHIFT1 10814 || TARGET_DOUBLE_WITH_ADD)))" 10815{ 10816 switch (get_attr_type (insn)) 10817 { 10818 case TYPE_ALU: 10819 gcc_assert (operands[2] == const1_rtx); 10820 return "add{l}\t{%k0, %k0|%k0, %k0}"; 10821 10822 default: 10823 if (REG_P (operands[2])) 10824 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 10825 else if (operands[2] == const1_rtx 10826 && (TARGET_SHIFT1 || optimize_size)) 10827 return "sal{l}\t%k0"; 10828 else 10829 return "sal{l}\t{%2, %k0|%k0, %2}"; 10830 } 10831} 10832 [(set (attr "type") 10833 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10834 (const_int 0)) 10835 (match_operand 2 "const1_operand" "")) 10836 (const_string "alu") 10837 ] 10838 (const_string "ishift"))) 10839 (set_attr "mode" "SI")]) 10840 10841(define_expand "ashlhi3" 10842 [(set (match_operand:HI 0 "nonimmediate_operand" "") 10843 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "") 10844 (match_operand:QI 2 "nonmemory_operand" ""))) 10845 (clobber (reg:CC FLAGS_REG))] 10846 "TARGET_HIMODE_MATH" 10847 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;") 10848 10849(define_insn "*ashlhi3_1_lea" 10850 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 10851 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l") 10852 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 10853 (clobber (reg:CC FLAGS_REG))] 10854 "!TARGET_PARTIAL_REG_STALL 10855 && ix86_binary_operator_ok (ASHIFT, HImode, operands)" 10856{ 10857 switch (get_attr_type (insn)) 10858 { 10859 case TYPE_LEA: 10860 return "#"; 10861 case TYPE_ALU: 10862 gcc_assert (operands[2] == const1_rtx); 10863 return "add{w}\t{%0, %0|%0, %0}"; 10864 10865 default: 10866 if (REG_P (operands[2])) 10867 return "sal{w}\t{%b2, %0|%0, %b2}"; 10868 else if (operands[2] == const1_rtx 10869 && (TARGET_SHIFT1 || optimize_size)) 10870 return "sal{w}\t%0"; 10871 else 10872 return "sal{w}\t{%2, %0|%0, %2}"; 10873 } 10874} 10875 [(set (attr "type") 10876 (cond [(eq_attr "alternative" "1") 10877 (const_string "lea") 10878 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10879 (const_int 0)) 10880 (match_operand 0 "register_operand" "")) 10881 (match_operand 2 "const1_operand" "")) 10882 (const_string "alu") 10883 ] 10884 (const_string "ishift"))) 10885 (set_attr "mode" "HI,SI")]) 10886 10887(define_insn "*ashlhi3_1" 10888 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10889 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") 10890 (match_operand:QI 2 "nonmemory_operand" "cI"))) 10891 (clobber (reg:CC FLAGS_REG))] 10892 "TARGET_PARTIAL_REG_STALL 10893 && ix86_binary_operator_ok (ASHIFT, HImode, operands)" 10894{ 10895 switch (get_attr_type (insn)) 10896 { 10897 case TYPE_ALU: 10898 gcc_assert (operands[2] == const1_rtx); 10899 return "add{w}\t{%0, %0|%0, %0}"; 10900 10901 default: 10902 if (REG_P (operands[2])) 10903 return "sal{w}\t{%b2, %0|%0, %b2}"; 10904 else if (operands[2] == const1_rtx 10905 && (TARGET_SHIFT1 || optimize_size)) 10906 return "sal{w}\t%0"; 10907 else 10908 return "sal{w}\t{%2, %0|%0, %2}"; 10909 } 10910} 10911 [(set (attr "type") 10912 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10913 (const_int 0)) 10914 (match_operand 0 "register_operand" "")) 10915 (match_operand 2 "const1_operand" "")) 10916 (const_string "alu") 10917 ] 10918 (const_string "ishift"))) 10919 (set_attr "mode" "HI")]) 10920 10921;; This pattern can't accept a variable shift count, since shifts by 10922;; zero don't affect the flags. We assume that shifts by constant 10923;; zero are optimized away. 10924(define_insn "*ashlhi3_cmp" 10925 [(set (reg FLAGS_REG) 10926 (compare 10927 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") 10928 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10929 (const_int 0))) 10930 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 10931 (ashift:HI (match_dup 1) (match_dup 2)))] 10932 "ix86_match_ccmode (insn, CCGOCmode) 10933 && ix86_binary_operator_ok (ASHIFT, HImode, operands) 10934 && (optimize_size 10935 || !TARGET_PARTIAL_FLAG_REG_STALL 10936 || (operands[2] == const1_rtx 10937 && (TARGET_SHIFT1 10938 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 10939{ 10940 switch (get_attr_type (insn)) 10941 { 10942 case TYPE_ALU: 10943 gcc_assert (operands[2] == const1_rtx); 10944 return "add{w}\t{%0, %0|%0, %0}"; 10945 10946 default: 10947 if (REG_P (operands[2])) 10948 return "sal{w}\t{%b2, %0|%0, %b2}"; 10949 else if (operands[2] == const1_rtx 10950 && (TARGET_SHIFT1 || optimize_size)) 10951 return "sal{w}\t%0"; 10952 else 10953 return "sal{w}\t{%2, %0|%0, %2}"; 10954 } 10955} 10956 [(set (attr "type") 10957 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10958 (const_int 0)) 10959 (match_operand 0 "register_operand" "")) 10960 (match_operand 2 "const1_operand" "")) 10961 (const_string "alu") 10962 ] 10963 (const_string "ishift"))) 10964 (set_attr "mode" "HI")]) 10965 10966(define_insn "*ashlhi3_cconly" 10967 [(set (reg FLAGS_REG) 10968 (compare 10969 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") 10970 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10971 (const_int 0))) 10972 (clobber (match_scratch:HI 0 "=r"))] 10973 "ix86_match_ccmode (insn, CCGOCmode) 10974 && ix86_binary_operator_ok (ASHIFT, HImode, operands) 10975 && (optimize_size 10976 || !TARGET_PARTIAL_FLAG_REG_STALL 10977 || (operands[2] == const1_rtx 10978 && (TARGET_SHIFT1 10979 || TARGET_DOUBLE_WITH_ADD)))" 10980{ 10981 switch (get_attr_type (insn)) 10982 { 10983 case TYPE_ALU: 10984 gcc_assert (operands[2] == const1_rtx); 10985 return "add{w}\t{%0, %0|%0, %0}"; 10986 10987 default: 10988 if (REG_P (operands[2])) 10989 return "sal{w}\t{%b2, %0|%0, %b2}"; 10990 else if (operands[2] == const1_rtx 10991 && (TARGET_SHIFT1 || optimize_size)) 10992 return "sal{w}\t%0"; 10993 else 10994 return "sal{w}\t{%2, %0|%0, %2}"; 10995 } 10996} 10997 [(set (attr "type") 10998 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 10999 (const_int 0)) 11000 (match_operand 0 "register_operand" "")) 11001 (match_operand 2 "const1_operand" "")) 11002 (const_string "alu") 11003 ] 11004 (const_string "ishift"))) 11005 (set_attr "mode" "HI")]) 11006 11007(define_expand "ashlqi3" 11008 [(set (match_operand:QI 0 "nonimmediate_operand" "") 11009 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "") 11010 (match_operand:QI 2 "nonmemory_operand" ""))) 11011 (clobber (reg:CC FLAGS_REG))] 11012 "TARGET_QIMODE_MATH" 11013 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;") 11014 11015;; %%% Potential partial reg stall on alternative 2. What to do? 11016 11017(define_insn "*ashlqi3_1_lea" 11018 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r") 11019 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l") 11020 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M"))) 11021 (clobber (reg:CC FLAGS_REG))] 11022 "!TARGET_PARTIAL_REG_STALL 11023 && ix86_binary_operator_ok (ASHIFT, QImode, operands)" 11024{ 11025 switch (get_attr_type (insn)) 11026 { 11027 case TYPE_LEA: 11028 return "#"; 11029 case TYPE_ALU: 11030 gcc_assert (operands[2] == const1_rtx); 11031 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) 11032 return "add{l}\t{%k0, %k0|%k0, %k0}"; 11033 else 11034 return "add{b}\t{%0, %0|%0, %0}"; 11035 11036 default: 11037 if (REG_P (operands[2])) 11038 { 11039 if (get_attr_mode (insn) == MODE_SI) 11040 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 11041 else 11042 return "sal{b}\t{%b2, %0|%0, %b2}"; 11043 } 11044 else if (operands[2] == const1_rtx 11045 && (TARGET_SHIFT1 || optimize_size)) 11046 { 11047 if (get_attr_mode (insn) == MODE_SI) 11048 return "sal{l}\t%0"; 11049 else 11050 return "sal{b}\t%0"; 11051 } 11052 else 11053 { 11054 if (get_attr_mode (insn) == MODE_SI) 11055 return "sal{l}\t{%2, %k0|%k0, %2}"; 11056 else 11057 return "sal{b}\t{%2, %0|%0, %2}"; 11058 } 11059 } 11060} 11061 [(set (attr "type") 11062 (cond [(eq_attr "alternative" "2") 11063 (const_string "lea") 11064 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11065 (const_int 0)) 11066 (match_operand 0 "register_operand" "")) 11067 (match_operand 2 "const1_operand" "")) 11068 (const_string "alu") 11069 ] 11070 (const_string "ishift"))) 11071 (set_attr "mode" "QI,SI,SI")]) 11072 11073(define_insn "*ashlqi3_1" 11074 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") 11075 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 11076 (match_operand:QI 2 "nonmemory_operand" "cI,cI"))) 11077 (clobber (reg:CC FLAGS_REG))] 11078 "TARGET_PARTIAL_REG_STALL 11079 && ix86_binary_operator_ok (ASHIFT, QImode, operands)" 11080{ 11081 switch (get_attr_type (insn)) 11082 { 11083 case TYPE_ALU: 11084 gcc_assert (operands[2] == const1_rtx); 11085 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) 11086 return "add{l}\t{%k0, %k0|%k0, %k0}"; 11087 else 11088 return "add{b}\t{%0, %0|%0, %0}"; 11089 11090 default: 11091 if (REG_P (operands[2])) 11092 { 11093 if (get_attr_mode (insn) == MODE_SI) 11094 return "sal{l}\t{%b2, %k0|%k0, %b2}"; 11095 else 11096 return "sal{b}\t{%b2, %0|%0, %b2}"; 11097 } 11098 else if (operands[2] == const1_rtx 11099 && (TARGET_SHIFT1 || optimize_size)) 11100 { 11101 if (get_attr_mode (insn) == MODE_SI) 11102 return "sal{l}\t%0"; 11103 else 11104 return "sal{b}\t%0"; 11105 } 11106 else 11107 { 11108 if (get_attr_mode (insn) == MODE_SI) 11109 return "sal{l}\t{%2, %k0|%k0, %2}"; 11110 else 11111 return "sal{b}\t{%2, %0|%0, %2}"; 11112 } 11113 } 11114} 11115 [(set (attr "type") 11116 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11117 (const_int 0)) 11118 (match_operand 0 "register_operand" "")) 11119 (match_operand 2 "const1_operand" "")) 11120 (const_string "alu") 11121 ] 11122 (const_string "ishift"))) 11123 (set_attr "mode" "QI,SI")]) 11124 11125;; This pattern can't accept a variable shift count, since shifts by 11126;; zero don't affect the flags. We assume that shifts by constant 11127;; zero are optimized away. 11128(define_insn "*ashlqi3_cmp" 11129 [(set (reg FLAGS_REG) 11130 (compare 11131 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11132 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11133 (const_int 0))) 11134 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11135 (ashift:QI (match_dup 1) (match_dup 2)))] 11136 "ix86_match_ccmode (insn, CCGOCmode) 11137 && ix86_binary_operator_ok (ASHIFT, QImode, operands) 11138 && (optimize_size 11139 || !TARGET_PARTIAL_FLAG_REG_STALL 11140 || (operands[2] == const1_rtx 11141 && (TARGET_SHIFT1 11142 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 11143{ 11144 switch (get_attr_type (insn)) 11145 { 11146 case TYPE_ALU: 11147 gcc_assert (operands[2] == const1_rtx); 11148 return "add{b}\t{%0, %0|%0, %0}"; 11149 11150 default: 11151 if (REG_P (operands[2])) 11152 return "sal{b}\t{%b2, %0|%0, %b2}"; 11153 else if (operands[2] == const1_rtx 11154 && (TARGET_SHIFT1 || optimize_size)) 11155 return "sal{b}\t%0"; 11156 else 11157 return "sal{b}\t{%2, %0|%0, %2}"; 11158 } 11159} 11160 [(set (attr "type") 11161 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11162 (const_int 0)) 11163 (match_operand 0 "register_operand" "")) 11164 (match_operand 2 "const1_operand" "")) 11165 (const_string "alu") 11166 ] 11167 (const_string "ishift"))) 11168 (set_attr "mode" "QI")]) 11169 11170(define_insn "*ashlqi3_cconly" 11171 [(set (reg FLAGS_REG) 11172 (compare 11173 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11174 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11175 (const_int 0))) 11176 (clobber (match_scratch:QI 0 "=q"))] 11177 "ix86_match_ccmode (insn, CCGOCmode) 11178 && ix86_binary_operator_ok (ASHIFT, QImode, operands) 11179 && (optimize_size 11180 || !TARGET_PARTIAL_FLAG_REG_STALL 11181 || (operands[2] == const1_rtx 11182 && (TARGET_SHIFT1 11183 || TARGET_DOUBLE_WITH_ADD)))" 11184{ 11185 switch (get_attr_type (insn)) 11186 { 11187 case TYPE_ALU: 11188 gcc_assert (operands[2] == const1_rtx); 11189 return "add{b}\t{%0, %0|%0, %0}"; 11190 11191 default: 11192 if (REG_P (operands[2])) 11193 return "sal{b}\t{%b2, %0|%0, %b2}"; 11194 else if (operands[2] == const1_rtx 11195 && (TARGET_SHIFT1 || optimize_size)) 11196 return "sal{b}\t%0"; 11197 else 11198 return "sal{b}\t{%2, %0|%0, %2}"; 11199 } 11200} 11201 [(set (attr "type") 11202 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD") 11203 (const_int 0)) 11204 (match_operand 0 "register_operand" "")) 11205 (match_operand 2 "const1_operand" "")) 11206 (const_string "alu") 11207 ] 11208 (const_string "ishift"))) 11209 (set_attr "mode" "QI")]) 11210 11211;; See comment above `ashldi3' about how this works. 11212 11213(define_expand "ashrti3" 11214 [(parallel [(set (match_operand:TI 0 "register_operand" "") 11215 (ashiftrt:TI (match_operand:TI 1 "register_operand" "") 11216 (match_operand:QI 2 "nonmemory_operand" ""))) 11217 (clobber (reg:CC FLAGS_REG))])] 11218 "TARGET_64BIT" 11219{ 11220 if (! immediate_operand (operands[2], QImode)) 11221 { 11222 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2])); 11223 DONE; 11224 } 11225 ix86_expand_binary_operator (ASHIFTRT, TImode, operands); 11226 DONE; 11227}) 11228 11229(define_insn "ashrti3_1" 11230 [(set (match_operand:TI 0 "register_operand" "=r") 11231 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0") 11232 (match_operand:QI 2 "register_operand" "c"))) 11233 (clobber (match_scratch:DI 3 "=&r")) 11234 (clobber (reg:CC FLAGS_REG))] 11235 "TARGET_64BIT" 11236 "#" 11237 [(set_attr "type" "multi")]) 11238 11239(define_insn "*ashrti3_2" 11240 [(set (match_operand:TI 0 "register_operand" "=r") 11241 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0") 11242 (match_operand:QI 2 "immediate_operand" "O"))) 11243 (clobber (reg:CC FLAGS_REG))] 11244 "TARGET_64BIT" 11245 "#" 11246 [(set_attr "type" "multi")]) 11247 11248(define_split 11249 [(set (match_operand:TI 0 "register_operand" "") 11250 (ashiftrt:TI (match_operand:TI 1 "register_operand" "") 11251 (match_operand:QI 2 "register_operand" ""))) 11252 (clobber (match_scratch:DI 3 "")) 11253 (clobber (reg:CC FLAGS_REG))] 11254 "TARGET_64BIT && reload_completed" 11255 [(const_int 0)] 11256 "ix86_split_ashr (operands, operands[3], TImode); DONE;") 11257 11258(define_split 11259 [(set (match_operand:TI 0 "register_operand" "") 11260 (ashiftrt:TI (match_operand:TI 1 "register_operand" "") 11261 (match_operand:QI 2 "immediate_operand" ""))) 11262 (clobber (reg:CC FLAGS_REG))] 11263 "TARGET_64BIT && reload_completed" 11264 [(const_int 0)] 11265 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;") 11266 11267(define_insn "x86_64_shrd" 11268 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m") 11269 (ior:DI (ashiftrt:DI (match_dup 0) 11270 (match_operand:QI 2 "nonmemory_operand" "J,c")) 11271 (ashift:DI (match_operand:DI 1 "register_operand" "r,r") 11272 (minus:QI (const_int 64) (match_dup 2))))) 11273 (clobber (reg:CC FLAGS_REG))] 11274 "TARGET_64BIT" 11275 "@ 11276 shrd{q}\t{%2, %1, %0|%0, %1, %2} 11277 shrd{q}\t{%s2%1, %0|%0, %1, %2}" 11278 [(set_attr "type" "ishift") 11279 (set_attr "prefix_0f" "1") 11280 (set_attr "mode" "DI") 11281 (set_attr "athlon_decode" "vector")]) 11282 11283(define_expand "ashrdi3" 11284 [(set (match_operand:DI 0 "shiftdi_operand" "") 11285 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") 11286 (match_operand:QI 2 "nonmemory_operand" "")))] 11287 "" 11288 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;") 11289 11290(define_insn "*ashrdi3_63_rex64" 11291 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm") 11292 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0") 11293 (match_operand:DI 2 "const_int_operand" "i,i"))) 11294 (clobber (reg:CC FLAGS_REG))] 11295 "TARGET_64BIT && INTVAL (operands[2]) == 63 11296 && (TARGET_USE_CLTD || optimize_size) 11297 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11298 "@ 11299 {cqto|cqo} 11300 sar{q}\t{%2, %0|%0, %2}" 11301 [(set_attr "type" "imovx,ishift") 11302 (set_attr "prefix_0f" "0,*") 11303 (set_attr "length_immediate" "0,*") 11304 (set_attr "modrm" "0,1") 11305 (set_attr "mode" "DI")]) 11306 11307(define_insn "*ashrdi3_1_one_bit_rex64" 11308 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11309 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11310 (match_operand:QI 2 "const1_operand" ""))) 11311 (clobber (reg:CC FLAGS_REG))] 11312 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands) 11313 && (TARGET_SHIFT1 || optimize_size)" 11314 "sar{q}\t%0" 11315 [(set_attr "type" "ishift") 11316 (set (attr "length") 11317 (if_then_else (match_operand:DI 0 "register_operand" "") 11318 (const_string "2") 11319 (const_string "*")))]) 11320 11321(define_insn "*ashrdi3_1_rex64" 11322 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 11323 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 11324 (match_operand:QI 2 "nonmemory_operand" "J,c"))) 11325 (clobber (reg:CC FLAGS_REG))] 11326 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11327 "@ 11328 sar{q}\t{%2, %0|%0, %2} 11329 sar{q}\t{%b2, %0|%0, %b2}" 11330 [(set_attr "type" "ishift") 11331 (set_attr "mode" "DI")]) 11332 11333;; This pattern can't accept a variable shift count, since shifts by 11334;; zero don't affect the flags. We assume that shifts by constant 11335;; zero are optimized away. 11336(define_insn "*ashrdi3_one_bit_cmp_rex64" 11337 [(set (reg FLAGS_REG) 11338 (compare 11339 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11340 (match_operand:QI 2 "const1_operand" "")) 11341 (const_int 0))) 11342 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11343 (ashiftrt:DI (match_dup 1) (match_dup 2)))] 11344 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11345 && (TARGET_SHIFT1 || optimize_size) 11346 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11347 "sar{q}\t%0" 11348 [(set_attr "type" "ishift") 11349 (set (attr "length") 11350 (if_then_else (match_operand:DI 0 "register_operand" "") 11351 (const_string "2") 11352 (const_string "*")))]) 11353 11354(define_insn "*ashrdi3_one_bit_cconly_rex64" 11355 [(set (reg FLAGS_REG) 11356 (compare 11357 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11358 (match_operand:QI 2 "const1_operand" "")) 11359 (const_int 0))) 11360 (clobber (match_scratch:DI 0 "=r"))] 11361 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11362 && (TARGET_SHIFT1 || optimize_size) 11363 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11364 "sar{q}\t%0" 11365 [(set_attr "type" "ishift") 11366 (set_attr "length" "2")]) 11367 11368;; This pattern can't accept a variable shift count, since shifts by 11369;; zero don't affect the flags. We assume that shifts by constant 11370;; zero are optimized away. 11371(define_insn "*ashrdi3_cmp_rex64" 11372 [(set (reg FLAGS_REG) 11373 (compare 11374 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11375 (match_operand:QI 2 "const_int_operand" "n")) 11376 (const_int 0))) 11377 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11378 (ashiftrt:DI (match_dup 1) (match_dup 2)))] 11379 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11380 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands) 11381 && (optimize_size 11382 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11383 "sar{q}\t{%2, %0|%0, %2}" 11384 [(set_attr "type" "ishift") 11385 (set_attr "mode" "DI")]) 11386 11387(define_insn "*ashrdi3_cconly_rex64" 11388 [(set (reg FLAGS_REG) 11389 (compare 11390 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11391 (match_operand:QI 2 "const_int_operand" "n")) 11392 (const_int 0))) 11393 (clobber (match_scratch:DI 0 "=r"))] 11394 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11395 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands) 11396 && (optimize_size 11397 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11398 "sar{q}\t{%2, %0|%0, %2}" 11399 [(set_attr "type" "ishift") 11400 (set_attr "mode" "DI")]) 11401 11402(define_insn "*ashrdi3_1" 11403 [(set (match_operand:DI 0 "register_operand" "=r") 11404 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") 11405 (match_operand:QI 2 "nonmemory_operand" "Jc"))) 11406 (clobber (reg:CC FLAGS_REG))] 11407 "!TARGET_64BIT" 11408 "#" 11409 [(set_attr "type" "multi")]) 11410 11411;; By default we don't ask for a scratch register, because when DImode 11412;; values are manipulated, registers are already at a premium. But if 11413;; we have one handy, we won't turn it away. 11414(define_peephole2 11415 [(match_scratch:SI 3 "r") 11416 (parallel [(set (match_operand:DI 0 "register_operand" "") 11417 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 11418 (match_operand:QI 2 "nonmemory_operand" ""))) 11419 (clobber (reg:CC FLAGS_REG))]) 11420 (match_dup 3)] 11421 "!TARGET_64BIT && TARGET_CMOVE" 11422 [(const_int 0)] 11423 "ix86_split_ashr (operands, operands[3], DImode); DONE;") 11424 11425(define_split 11426 [(set (match_operand:DI 0 "register_operand" "") 11427 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 11428 (match_operand:QI 2 "nonmemory_operand" ""))) 11429 (clobber (reg:CC FLAGS_REG))] 11430 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) 11431 ? flow2_completed : reload_completed)" 11432 [(const_int 0)] 11433 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;") 11434 11435(define_insn "x86_shrd_1" 11436 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m") 11437 (ior:SI (ashiftrt:SI (match_dup 0) 11438 (match_operand:QI 2 "nonmemory_operand" "I,c")) 11439 (ashift:SI (match_operand:SI 1 "register_operand" "r,r") 11440 (minus:QI (const_int 32) (match_dup 2))))) 11441 (clobber (reg:CC FLAGS_REG))] 11442 "" 11443 "@ 11444 shrd{l}\t{%2, %1, %0|%0, %1, %2} 11445 shrd{l}\t{%s2%1, %0|%0, %1, %2}" 11446 [(set_attr "type" "ishift") 11447 (set_attr "prefix_0f" "1") 11448 (set_attr "pent_pair" "np") 11449 (set_attr "mode" "SI")]) 11450 11451(define_expand "x86_shift_adj_3" 11452 [(use (match_operand:SI 0 "register_operand" "")) 11453 (use (match_operand:SI 1 "register_operand" "")) 11454 (use (match_operand:QI 2 "register_operand" ""))] 11455 "" 11456{ 11457 rtx label = gen_label_rtx (); 11458 rtx tmp; 11459 11460 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32))); 11461 11462 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 11463 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 11464 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 11465 gen_rtx_LABEL_REF (VOIDmode, label), 11466 pc_rtx); 11467 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 11468 JUMP_LABEL (tmp) = label; 11469 11470 emit_move_insn (operands[0], operands[1]); 11471 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31))); 11472 11473 emit_label (label); 11474 LABEL_NUSES (label) = 1; 11475 11476 DONE; 11477}) 11478 11479(define_insn "ashrsi3_31" 11480 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm") 11481 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0") 11482 (match_operand:SI 2 "const_int_operand" "i,i"))) 11483 (clobber (reg:CC FLAGS_REG))] 11484 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size) 11485 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11486 "@ 11487 {cltd|cdq} 11488 sar{l}\t{%2, %0|%0, %2}" 11489 [(set_attr "type" "imovx,ishift") 11490 (set_attr "prefix_0f" "0,*") 11491 (set_attr "length_immediate" "0,*") 11492 (set_attr "modrm" "0,1") 11493 (set_attr "mode" "SI")]) 11494 11495(define_insn "*ashrsi3_31_zext" 11496 [(set (match_operand:DI 0 "register_operand" "=*d,r") 11497 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0") 11498 (match_operand:SI 2 "const_int_operand" "i,i")))) 11499 (clobber (reg:CC FLAGS_REG))] 11500 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size) 11501 && INTVAL (operands[2]) == 31 11502 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11503 "@ 11504 {cltd|cdq} 11505 sar{l}\t{%2, %k0|%k0, %2}" 11506 [(set_attr "type" "imovx,ishift") 11507 (set_attr "prefix_0f" "0,*") 11508 (set_attr "length_immediate" "0,*") 11509 (set_attr "modrm" "0,1") 11510 (set_attr "mode" "SI")]) 11511 11512(define_expand "ashrsi3" 11513 [(set (match_operand:SI 0 "nonimmediate_operand" "") 11514 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") 11515 (match_operand:QI 2 "nonmemory_operand" ""))) 11516 (clobber (reg:CC FLAGS_REG))] 11517 "" 11518 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;") 11519 11520(define_insn "*ashrsi3_1_one_bit" 11521 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 11522 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11523 (match_operand:QI 2 "const1_operand" ""))) 11524 (clobber (reg:CC FLAGS_REG))] 11525 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11526 && (TARGET_SHIFT1 || optimize_size)" 11527 "sar{l}\t%0" 11528 [(set_attr "type" "ishift") 11529 (set (attr "length") 11530 (if_then_else (match_operand:SI 0 "register_operand" "") 11531 (const_string "2") 11532 (const_string "*")))]) 11533 11534(define_insn "*ashrsi3_1_one_bit_zext" 11535 [(set (match_operand:DI 0 "register_operand" "=r") 11536 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 11537 (match_operand:QI 2 "const1_operand" "")))) 11538 (clobber (reg:CC FLAGS_REG))] 11539 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11540 && (TARGET_SHIFT1 || optimize_size)" 11541 "sar{l}\t%k0" 11542 [(set_attr "type" "ishift") 11543 (set_attr "length" "2")]) 11544 11545(define_insn "*ashrsi3_1" 11546 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 11547 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 11548 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 11549 (clobber (reg:CC FLAGS_REG))] 11550 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11551 "@ 11552 sar{l}\t{%2, %0|%0, %2} 11553 sar{l}\t{%b2, %0|%0, %b2}" 11554 [(set_attr "type" "ishift") 11555 (set_attr "mode" "SI")]) 11556 11557(define_insn "*ashrsi3_1_zext" 11558 [(set (match_operand:DI 0 "register_operand" "=r,r") 11559 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0") 11560 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 11561 (clobber (reg:CC FLAGS_REG))] 11562 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11563 "@ 11564 sar{l}\t{%2, %k0|%k0, %2} 11565 sar{l}\t{%b2, %k0|%k0, %b2}" 11566 [(set_attr "type" "ishift") 11567 (set_attr "mode" "SI")]) 11568 11569;; This pattern can't accept a variable shift count, since shifts by 11570;; zero don't affect the flags. We assume that shifts by constant 11571;; zero are optimized away. 11572(define_insn "*ashrsi3_one_bit_cmp" 11573 [(set (reg FLAGS_REG) 11574 (compare 11575 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11576 (match_operand:QI 2 "const1_operand" "")) 11577 (const_int 0))) 11578 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 11579 (ashiftrt:SI (match_dup 1) (match_dup 2)))] 11580 "ix86_match_ccmode (insn, CCGOCmode) 11581 && (TARGET_SHIFT1 || optimize_size) 11582 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11583 "sar{l}\t%0" 11584 [(set_attr "type" "ishift") 11585 (set (attr "length") 11586 (if_then_else (match_operand:SI 0 "register_operand" "") 11587 (const_string "2") 11588 (const_string "*")))]) 11589 11590(define_insn "*ashrsi3_one_bit_cconly" 11591 [(set (reg FLAGS_REG) 11592 (compare 11593 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11594 (match_operand:QI 2 "const1_operand" "")) 11595 (const_int 0))) 11596 (clobber (match_scratch:SI 0 "=r"))] 11597 "ix86_match_ccmode (insn, CCGOCmode) 11598 && (TARGET_SHIFT1 || optimize_size) 11599 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11600 "sar{l}\t%0" 11601 [(set_attr "type" "ishift") 11602 (set_attr "length" "2")]) 11603 11604(define_insn "*ashrsi3_one_bit_cmp_zext" 11605 [(set (reg FLAGS_REG) 11606 (compare 11607 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 11608 (match_operand:QI 2 "const1_operand" "")) 11609 (const_int 0))) 11610 (set (match_operand:DI 0 "register_operand" "=r") 11611 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))] 11612 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 11613 && (TARGET_SHIFT1 || optimize_size) 11614 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11615 "sar{l}\t%k0" 11616 [(set_attr "type" "ishift") 11617 (set_attr "length" "2")]) 11618 11619;; This pattern can't accept a variable shift count, since shifts by 11620;; zero don't affect the flags. We assume that shifts by constant 11621;; zero are optimized away. 11622(define_insn "*ashrsi3_cmp" 11623 [(set (reg FLAGS_REG) 11624 (compare 11625 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11626 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11627 (const_int 0))) 11628 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 11629 (ashiftrt:SI (match_dup 1) (match_dup 2)))] 11630 "ix86_match_ccmode (insn, CCGOCmode) 11631 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11632 && (optimize_size 11633 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11634 "sar{l}\t{%2, %0|%0, %2}" 11635 [(set_attr "type" "ishift") 11636 (set_attr "mode" "SI")]) 11637 11638(define_insn "*ashrsi3_cconly" 11639 [(set (reg FLAGS_REG) 11640 (compare 11641 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 11642 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11643 (const_int 0))) 11644 (clobber (match_scratch:SI 0 "=r"))] 11645 "ix86_match_ccmode (insn, CCGOCmode) 11646 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11647 && (optimize_size 11648 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11649 "sar{l}\t{%2, %0|%0, %2}" 11650 [(set_attr "type" "ishift") 11651 (set_attr "mode" "SI")]) 11652 11653(define_insn "*ashrsi3_cmp_zext" 11654 [(set (reg FLAGS_REG) 11655 (compare 11656 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") 11657 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11658 (const_int 0))) 11659 (set (match_operand:DI 0 "register_operand" "=r") 11660 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))] 11661 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 11662 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands) 11663 && (optimize_size 11664 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11665 "sar{l}\t{%2, %k0|%k0, %2}" 11666 [(set_attr "type" "ishift") 11667 (set_attr "mode" "SI")]) 11668 11669(define_expand "ashrhi3" 11670 [(set (match_operand:HI 0 "nonimmediate_operand" "") 11671 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") 11672 (match_operand:QI 2 "nonmemory_operand" ""))) 11673 (clobber (reg:CC FLAGS_REG))] 11674 "TARGET_HIMODE_MATH" 11675 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;") 11676 11677(define_insn "*ashrhi3_1_one_bit" 11678 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 11679 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11680 (match_operand:QI 2 "const1_operand" ""))) 11681 (clobber (reg:CC FLAGS_REG))] 11682 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands) 11683 && (TARGET_SHIFT1 || optimize_size)" 11684 "sar{w}\t%0" 11685 [(set_attr "type" "ishift") 11686 (set (attr "length") 11687 (if_then_else (match_operand 0 "register_operand" "") 11688 (const_string "2") 11689 (const_string "*")))]) 11690 11691(define_insn "*ashrhi3_1" 11692 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 11693 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 11694 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 11695 (clobber (reg:CC FLAGS_REG))] 11696 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" 11697 "@ 11698 sar{w}\t{%2, %0|%0, %2} 11699 sar{w}\t{%b2, %0|%0, %b2}" 11700 [(set_attr "type" "ishift") 11701 (set_attr "mode" "HI")]) 11702 11703;; This pattern can't accept a variable shift count, since shifts by 11704;; zero don't affect the flags. We assume that shifts by constant 11705;; zero are optimized away. 11706(define_insn "*ashrhi3_one_bit_cmp" 11707 [(set (reg FLAGS_REG) 11708 (compare 11709 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11710 (match_operand:QI 2 "const1_operand" "")) 11711 (const_int 0))) 11712 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 11713 (ashiftrt:HI (match_dup 1) (match_dup 2)))] 11714 "ix86_match_ccmode (insn, CCGOCmode) 11715 && (TARGET_SHIFT1 || optimize_size) 11716 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" 11717 "sar{w}\t%0" 11718 [(set_attr "type" "ishift") 11719 (set (attr "length") 11720 (if_then_else (match_operand 0 "register_operand" "") 11721 (const_string "2") 11722 (const_string "*")))]) 11723 11724(define_insn "*ashrhi3_one_bit_cconly" 11725 [(set (reg FLAGS_REG) 11726 (compare 11727 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11728 (match_operand:QI 2 "const1_operand" "")) 11729 (const_int 0))) 11730 (clobber (match_scratch:HI 0 "=r"))] 11731 "ix86_match_ccmode (insn, CCGOCmode) 11732 && (TARGET_SHIFT1 || optimize_size) 11733 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)" 11734 "sar{w}\t%0" 11735 [(set_attr "type" "ishift") 11736 (set_attr "length" "2")]) 11737 11738;; This pattern can't accept a variable shift count, since shifts by 11739;; zero don't affect the flags. We assume that shifts by constant 11740;; zero are optimized away. 11741(define_insn "*ashrhi3_cmp" 11742 [(set (reg FLAGS_REG) 11743 (compare 11744 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11745 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11746 (const_int 0))) 11747 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 11748 (ashiftrt:HI (match_dup 1) (match_dup 2)))] 11749 "ix86_match_ccmode (insn, CCGOCmode) 11750 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands) 11751 && (optimize_size 11752 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11753 "sar{w}\t{%2, %0|%0, %2}" 11754 [(set_attr "type" "ishift") 11755 (set_attr "mode" "HI")]) 11756 11757(define_insn "*ashrhi3_cconly" 11758 [(set (reg FLAGS_REG) 11759 (compare 11760 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 11761 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11762 (const_int 0))) 11763 (clobber (match_scratch:HI 0 "=r"))] 11764 "ix86_match_ccmode (insn, CCGOCmode) 11765 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands) 11766 && (optimize_size 11767 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11768 "sar{w}\t{%2, %0|%0, %2}" 11769 [(set_attr "type" "ishift") 11770 (set_attr "mode" "HI")]) 11771 11772(define_expand "ashrqi3" 11773 [(set (match_operand:QI 0 "nonimmediate_operand" "") 11774 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "") 11775 (match_operand:QI 2 "nonmemory_operand" ""))) 11776 (clobber (reg:CC FLAGS_REG))] 11777 "TARGET_QIMODE_MATH" 11778 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;") 11779 11780(define_insn "*ashrqi3_1_one_bit" 11781 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11782 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11783 (match_operand:QI 2 "const1_operand" ""))) 11784 (clobber (reg:CC FLAGS_REG))] 11785 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 11786 && (TARGET_SHIFT1 || optimize_size)" 11787 "sar{b}\t%0" 11788 [(set_attr "type" "ishift") 11789 (set (attr "length") 11790 (if_then_else (match_operand 0 "register_operand" "") 11791 (const_string "2") 11792 (const_string "*")))]) 11793 11794(define_insn "*ashrqi3_1_one_bit_slp" 11795 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 11796 (ashiftrt:QI (match_dup 0) 11797 (match_operand:QI 1 "const1_operand" ""))) 11798 (clobber (reg:CC FLAGS_REG))] 11799 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 11800 && (! TARGET_PARTIAL_REG_STALL || optimize_size) 11801 && (TARGET_SHIFT1 || optimize_size)" 11802 "sar{b}\t%0" 11803 [(set_attr "type" "ishift1") 11804 (set (attr "length") 11805 (if_then_else (match_operand 0 "register_operand" "") 11806 (const_string "2") 11807 (const_string "*")))]) 11808 11809(define_insn "*ashrqi3_1" 11810 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 11811 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 11812 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 11813 (clobber (reg:CC FLAGS_REG))] 11814 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" 11815 "@ 11816 sar{b}\t{%2, %0|%0, %2} 11817 sar{b}\t{%b2, %0|%0, %b2}" 11818 [(set_attr "type" "ishift") 11819 (set_attr "mode" "QI")]) 11820 11821(define_insn "*ashrqi3_1_slp" 11822 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 11823 (ashiftrt:QI (match_dup 0) 11824 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 11825 (clobber (reg:CC FLAGS_REG))] 11826 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 11827 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 11828 "@ 11829 sar{b}\t{%1, %0|%0, %1} 11830 sar{b}\t{%b1, %0|%0, %b1}" 11831 [(set_attr "type" "ishift1") 11832 (set_attr "mode" "QI")]) 11833 11834;; This pattern can't accept a variable shift count, since shifts by 11835;; zero don't affect the flags. We assume that shifts by constant 11836;; zero are optimized away. 11837(define_insn "*ashrqi3_one_bit_cmp" 11838 [(set (reg FLAGS_REG) 11839 (compare 11840 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11841 (match_operand:QI 2 "const1_operand" "I")) 11842 (const_int 0))) 11843 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11844 (ashiftrt:QI (match_dup 1) (match_dup 2)))] 11845 "ix86_match_ccmode (insn, CCGOCmode) 11846 && (TARGET_SHIFT1 || optimize_size) 11847 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" 11848 "sar{b}\t%0" 11849 [(set_attr "type" "ishift") 11850 (set (attr "length") 11851 (if_then_else (match_operand 0 "register_operand" "") 11852 (const_string "2") 11853 (const_string "*")))]) 11854 11855(define_insn "*ashrqi3_one_bit_cconly" 11856 [(set (reg FLAGS_REG) 11857 (compare 11858 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11859 (match_operand:QI 2 "const1_operand" "I")) 11860 (const_int 0))) 11861 (clobber (match_scratch:QI 0 "=q"))] 11862 "ix86_match_ccmode (insn, CCGOCmode) 11863 && (TARGET_SHIFT1 || optimize_size) 11864 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)" 11865 "sar{b}\t%0" 11866 [(set_attr "type" "ishift") 11867 (set_attr "length" "2")]) 11868 11869;; This pattern can't accept a variable shift count, since shifts by 11870;; zero don't affect the flags. We assume that shifts by constant 11871;; zero are optimized away. 11872(define_insn "*ashrqi3_cmp" 11873 [(set (reg FLAGS_REG) 11874 (compare 11875 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11876 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11877 (const_int 0))) 11878 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 11879 (ashiftrt:QI (match_dup 1) (match_dup 2)))] 11880 "ix86_match_ccmode (insn, CCGOCmode) 11881 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 11882 && (optimize_size 11883 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11884 "sar{b}\t{%2, %0|%0, %2}" 11885 [(set_attr "type" "ishift") 11886 (set_attr "mode" "QI")]) 11887 11888(define_insn "*ashrqi3_cconly" 11889 [(set (reg FLAGS_REG) 11890 (compare 11891 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 11892 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11893 (const_int 0))) 11894 (clobber (match_scratch:QI 0 "=q"))] 11895 "ix86_match_ccmode (insn, CCGOCmode) 11896 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands) 11897 && (optimize_size 11898 || !TARGET_PARTIAL_FLAG_REG_STALL)" 11899 "sar{b}\t{%2, %0|%0, %2}" 11900 [(set_attr "type" "ishift") 11901 (set_attr "mode" "QI")]) 11902 11903 11904;; Logical shift instructions 11905 11906;; See comment above `ashldi3' about how this works. 11907 11908(define_expand "lshrti3" 11909 [(parallel [(set (match_operand:TI 0 "register_operand" "") 11910 (lshiftrt:TI (match_operand:TI 1 "register_operand" "") 11911 (match_operand:QI 2 "nonmemory_operand" ""))) 11912 (clobber (reg:CC FLAGS_REG))])] 11913 "TARGET_64BIT" 11914{ 11915 if (! immediate_operand (operands[2], QImode)) 11916 { 11917 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2])); 11918 DONE; 11919 } 11920 ix86_expand_binary_operator (LSHIFTRT, TImode, operands); 11921 DONE; 11922}) 11923 11924(define_insn "lshrti3_1" 11925 [(set (match_operand:TI 0 "register_operand" "=r") 11926 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0") 11927 (match_operand:QI 2 "register_operand" "c"))) 11928 (clobber (match_scratch:DI 3 "=&r")) 11929 (clobber (reg:CC FLAGS_REG))] 11930 "TARGET_64BIT" 11931 "#" 11932 [(set_attr "type" "multi")]) 11933 11934(define_insn "*lshrti3_2" 11935 [(set (match_operand:TI 0 "register_operand" "=r") 11936 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0") 11937 (match_operand:QI 2 "immediate_operand" "O"))) 11938 (clobber (reg:CC FLAGS_REG))] 11939 "TARGET_64BIT" 11940 "#" 11941 [(set_attr "type" "multi")]) 11942 11943(define_split 11944 [(set (match_operand:TI 0 "register_operand" "") 11945 (lshiftrt:TI (match_operand:TI 1 "register_operand" "") 11946 (match_operand:QI 2 "register_operand" ""))) 11947 (clobber (match_scratch:DI 3 "")) 11948 (clobber (reg:CC FLAGS_REG))] 11949 "TARGET_64BIT && reload_completed" 11950 [(const_int 0)] 11951 "ix86_split_lshr (operands, operands[3], TImode); DONE;") 11952 11953(define_split 11954 [(set (match_operand:TI 0 "register_operand" "") 11955 (lshiftrt:TI (match_operand:TI 1 "register_operand" "") 11956 (match_operand:QI 2 "immediate_operand" ""))) 11957 (clobber (reg:CC FLAGS_REG))] 11958 "TARGET_64BIT && reload_completed" 11959 [(const_int 0)] 11960 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;") 11961 11962(define_expand "lshrdi3" 11963 [(set (match_operand:DI 0 "shiftdi_operand" "") 11964 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "") 11965 (match_operand:QI 2 "nonmemory_operand" "")))] 11966 "" 11967 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;") 11968 11969(define_insn "*lshrdi3_1_one_bit_rex64" 11970 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 11971 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 11972 (match_operand:QI 2 "const1_operand" ""))) 11973 (clobber (reg:CC FLAGS_REG))] 11974 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 11975 && (TARGET_SHIFT1 || optimize_size)" 11976 "shr{q}\t%0" 11977 [(set_attr "type" "ishift") 11978 (set (attr "length") 11979 (if_then_else (match_operand:DI 0 "register_operand" "") 11980 (const_string "2") 11981 (const_string "*")))]) 11982 11983(define_insn "*lshrdi3_1_rex64" 11984 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 11985 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 11986 (match_operand:QI 2 "nonmemory_operand" "J,c"))) 11987 (clobber (reg:CC FLAGS_REG))] 11988 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 11989 "@ 11990 shr{q}\t{%2, %0|%0, %2} 11991 shr{q}\t{%b2, %0|%0, %b2}" 11992 [(set_attr "type" "ishift") 11993 (set_attr "mode" "DI")]) 11994 11995;; This pattern can't accept a variable shift count, since shifts by 11996;; zero don't affect the flags. We assume that shifts by constant 11997;; zero are optimized away. 11998(define_insn "*lshrdi3_cmp_one_bit_rex64" 11999 [(set (reg FLAGS_REG) 12000 (compare 12001 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12002 (match_operand:QI 2 "const1_operand" "")) 12003 (const_int 0))) 12004 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12005 (lshiftrt:DI (match_dup 1) (match_dup 2)))] 12006 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12007 && (TARGET_SHIFT1 || optimize_size) 12008 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12009 "shr{q}\t%0" 12010 [(set_attr "type" "ishift") 12011 (set (attr "length") 12012 (if_then_else (match_operand:DI 0 "register_operand" "") 12013 (const_string "2") 12014 (const_string "*")))]) 12015 12016(define_insn "*lshrdi3_cconly_one_bit_rex64" 12017 [(set (reg FLAGS_REG) 12018 (compare 12019 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12020 (match_operand:QI 2 "const1_operand" "")) 12021 (const_int 0))) 12022 (clobber (match_scratch:DI 0 "=r"))] 12023 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12024 && (TARGET_SHIFT1 || optimize_size) 12025 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12026 "shr{q}\t%0" 12027 [(set_attr "type" "ishift") 12028 (set_attr "length" "2")]) 12029 12030;; This pattern can't accept a variable shift count, since shifts by 12031;; zero don't affect the flags. We assume that shifts by constant 12032;; zero are optimized away. 12033(define_insn "*lshrdi3_cmp_rex64" 12034 [(set (reg FLAGS_REG) 12035 (compare 12036 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12037 (match_operand:QI 2 "const_int_operand" "e")) 12038 (const_int 0))) 12039 (set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12040 (lshiftrt:DI (match_dup 1) (match_dup 2)))] 12041 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12042 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12043 && (optimize_size 12044 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12045 "shr{q}\t{%2, %0|%0, %2}" 12046 [(set_attr "type" "ishift") 12047 (set_attr "mode" "DI")]) 12048 12049(define_insn "*lshrdi3_cconly_rex64" 12050 [(set (reg FLAGS_REG) 12051 (compare 12052 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12053 (match_operand:QI 2 "const_int_operand" "e")) 12054 (const_int 0))) 12055 (clobber (match_scratch:DI 0 "=r"))] 12056 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12057 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12058 && (optimize_size 12059 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12060 "shr{q}\t{%2, %0|%0, %2}" 12061 [(set_attr "type" "ishift") 12062 (set_attr "mode" "DI")]) 12063 12064(define_insn "*lshrdi3_1" 12065 [(set (match_operand:DI 0 "register_operand" "=r") 12066 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") 12067 (match_operand:QI 2 "nonmemory_operand" "Jc"))) 12068 (clobber (reg:CC FLAGS_REG))] 12069 "!TARGET_64BIT" 12070 "#" 12071 [(set_attr "type" "multi")]) 12072 12073;; By default we don't ask for a scratch register, because when DImode 12074;; values are manipulated, registers are already at a premium. But if 12075;; we have one handy, we won't turn it away. 12076(define_peephole2 12077 [(match_scratch:SI 3 "r") 12078 (parallel [(set (match_operand:DI 0 "register_operand" "") 12079 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 12080 (match_operand:QI 2 "nonmemory_operand" ""))) 12081 (clobber (reg:CC FLAGS_REG))]) 12082 (match_dup 3)] 12083 "!TARGET_64BIT && TARGET_CMOVE" 12084 [(const_int 0)] 12085 "ix86_split_lshr (operands, operands[3], DImode); DONE;") 12086 12087(define_split 12088 [(set (match_operand:DI 0 "register_operand" "") 12089 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 12090 (match_operand:QI 2 "nonmemory_operand" ""))) 12091 (clobber (reg:CC FLAGS_REG))] 12092 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2) 12093 ? flow2_completed : reload_completed)" 12094 [(const_int 0)] 12095 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;") 12096 12097(define_expand "lshrsi3" 12098 [(set (match_operand:SI 0 "nonimmediate_operand" "") 12099 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "") 12100 (match_operand:QI 2 "nonmemory_operand" ""))) 12101 (clobber (reg:CC FLAGS_REG))] 12102 "" 12103 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;") 12104 12105(define_insn "*lshrsi3_1_one_bit" 12106 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12107 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12108 (match_operand:QI 2 "const1_operand" ""))) 12109 (clobber (reg:CC FLAGS_REG))] 12110 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12111 && (TARGET_SHIFT1 || optimize_size)" 12112 "shr{l}\t%0" 12113 [(set_attr "type" "ishift") 12114 (set (attr "length") 12115 (if_then_else (match_operand:SI 0 "register_operand" "") 12116 (const_string "2") 12117 (const_string "*")))]) 12118 12119(define_insn "*lshrsi3_1_one_bit_zext" 12120 [(set (match_operand:DI 0 "register_operand" "=r") 12121 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0")) 12122 (match_operand:QI 2 "const1_operand" ""))) 12123 (clobber (reg:CC FLAGS_REG))] 12124 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12125 && (TARGET_SHIFT1 || optimize_size)" 12126 "shr{l}\t%k0" 12127 [(set_attr "type" "ishift") 12128 (set_attr "length" "2")]) 12129 12130(define_insn "*lshrsi3_1" 12131 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 12132 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12133 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12134 (clobber (reg:CC FLAGS_REG))] 12135 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12136 "@ 12137 shr{l}\t{%2, %0|%0, %2} 12138 shr{l}\t{%b2, %0|%0, %b2}" 12139 [(set_attr "type" "ishift") 12140 (set_attr "mode" "SI")]) 12141 12142(define_insn "*lshrsi3_1_zext" 12143 [(set (match_operand:DI 0 "register_operand" "=r,r") 12144 (zero_extend:DI 12145 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12146 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 12147 (clobber (reg:CC FLAGS_REG))] 12148 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12149 "@ 12150 shr{l}\t{%2, %k0|%k0, %2} 12151 shr{l}\t{%b2, %k0|%k0, %b2}" 12152 [(set_attr "type" "ishift") 12153 (set_attr "mode" "SI")]) 12154 12155;; This pattern can't accept a variable shift count, since shifts by 12156;; zero don't affect the flags. We assume that shifts by constant 12157;; zero are optimized away. 12158(define_insn "*lshrsi3_one_bit_cmp" 12159 [(set (reg FLAGS_REG) 12160 (compare 12161 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12162 (match_operand:QI 2 "const1_operand" "")) 12163 (const_int 0))) 12164 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12165 (lshiftrt:SI (match_dup 1) (match_dup 2)))] 12166 "ix86_match_ccmode (insn, CCGOCmode) 12167 && (TARGET_SHIFT1 || optimize_size) 12168 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12169 "shr{l}\t%0" 12170 [(set_attr "type" "ishift") 12171 (set (attr "length") 12172 (if_then_else (match_operand:SI 0 "register_operand" "") 12173 (const_string "2") 12174 (const_string "*")))]) 12175 12176(define_insn "*lshrsi3_one_bit_cconly" 12177 [(set (reg FLAGS_REG) 12178 (compare 12179 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12180 (match_operand:QI 2 "const1_operand" "")) 12181 (const_int 0))) 12182 (clobber (match_scratch:SI 0 "=r"))] 12183 "ix86_match_ccmode (insn, CCGOCmode) 12184 && (TARGET_SHIFT1 || optimize_size) 12185 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12186 "shr{l}\t%0" 12187 [(set_attr "type" "ishift") 12188 (set_attr "length" "2")]) 12189 12190(define_insn "*lshrsi3_cmp_one_bit_zext" 12191 [(set (reg FLAGS_REG) 12192 (compare 12193 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 12194 (match_operand:QI 2 "const1_operand" "")) 12195 (const_int 0))) 12196 (set (match_operand:DI 0 "register_operand" "=r") 12197 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 12198 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12199 && (TARGET_SHIFT1 || optimize_size) 12200 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12201 "shr{l}\t%k0" 12202 [(set_attr "type" "ishift") 12203 (set_attr "length" "2")]) 12204 12205;; This pattern can't accept a variable shift count, since shifts by 12206;; zero don't affect the flags. We assume that shifts by constant 12207;; zero are optimized away. 12208(define_insn "*lshrsi3_cmp" 12209 [(set (reg FLAGS_REG) 12210 (compare 12211 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12212 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12213 (const_int 0))) 12214 (set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12215 (lshiftrt:SI (match_dup 1) (match_dup 2)))] 12216 "ix86_match_ccmode (insn, CCGOCmode) 12217 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12218 && (optimize_size 12219 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12220 "shr{l}\t{%2, %0|%0, %2}" 12221 [(set_attr "type" "ishift") 12222 (set_attr "mode" "SI")]) 12223 12224(define_insn "*lshrsi3_cconly" 12225 [(set (reg FLAGS_REG) 12226 (compare 12227 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12228 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12229 (const_int 0))) 12230 (clobber (match_scratch:SI 0 "=r"))] 12231 "ix86_match_ccmode (insn, CCGOCmode) 12232 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12233 && (optimize_size 12234 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12235 "shr{l}\t{%2, %0|%0, %2}" 12236 [(set_attr "type" "ishift") 12237 (set_attr "mode" "SI")]) 12238 12239(define_insn "*lshrsi3_cmp_zext" 12240 [(set (reg FLAGS_REG) 12241 (compare 12242 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") 12243 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12244 (const_int 0))) 12245 (set (match_operand:DI 0 "register_operand" "=r") 12246 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 12247 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 12248 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12249 && (optimize_size 12250 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12251 "shr{l}\t{%2, %k0|%k0, %2}" 12252 [(set_attr "type" "ishift") 12253 (set_attr "mode" "SI")]) 12254 12255(define_expand "lshrhi3" 12256 [(set (match_operand:HI 0 "nonimmediate_operand" "") 12257 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "") 12258 (match_operand:QI 2 "nonmemory_operand" ""))) 12259 (clobber (reg:CC FLAGS_REG))] 12260 "TARGET_HIMODE_MATH" 12261 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;") 12262 12263(define_insn "*lshrhi3_1_one_bit" 12264 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12265 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12266 (match_operand:QI 2 "const1_operand" ""))) 12267 (clobber (reg:CC FLAGS_REG))] 12268 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12269 && (TARGET_SHIFT1 || optimize_size)" 12270 "shr{w}\t%0" 12271 [(set_attr "type" "ishift") 12272 (set (attr "length") 12273 (if_then_else (match_operand 0 "register_operand" "") 12274 (const_string "2") 12275 (const_string "*")))]) 12276 12277(define_insn "*lshrhi3_1" 12278 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 12279 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 12280 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12281 (clobber (reg:CC FLAGS_REG))] 12282 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12283 "@ 12284 shr{w}\t{%2, %0|%0, %2} 12285 shr{w}\t{%b2, %0|%0, %b2}" 12286 [(set_attr "type" "ishift") 12287 (set_attr "mode" "HI")]) 12288 12289;; This pattern can't accept a variable shift count, since shifts by 12290;; zero don't affect the flags. We assume that shifts by constant 12291;; zero are optimized away. 12292(define_insn "*lshrhi3_one_bit_cmp" 12293 [(set (reg FLAGS_REG) 12294 (compare 12295 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12296 (match_operand:QI 2 "const1_operand" "")) 12297 (const_int 0))) 12298 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12299 (lshiftrt:HI (match_dup 1) (match_dup 2)))] 12300 "ix86_match_ccmode (insn, CCGOCmode) 12301 && (TARGET_SHIFT1 || optimize_size) 12302 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12303 "shr{w}\t%0" 12304 [(set_attr "type" "ishift") 12305 (set (attr "length") 12306 (if_then_else (match_operand:SI 0 "register_operand" "") 12307 (const_string "2") 12308 (const_string "*")))]) 12309 12310(define_insn "*lshrhi3_one_bit_cconly" 12311 [(set (reg FLAGS_REG) 12312 (compare 12313 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12314 (match_operand:QI 2 "const1_operand" "")) 12315 (const_int 0))) 12316 (clobber (match_scratch:HI 0 "=r"))] 12317 "ix86_match_ccmode (insn, CCGOCmode) 12318 && (TARGET_SHIFT1 || optimize_size) 12319 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)" 12320 "shr{w}\t%0" 12321 [(set_attr "type" "ishift") 12322 (set_attr "length" "2")]) 12323 12324;; This pattern can't accept a variable shift count, since shifts by 12325;; zero don't affect the flags. We assume that shifts by constant 12326;; zero are optimized away. 12327(define_insn "*lshrhi3_cmp" 12328 [(set (reg FLAGS_REG) 12329 (compare 12330 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12331 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12332 (const_int 0))) 12333 (set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12334 (lshiftrt:HI (match_dup 1) (match_dup 2)))] 12335 "ix86_match_ccmode (insn, CCGOCmode) 12336 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12337 && (optimize_size 12338 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12339 "shr{w}\t{%2, %0|%0, %2}" 12340 [(set_attr "type" "ishift") 12341 (set_attr "mode" "HI")]) 12342 12343(define_insn "*lshrhi3_cconly" 12344 [(set (reg FLAGS_REG) 12345 (compare 12346 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12347 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12348 (const_int 0))) 12349 (clobber (match_scratch:HI 0 "=r"))] 12350 "ix86_match_ccmode (insn, CCGOCmode) 12351 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands) 12352 && (optimize_size 12353 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12354 "shr{w}\t{%2, %0|%0, %2}" 12355 [(set_attr "type" "ishift") 12356 (set_attr "mode" "HI")]) 12357 12358(define_expand "lshrqi3" 12359 [(set (match_operand:QI 0 "nonimmediate_operand" "") 12360 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "") 12361 (match_operand:QI 2 "nonmemory_operand" ""))) 12362 (clobber (reg:CC FLAGS_REG))] 12363 "TARGET_QIMODE_MATH" 12364 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;") 12365 12366(define_insn "*lshrqi3_1_one_bit" 12367 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12368 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12369 (match_operand:QI 2 "const1_operand" ""))) 12370 (clobber (reg:CC FLAGS_REG))] 12371 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands) 12372 && (TARGET_SHIFT1 || optimize_size)" 12373 "shr{b}\t%0" 12374 [(set_attr "type" "ishift") 12375 (set (attr "length") 12376 (if_then_else (match_operand 0 "register_operand" "") 12377 (const_string "2") 12378 (const_string "*")))]) 12379 12380(define_insn "*lshrqi3_1_one_bit_slp" 12381 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 12382 (lshiftrt:QI (match_dup 0) 12383 (match_operand:QI 1 "const1_operand" ""))) 12384 (clobber (reg:CC FLAGS_REG))] 12385 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12386 && (TARGET_SHIFT1 || optimize_size)" 12387 "shr{b}\t%0" 12388 [(set_attr "type" "ishift1") 12389 (set (attr "length") 12390 (if_then_else (match_operand 0 "register_operand" "") 12391 (const_string "2") 12392 (const_string "*")))]) 12393 12394(define_insn "*lshrqi3_1" 12395 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 12396 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 12397 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12398 (clobber (reg:CC FLAGS_REG))] 12399 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" 12400 "@ 12401 shr{b}\t{%2, %0|%0, %2} 12402 shr{b}\t{%b2, %0|%0, %b2}" 12403 [(set_attr "type" "ishift") 12404 (set_attr "mode" "QI")]) 12405 12406(define_insn "*lshrqi3_1_slp" 12407 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 12408 (lshiftrt:QI (match_dup 0) 12409 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 12410 (clobber (reg:CC FLAGS_REG))] 12411 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12412 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 12413 "@ 12414 shr{b}\t{%1, %0|%0, %1} 12415 shr{b}\t{%b1, %0|%0, %b1}" 12416 [(set_attr "type" "ishift1") 12417 (set_attr "mode" "QI")]) 12418 12419;; This pattern can't accept a variable shift count, since shifts by 12420;; zero don't affect the flags. We assume that shifts by constant 12421;; zero are optimized away. 12422(define_insn "*lshrqi2_one_bit_cmp" 12423 [(set (reg FLAGS_REG) 12424 (compare 12425 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12426 (match_operand:QI 2 "const1_operand" "")) 12427 (const_int 0))) 12428 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12429 (lshiftrt:QI (match_dup 1) (match_dup 2)))] 12430 "ix86_match_ccmode (insn, CCGOCmode) 12431 && (TARGET_SHIFT1 || optimize_size) 12432 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" 12433 "shr{b}\t%0" 12434 [(set_attr "type" "ishift") 12435 (set (attr "length") 12436 (if_then_else (match_operand:SI 0 "register_operand" "") 12437 (const_string "2") 12438 (const_string "*")))]) 12439 12440(define_insn "*lshrqi2_one_bit_cconly" 12441 [(set (reg FLAGS_REG) 12442 (compare 12443 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12444 (match_operand:QI 2 "const1_operand" "")) 12445 (const_int 0))) 12446 (clobber (match_scratch:QI 0 "=q"))] 12447 "ix86_match_ccmode (insn, CCGOCmode) 12448 && (TARGET_SHIFT1 || optimize_size) 12449 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)" 12450 "shr{b}\t%0" 12451 [(set_attr "type" "ishift") 12452 (set_attr "length" "2")]) 12453 12454;; This pattern can't accept a variable shift count, since shifts by 12455;; zero don't affect the flags. We assume that shifts by constant 12456;; zero are optimized away. 12457(define_insn "*lshrqi2_cmp" 12458 [(set (reg FLAGS_REG) 12459 (compare 12460 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12461 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12462 (const_int 0))) 12463 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12464 (lshiftrt:QI (match_dup 1) (match_dup 2)))] 12465 "ix86_match_ccmode (insn, CCGOCmode) 12466 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands) 12467 && (optimize_size 12468 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12469 "shr{b}\t{%2, %0|%0, %2}" 12470 [(set_attr "type" "ishift") 12471 (set_attr "mode" "QI")]) 12472 12473(define_insn "*lshrqi2_cconly" 12474 [(set (reg FLAGS_REG) 12475 (compare 12476 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12477 (match_operand:QI 2 "const_1_to_31_operand" "I")) 12478 (const_int 0))) 12479 (clobber (match_scratch:QI 0 "=q"))] 12480 "ix86_match_ccmode (insn, CCGOCmode) 12481 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands) 12482 && (optimize_size 12483 || !TARGET_PARTIAL_FLAG_REG_STALL)" 12484 "shr{b}\t{%2, %0|%0, %2}" 12485 [(set_attr "type" "ishift") 12486 (set_attr "mode" "QI")]) 12487 12488;; Rotate instructions 12489 12490(define_expand "rotldi3" 12491 [(set (match_operand:DI 0 "shiftdi_operand" "") 12492 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "") 12493 (match_operand:QI 2 "nonmemory_operand" ""))) 12494 (clobber (reg:CC FLAGS_REG))] 12495 "" 12496{ 12497 if (TARGET_64BIT) 12498 { 12499 ix86_expand_binary_operator (ROTATE, DImode, operands); 12500 DONE; 12501 } 12502 if (!const_1_to_31_operand (operands[2], VOIDmode)) 12503 FAIL; 12504 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2])); 12505 DONE; 12506}) 12507 12508;; Implement rotation using two double-precision shift instructions 12509;; and a scratch register. 12510(define_insn_and_split "ix86_rotldi3" 12511 [(set (match_operand:DI 0 "register_operand" "=r") 12512 (rotate:DI (match_operand:DI 1 "register_operand" "0") 12513 (match_operand:QI 2 "const_1_to_31_operand" "I"))) 12514 (clobber (reg:CC FLAGS_REG)) 12515 (clobber (match_scratch:SI 3 "=&r"))] 12516 "!TARGET_64BIT" 12517 "" 12518 "&& reload_completed" 12519 [(set (match_dup 3) (match_dup 4)) 12520 (parallel 12521 [(set (match_dup 4) 12522 (ior:SI (ashift:SI (match_dup 4) (match_dup 2)) 12523 (lshiftrt:SI (match_dup 5) 12524 (minus:QI (const_int 32) (match_dup 2))))) 12525 (clobber (reg:CC FLAGS_REG))]) 12526 (parallel 12527 [(set (match_dup 5) 12528 (ior:SI (ashift:SI (match_dup 5) (match_dup 2)) 12529 (lshiftrt:SI (match_dup 3) 12530 (minus:QI (const_int 32) (match_dup 2))))) 12531 (clobber (reg:CC FLAGS_REG))])] 12532 "split_di (operands, 1, operands + 4, operands + 5);") 12533 12534(define_insn "*rotlsi3_1_one_bit_rex64" 12535 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12536 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12537 (match_operand:QI 2 "const1_operand" ""))) 12538 (clobber (reg:CC FLAGS_REG))] 12539 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands) 12540 && (TARGET_SHIFT1 || optimize_size)" 12541 "rol{q}\t%0" 12542 [(set_attr "type" "rotate") 12543 (set (attr "length") 12544 (if_then_else (match_operand:DI 0 "register_operand" "") 12545 (const_string "2") 12546 (const_string "*")))]) 12547 12548(define_insn "*rotldi3_1_rex64" 12549 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 12550 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 12551 (match_operand:QI 2 "nonmemory_operand" "e,c"))) 12552 (clobber (reg:CC FLAGS_REG))] 12553 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)" 12554 "@ 12555 rol{q}\t{%2, %0|%0, %2} 12556 rol{q}\t{%b2, %0|%0, %b2}" 12557 [(set_attr "type" "rotate") 12558 (set_attr "mode" "DI")]) 12559 12560(define_expand "rotlsi3" 12561 [(set (match_operand:SI 0 "nonimmediate_operand" "") 12562 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "") 12563 (match_operand:QI 2 "nonmemory_operand" ""))) 12564 (clobber (reg:CC FLAGS_REG))] 12565 "" 12566 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;") 12567 12568(define_insn "*rotlsi3_1_one_bit" 12569 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12570 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12571 (match_operand:QI 2 "const1_operand" ""))) 12572 (clobber (reg:CC FLAGS_REG))] 12573 "ix86_binary_operator_ok (ROTATE, SImode, operands) 12574 && (TARGET_SHIFT1 || optimize_size)" 12575 "rol{l}\t%0" 12576 [(set_attr "type" "rotate") 12577 (set (attr "length") 12578 (if_then_else (match_operand:SI 0 "register_operand" "") 12579 (const_string "2") 12580 (const_string "*")))]) 12581 12582(define_insn "*rotlsi3_1_one_bit_zext" 12583 [(set (match_operand:DI 0 "register_operand" "=r") 12584 (zero_extend:DI 12585 (rotate:SI (match_operand:SI 1 "register_operand" "0") 12586 (match_operand:QI 2 "const1_operand" "")))) 12587 (clobber (reg:CC FLAGS_REG))] 12588 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands) 12589 && (TARGET_SHIFT1 || optimize_size)" 12590 "rol{l}\t%k0" 12591 [(set_attr "type" "rotate") 12592 (set_attr "length" "2")]) 12593 12594(define_insn "*rotlsi3_1" 12595 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 12596 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12597 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12598 (clobber (reg:CC FLAGS_REG))] 12599 "ix86_binary_operator_ok (ROTATE, SImode, operands)" 12600 "@ 12601 rol{l}\t{%2, %0|%0, %2} 12602 rol{l}\t{%b2, %0|%0, %b2}" 12603 [(set_attr "type" "rotate") 12604 (set_attr "mode" "SI")]) 12605 12606(define_insn "*rotlsi3_1_zext" 12607 [(set (match_operand:DI 0 "register_operand" "=r,r") 12608 (zero_extend:DI 12609 (rotate:SI (match_operand:SI 1 "register_operand" "0,0") 12610 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 12611 (clobber (reg:CC FLAGS_REG))] 12612 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)" 12613 "@ 12614 rol{l}\t{%2, %k0|%k0, %2} 12615 rol{l}\t{%b2, %k0|%k0, %b2}" 12616 [(set_attr "type" "rotate") 12617 (set_attr "mode" "SI")]) 12618 12619(define_expand "rotlhi3" 12620 [(set (match_operand:HI 0 "nonimmediate_operand" "") 12621 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "") 12622 (match_operand:QI 2 "nonmemory_operand" ""))) 12623 (clobber (reg:CC FLAGS_REG))] 12624 "TARGET_HIMODE_MATH" 12625 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;") 12626 12627(define_insn "*rotlhi3_1_one_bit" 12628 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12629 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12630 (match_operand:QI 2 "const1_operand" ""))) 12631 (clobber (reg:CC FLAGS_REG))] 12632 "ix86_binary_operator_ok (ROTATE, HImode, operands) 12633 && (TARGET_SHIFT1 || optimize_size)" 12634 "rol{w}\t%0" 12635 [(set_attr "type" "rotate") 12636 (set (attr "length") 12637 (if_then_else (match_operand 0 "register_operand" "") 12638 (const_string "2") 12639 (const_string "*")))]) 12640 12641(define_insn "*rotlhi3_1" 12642 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 12643 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 12644 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12645 (clobber (reg:CC FLAGS_REG))] 12646 "ix86_binary_operator_ok (ROTATE, HImode, operands)" 12647 "@ 12648 rol{w}\t{%2, %0|%0, %2} 12649 rol{w}\t{%b2, %0|%0, %b2}" 12650 [(set_attr "type" "rotate") 12651 (set_attr "mode" "HI")]) 12652 12653(define_expand "rotlqi3" 12654 [(set (match_operand:QI 0 "nonimmediate_operand" "") 12655 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "") 12656 (match_operand:QI 2 "nonmemory_operand" ""))) 12657 (clobber (reg:CC FLAGS_REG))] 12658 "TARGET_QIMODE_MATH" 12659 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;") 12660 12661(define_insn "*rotlqi3_1_one_bit_slp" 12662 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 12663 (rotate:QI (match_dup 0) 12664 (match_operand:QI 1 "const1_operand" ""))) 12665 (clobber (reg:CC FLAGS_REG))] 12666 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12667 && (TARGET_SHIFT1 || optimize_size)" 12668 "rol{b}\t%0" 12669 [(set_attr "type" "rotate1") 12670 (set (attr "length") 12671 (if_then_else (match_operand 0 "register_operand" "") 12672 (const_string "2") 12673 (const_string "*")))]) 12674 12675(define_insn "*rotlqi3_1_one_bit" 12676 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12677 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12678 (match_operand:QI 2 "const1_operand" ""))) 12679 (clobber (reg:CC FLAGS_REG))] 12680 "ix86_binary_operator_ok (ROTATE, QImode, operands) 12681 && (TARGET_SHIFT1 || optimize_size)" 12682 "rol{b}\t%0" 12683 [(set_attr "type" "rotate") 12684 (set (attr "length") 12685 (if_then_else (match_operand 0 "register_operand" "") 12686 (const_string "2") 12687 (const_string "*")))]) 12688 12689(define_insn "*rotlqi3_1_slp" 12690 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 12691 (rotate:QI (match_dup 0) 12692 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 12693 (clobber (reg:CC FLAGS_REG))] 12694 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12695 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 12696 "@ 12697 rol{b}\t{%1, %0|%0, %1} 12698 rol{b}\t{%b1, %0|%0, %b1}" 12699 [(set_attr "type" "rotate1") 12700 (set_attr "mode" "QI")]) 12701 12702(define_insn "*rotlqi3_1" 12703 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 12704 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 12705 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12706 (clobber (reg:CC FLAGS_REG))] 12707 "ix86_binary_operator_ok (ROTATE, QImode, operands)" 12708 "@ 12709 rol{b}\t{%2, %0|%0, %2} 12710 rol{b}\t{%b2, %0|%0, %b2}" 12711 [(set_attr "type" "rotate") 12712 (set_attr "mode" "QI")]) 12713 12714(define_expand "rotrdi3" 12715 [(set (match_operand:DI 0 "shiftdi_operand" "") 12716 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "") 12717 (match_operand:QI 2 "nonmemory_operand" ""))) 12718 (clobber (reg:CC FLAGS_REG))] 12719 "" 12720{ 12721 if (TARGET_64BIT) 12722 { 12723 ix86_expand_binary_operator (ROTATERT, DImode, operands); 12724 DONE; 12725 } 12726 if (!const_1_to_31_operand (operands[2], VOIDmode)) 12727 FAIL; 12728 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2])); 12729 DONE; 12730}) 12731 12732;; Implement rotation using two double-precision shift instructions 12733;; and a scratch register. 12734(define_insn_and_split "ix86_rotrdi3" 12735 [(set (match_operand:DI 0 "register_operand" "=r") 12736 (rotatert:DI (match_operand:DI 1 "register_operand" "0") 12737 (match_operand:QI 2 "const_1_to_31_operand" "I"))) 12738 (clobber (reg:CC FLAGS_REG)) 12739 (clobber (match_scratch:SI 3 "=&r"))] 12740 "!TARGET_64BIT" 12741 "" 12742 "&& reload_completed" 12743 [(set (match_dup 3) (match_dup 4)) 12744 (parallel 12745 [(set (match_dup 4) 12746 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2)) 12747 (ashift:SI (match_dup 5) 12748 (minus:QI (const_int 32) (match_dup 2))))) 12749 (clobber (reg:CC FLAGS_REG))]) 12750 (parallel 12751 [(set (match_dup 5) 12752 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2)) 12753 (ashift:SI (match_dup 3) 12754 (minus:QI (const_int 32) (match_dup 2))))) 12755 (clobber (reg:CC FLAGS_REG))])] 12756 "split_di (operands, 1, operands + 4, operands + 5);") 12757 12758(define_insn "*rotrdi3_1_one_bit_rex64" 12759 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 12760 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0") 12761 (match_operand:QI 2 "const1_operand" ""))) 12762 (clobber (reg:CC FLAGS_REG))] 12763 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands) 12764 && (TARGET_SHIFT1 || optimize_size)" 12765 "ror{q}\t%0" 12766 [(set_attr "type" "rotate") 12767 (set (attr "length") 12768 (if_then_else (match_operand:DI 0 "register_operand" "") 12769 (const_string "2") 12770 (const_string "*")))]) 12771 12772(define_insn "*rotrdi3_1_rex64" 12773 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") 12774 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") 12775 (match_operand:QI 2 "nonmemory_operand" "J,c"))) 12776 (clobber (reg:CC FLAGS_REG))] 12777 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)" 12778 "@ 12779 ror{q}\t{%2, %0|%0, %2} 12780 ror{q}\t{%b2, %0|%0, %b2}" 12781 [(set_attr "type" "rotate") 12782 (set_attr "mode" "DI")]) 12783 12784(define_expand "rotrsi3" 12785 [(set (match_operand:SI 0 "nonimmediate_operand" "") 12786 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "") 12787 (match_operand:QI 2 "nonmemory_operand" ""))) 12788 (clobber (reg:CC FLAGS_REG))] 12789 "" 12790 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;") 12791 12792(define_insn "*rotrsi3_1_one_bit" 12793 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 12794 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0") 12795 (match_operand:QI 2 "const1_operand" ""))) 12796 (clobber (reg:CC FLAGS_REG))] 12797 "ix86_binary_operator_ok (ROTATERT, SImode, operands) 12798 && (TARGET_SHIFT1 || optimize_size)" 12799 "ror{l}\t%0" 12800 [(set_attr "type" "rotate") 12801 (set (attr "length") 12802 (if_then_else (match_operand:SI 0 "register_operand" "") 12803 (const_string "2") 12804 (const_string "*")))]) 12805 12806(define_insn "*rotrsi3_1_one_bit_zext" 12807 [(set (match_operand:DI 0 "register_operand" "=r") 12808 (zero_extend:DI 12809 (rotatert:SI (match_operand:SI 1 "register_operand" "0") 12810 (match_operand:QI 2 "const1_operand" "")))) 12811 (clobber (reg:CC FLAGS_REG))] 12812 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands) 12813 && (TARGET_SHIFT1 || optimize_size)" 12814 "ror{l}\t%k0" 12815 [(set_attr "type" "rotate") 12816 (set (attr "length") 12817 (if_then_else (match_operand:SI 0 "register_operand" "") 12818 (const_string "2") 12819 (const_string "*")))]) 12820 12821(define_insn "*rotrsi3_1" 12822 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") 12823 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 12824 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12825 (clobber (reg:CC FLAGS_REG))] 12826 "ix86_binary_operator_ok (ROTATERT, SImode, operands)" 12827 "@ 12828 ror{l}\t{%2, %0|%0, %2} 12829 ror{l}\t{%b2, %0|%0, %b2}" 12830 [(set_attr "type" "rotate") 12831 (set_attr "mode" "SI")]) 12832 12833(define_insn "*rotrsi3_1_zext" 12834 [(set (match_operand:DI 0 "register_operand" "=r,r") 12835 (zero_extend:DI 12836 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0") 12837 (match_operand:QI 2 "nonmemory_operand" "I,c")))) 12838 (clobber (reg:CC FLAGS_REG))] 12839 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)" 12840 "@ 12841 ror{l}\t{%2, %k0|%k0, %2} 12842 ror{l}\t{%b2, %k0|%k0, %b2}" 12843 [(set_attr "type" "rotate") 12844 (set_attr "mode" "SI")]) 12845 12846(define_expand "rotrhi3" 12847 [(set (match_operand:HI 0 "nonimmediate_operand" "") 12848 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "") 12849 (match_operand:QI 2 "nonmemory_operand" ""))) 12850 (clobber (reg:CC FLAGS_REG))] 12851 "TARGET_HIMODE_MATH" 12852 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;") 12853 12854(define_insn "*rotrhi3_one_bit" 12855 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 12856 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0") 12857 (match_operand:QI 2 "const1_operand" ""))) 12858 (clobber (reg:CC FLAGS_REG))] 12859 "ix86_binary_operator_ok (ROTATERT, HImode, operands) 12860 && (TARGET_SHIFT1 || optimize_size)" 12861 "ror{w}\t%0" 12862 [(set_attr "type" "rotate") 12863 (set (attr "length") 12864 (if_then_else (match_operand 0 "register_operand" "") 12865 (const_string "2") 12866 (const_string "*")))]) 12867 12868(define_insn "*rotrhi3" 12869 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") 12870 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 12871 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12872 (clobber (reg:CC FLAGS_REG))] 12873 "ix86_binary_operator_ok (ROTATERT, HImode, operands)" 12874 "@ 12875 ror{w}\t{%2, %0|%0, %2} 12876 ror{w}\t{%b2, %0|%0, %b2}" 12877 [(set_attr "type" "rotate") 12878 (set_attr "mode" "HI")]) 12879 12880(define_expand "rotrqi3" 12881 [(set (match_operand:QI 0 "nonimmediate_operand" "") 12882 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "") 12883 (match_operand:QI 2 "nonmemory_operand" ""))) 12884 (clobber (reg:CC FLAGS_REG))] 12885 "TARGET_QIMODE_MATH" 12886 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;") 12887 12888(define_insn "*rotrqi3_1_one_bit" 12889 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12890 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0") 12891 (match_operand:QI 2 "const1_operand" ""))) 12892 (clobber (reg:CC FLAGS_REG))] 12893 "ix86_binary_operator_ok (ROTATERT, QImode, operands) 12894 && (TARGET_SHIFT1 || optimize_size)" 12895 "ror{b}\t%0" 12896 [(set_attr "type" "rotate") 12897 (set (attr "length") 12898 (if_then_else (match_operand 0 "register_operand" "") 12899 (const_string "2") 12900 (const_string "*")))]) 12901 12902(define_insn "*rotrqi3_1_one_bit_slp" 12903 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 12904 (rotatert:QI (match_dup 0) 12905 (match_operand:QI 1 "const1_operand" ""))) 12906 (clobber (reg:CC FLAGS_REG))] 12907 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12908 && (TARGET_SHIFT1 || optimize_size)" 12909 "ror{b}\t%0" 12910 [(set_attr "type" "rotate1") 12911 (set (attr "length") 12912 (if_then_else (match_operand 0 "register_operand" "") 12913 (const_string "2") 12914 (const_string "*")))]) 12915 12916(define_insn "*rotrqi3_1" 12917 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") 12918 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 12919 (match_operand:QI 2 "nonmemory_operand" "I,c"))) 12920 (clobber (reg:CC FLAGS_REG))] 12921 "ix86_binary_operator_ok (ROTATERT, QImode, operands)" 12922 "@ 12923 ror{b}\t{%2, %0|%0, %2} 12924 ror{b}\t{%b2, %0|%0, %b2}" 12925 [(set_attr "type" "rotate") 12926 (set_attr "mode" "QI")]) 12927 12928(define_insn "*rotrqi3_1_slp" 12929 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) 12930 (rotatert:QI (match_dup 0) 12931 (match_operand:QI 1 "nonmemory_operand" "I,c"))) 12932 (clobber (reg:CC FLAGS_REG))] 12933 "(! TARGET_PARTIAL_REG_STALL || optimize_size) 12934 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 12935 "@ 12936 ror{b}\t{%1, %0|%0, %1} 12937 ror{b}\t{%b1, %0|%0, %b1}" 12938 [(set_attr "type" "rotate1") 12939 (set_attr "mode" "QI")]) 12940 12941;; Bit set / bit test instructions 12942 12943(define_expand "extv" 12944 [(set (match_operand:SI 0 "register_operand" "") 12945 (sign_extract:SI (match_operand:SI 1 "register_operand" "") 12946 (match_operand:SI 2 "const8_operand" "") 12947 (match_operand:SI 3 "const8_operand" "")))] 12948 "" 12949{ 12950 /* Handle extractions from %ah et al. */ 12951 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 12952 FAIL; 12953 12954 /* From mips.md: extract_bit_field doesn't verify that our source 12955 matches the predicate, so check it again here. */ 12956 if (! ext_register_operand (operands[1], VOIDmode)) 12957 FAIL; 12958}) 12959 12960(define_expand "extzv" 12961 [(set (match_operand:SI 0 "register_operand" "") 12962 (zero_extract:SI (match_operand 1 "ext_register_operand" "") 12963 (match_operand:SI 2 "const8_operand" "") 12964 (match_operand:SI 3 "const8_operand" "")))] 12965 "" 12966{ 12967 /* Handle extractions from %ah et al. */ 12968 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 12969 FAIL; 12970 12971 /* From mips.md: extract_bit_field doesn't verify that our source 12972 matches the predicate, so check it again here. */ 12973 if (! ext_register_operand (operands[1], VOIDmode)) 12974 FAIL; 12975}) 12976 12977(define_expand "insv" 12978 [(set (zero_extract (match_operand 0 "ext_register_operand" "") 12979 (match_operand 1 "const8_operand" "") 12980 (match_operand 2 "const8_operand" "")) 12981 (match_operand 3 "register_operand" ""))] 12982 "" 12983{ 12984 /* Handle insertions to %ah et al. */ 12985 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8) 12986 FAIL; 12987 12988 /* From mips.md: insert_bit_field doesn't verify that our source 12989 matches the predicate, so check it again here. */ 12990 if (! ext_register_operand (operands[0], VOIDmode)) 12991 FAIL; 12992 12993 if (TARGET_64BIT) 12994 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3])); 12995 else 12996 emit_insn (gen_movsi_insv_1 (operands[0], operands[3])); 12997 12998 DONE; 12999}) 13000 13001;; %%% bts, btr, btc, bt. 13002;; In general these instructions are *slow* when applied to memory, 13003;; since they enforce atomic operation. When applied to registers, 13004;; it depends on the cpu implementation. They're never faster than 13005;; the corresponding and/ior/xor operations, so with 32-bit there's 13006;; no point. But in 64-bit, we can't hold the relevant immediates 13007;; within the instruction itself, so operating on bits in the high 13008;; 32-bits of a register becomes easier. 13009;; 13010;; These are slow on Nocona, but fast on Athlon64. We do require the use 13011;; of btrq and btcq for corner cases of post-reload expansion of absdf and 13012;; negdf respectively, so they can never be disabled entirely. 13013 13014(define_insn "*btsq" 13015 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 13016 (const_int 1) 13017 (match_operand:DI 1 "const_0_to_63_operand" "")) 13018 (const_int 1)) 13019 (clobber (reg:CC FLAGS_REG))] 13020 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 13021 "bts{q} %1,%0" 13022 [(set_attr "type" "alu1")]) 13023 13024(define_insn "*btrq" 13025 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 13026 (const_int 1) 13027 (match_operand:DI 1 "const_0_to_63_operand" "")) 13028 (const_int 0)) 13029 (clobber (reg:CC FLAGS_REG))] 13030 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 13031 "btr{q} %1,%0" 13032 [(set_attr "type" "alu1")]) 13033 13034(define_insn "*btcq" 13035 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 13036 (const_int 1) 13037 (match_operand:DI 1 "const_0_to_63_operand" "")) 13038 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) 13039 (clobber (reg:CC FLAGS_REG))] 13040 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 13041 "btc{q} %1,%0" 13042 [(set_attr "type" "alu1")]) 13043 13044;; Allow Nocona to avoid these instructions if a register is available. 13045 13046(define_peephole2 13047 [(match_scratch:DI 2 "r") 13048 (parallel [(set (zero_extract:DI 13049 (match_operand:DI 0 "register_operand" "") 13050 (const_int 1) 13051 (match_operand:DI 1 "const_0_to_63_operand" "")) 13052 (const_int 1)) 13053 (clobber (reg:CC FLAGS_REG))])] 13054 "TARGET_64BIT && !TARGET_USE_BT" 13055 [(const_int 0)] 13056{ 13057 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 13058 rtx op1; 13059 13060 if (HOST_BITS_PER_WIDE_INT >= 64) 13061 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13062 else if (i < HOST_BITS_PER_WIDE_INT) 13063 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13064 else 13065 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 13066 13067 op1 = immed_double_const (lo, hi, DImode); 13068 if (i >= 31) 13069 { 13070 emit_move_insn (operands[2], op1); 13071 op1 = operands[2]; 13072 } 13073 13074 emit_insn (gen_iordi3 (operands[0], operands[0], op1)); 13075 DONE; 13076}) 13077 13078(define_peephole2 13079 [(match_scratch:DI 2 "r") 13080 (parallel [(set (zero_extract:DI 13081 (match_operand:DI 0 "register_operand" "") 13082 (const_int 1) 13083 (match_operand:DI 1 "const_0_to_63_operand" "")) 13084 (const_int 0)) 13085 (clobber (reg:CC FLAGS_REG))])] 13086 "TARGET_64BIT && !TARGET_USE_BT" 13087 [(const_int 0)] 13088{ 13089 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 13090 rtx op1; 13091 13092 if (HOST_BITS_PER_WIDE_INT >= 64) 13093 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13094 else if (i < HOST_BITS_PER_WIDE_INT) 13095 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13096 else 13097 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 13098 13099 op1 = immed_double_const (~lo, ~hi, DImode); 13100 if (i >= 32) 13101 { 13102 emit_move_insn (operands[2], op1); 13103 op1 = operands[2]; 13104 } 13105 13106 emit_insn (gen_anddi3 (operands[0], operands[0], op1)); 13107 DONE; 13108}) 13109 13110(define_peephole2 13111 [(match_scratch:DI 2 "r") 13112 (parallel [(set (zero_extract:DI 13113 (match_operand:DI 0 "register_operand" "") 13114 (const_int 1) 13115 (match_operand:DI 1 "const_0_to_63_operand" "")) 13116 (not:DI (zero_extract:DI 13117 (match_dup 0) (const_int 1) (match_dup 1)))) 13118 (clobber (reg:CC FLAGS_REG))])] 13119 "TARGET_64BIT && !TARGET_USE_BT" 13120 [(const_int 0)] 13121{ 13122 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 13123 rtx op1; 13124 13125 if (HOST_BITS_PER_WIDE_INT >= 64) 13126 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13127 else if (i < HOST_BITS_PER_WIDE_INT) 13128 lo = (HOST_WIDE_INT)1 << i, hi = 0; 13129 else 13130 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 13131 13132 op1 = immed_double_const (lo, hi, DImode); 13133 if (i >= 31) 13134 { 13135 emit_move_insn (operands[2], op1); 13136 op1 = operands[2]; 13137 } 13138 13139 emit_insn (gen_xordi3 (operands[0], operands[0], op1)); 13140 DONE; 13141}) 13142 13143;; Store-flag instructions. 13144 13145;; For all sCOND expanders, also expand the compare or test insn that 13146;; generates cc0. Generate an equality comparison if `seq' or `sne'. 13147 13148;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way 13149;; to avoid partial register stalls. Otherwise do things the setcc+movzx 13150;; way, which can later delete the movzx if only QImode is needed. 13151 13152(define_expand "seq" 13153 [(set (match_operand:QI 0 "register_operand" "") 13154 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))] 13155 "" 13156 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;") 13157 13158(define_expand "sne" 13159 [(set (match_operand:QI 0 "register_operand" "") 13160 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))] 13161 "" 13162 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;") 13163 13164(define_expand "sgt" 13165 [(set (match_operand:QI 0 "register_operand" "") 13166 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13167 "" 13168 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;") 13169 13170(define_expand "sgtu" 13171 [(set (match_operand:QI 0 "register_operand" "") 13172 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13173 "" 13174 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;") 13175 13176(define_expand "slt" 13177 [(set (match_operand:QI 0 "register_operand" "") 13178 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13179 "" 13180 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;") 13181 13182(define_expand "sltu" 13183 [(set (match_operand:QI 0 "register_operand" "") 13184 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13185 "" 13186 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;") 13187 13188(define_expand "sge" 13189 [(set (match_operand:QI 0 "register_operand" "") 13190 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))] 13191 "" 13192 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;") 13193 13194(define_expand "sgeu" 13195 [(set (match_operand:QI 0 "register_operand" "") 13196 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13197 "" 13198 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;") 13199 13200(define_expand "sle" 13201 [(set (match_operand:QI 0 "register_operand" "") 13202 (le:QI (reg:CC FLAGS_REG) (const_int 0)))] 13203 "" 13204 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;") 13205 13206(define_expand "sleu" 13207 [(set (match_operand:QI 0 "register_operand" "") 13208 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))] 13209 "" 13210 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;") 13211 13212(define_expand "sunordered" 13213 [(set (match_operand:QI 0 "register_operand" "") 13214 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))] 13215 "TARGET_80387 || TARGET_SSE" 13216 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;") 13217 13218(define_expand "sordered" 13219 [(set (match_operand:QI 0 "register_operand" "") 13220 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))] 13221 "TARGET_80387" 13222 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;") 13223 13224(define_expand "suneq" 13225 [(set (match_operand:QI 0 "register_operand" "") 13226 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))] 13227 "TARGET_80387 || TARGET_SSE" 13228 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;") 13229 13230(define_expand "sunge" 13231 [(set (match_operand:QI 0 "register_operand" "") 13232 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))] 13233 "TARGET_80387 || TARGET_SSE" 13234 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;") 13235 13236(define_expand "sungt" 13237 [(set (match_operand:QI 0 "register_operand" "") 13238 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13239 "TARGET_80387 || TARGET_SSE" 13240 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;") 13241 13242(define_expand "sunle" 13243 [(set (match_operand:QI 0 "register_operand" "") 13244 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))] 13245 "TARGET_80387 || TARGET_SSE" 13246 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;") 13247 13248(define_expand "sunlt" 13249 [(set (match_operand:QI 0 "register_operand" "") 13250 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13251 "TARGET_80387 || TARGET_SSE" 13252 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;") 13253 13254(define_expand "sltgt" 13255 [(set (match_operand:QI 0 "register_operand" "") 13256 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))] 13257 "TARGET_80387 || TARGET_SSE" 13258 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;") 13259 13260(define_insn "*setcc_1" 13261 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 13262 (match_operator:QI 1 "ix86_comparison_operator" 13263 [(reg FLAGS_REG) (const_int 0)]))] 13264 "" 13265 "set%C1\t%0" 13266 [(set_attr "type" "setcc") 13267 (set_attr "mode" "QI")]) 13268 13269(define_insn "*setcc_2" 13270 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 13271 (match_operator:QI 1 "ix86_comparison_operator" 13272 [(reg FLAGS_REG) (const_int 0)]))] 13273 "" 13274 "set%C1\t%0" 13275 [(set_attr "type" "setcc") 13276 (set_attr "mode" "QI")]) 13277 13278;; In general it is not safe to assume too much about CCmode registers, 13279;; so simplify-rtx stops when it sees a second one. Under certain 13280;; conditions this is safe on x86, so help combine not create 13281;; 13282;; seta %al 13283;; testb %al, %al 13284;; sete %al 13285 13286(define_split 13287 [(set (match_operand:QI 0 "nonimmediate_operand" "") 13288 (ne:QI (match_operator 1 "ix86_comparison_operator" 13289 [(reg FLAGS_REG) (const_int 0)]) 13290 (const_int 0)))] 13291 "" 13292 [(set (match_dup 0) (match_dup 1))] 13293{ 13294 PUT_MODE (operands[1], QImode); 13295}) 13296 13297(define_split 13298 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 13299 (ne:QI (match_operator 1 "ix86_comparison_operator" 13300 [(reg FLAGS_REG) (const_int 0)]) 13301 (const_int 0)))] 13302 "" 13303 [(set (match_dup 0) (match_dup 1))] 13304{ 13305 PUT_MODE (operands[1], QImode); 13306}) 13307 13308(define_split 13309 [(set (match_operand:QI 0 "nonimmediate_operand" "") 13310 (eq:QI (match_operator 1 "ix86_comparison_operator" 13311 [(reg FLAGS_REG) (const_int 0)]) 13312 (const_int 0)))] 13313 "" 13314 [(set (match_dup 0) (match_dup 1))] 13315{ 13316 rtx new_op1 = copy_rtx (operands[1]); 13317 operands[1] = new_op1; 13318 PUT_MODE (new_op1, QImode); 13319 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), 13320 GET_MODE (XEXP (new_op1, 0)))); 13321 13322 /* Make sure that (a) the CCmode we have for the flags is strong 13323 enough for the reversed compare or (b) we have a valid FP compare. */ 13324 if (! ix86_comparison_operator (new_op1, VOIDmode)) 13325 FAIL; 13326}) 13327 13328(define_split 13329 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "")) 13330 (eq:QI (match_operator 1 "ix86_comparison_operator" 13331 [(reg FLAGS_REG) (const_int 0)]) 13332 (const_int 0)))] 13333 "" 13334 [(set (match_dup 0) (match_dup 1))] 13335{ 13336 rtx new_op1 = copy_rtx (operands[1]); 13337 operands[1] = new_op1; 13338 PUT_MODE (new_op1, QImode); 13339 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), 13340 GET_MODE (XEXP (new_op1, 0)))); 13341 13342 /* Make sure that (a) the CCmode we have for the flags is strong 13343 enough for the reversed compare or (b) we have a valid FP compare. */ 13344 if (! ix86_comparison_operator (new_op1, VOIDmode)) 13345 FAIL; 13346}) 13347 13348;; The SSE store flag instructions saves 0 or 0xffffffff to the result. 13349;; subsequent logical operations are used to imitate conditional moves. 13350;; 0xffffffff is NaN, but not in normalized form, so we can't represent 13351;; it directly. 13352 13353(define_insn "*sse_setccsf" 13354 [(set (match_operand:SF 0 "register_operand" "=x") 13355 (match_operator:SF 1 "sse_comparison_operator" 13356 [(match_operand:SF 2 "register_operand" "0") 13357 (match_operand:SF 3 "nonimmediate_operand" "xm")]))] 13358 "TARGET_SSE" 13359 "cmp%D1ss\t{%3, %0|%0, %3}" 13360 [(set_attr "type" "ssecmp") 13361 (set_attr "mode" "SF")]) 13362 13363(define_insn "*sse_setccdf" 13364 [(set (match_operand:DF 0 "register_operand" "=Y") 13365 (match_operator:DF 1 "sse_comparison_operator" 13366 [(match_operand:DF 2 "register_operand" "0") 13367 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))] 13368 "TARGET_SSE2" 13369 "cmp%D1sd\t{%3, %0|%0, %3}" 13370 [(set_attr "type" "ssecmp") 13371 (set_attr "mode" "DF")]) 13372 13373;; Basic conditional jump instructions. 13374;; We ignore the overflow flag for signed branch instructions. 13375 13376;; For all bCOND expanders, also expand the compare or test insn that 13377;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'. 13378 13379(define_expand "beq" 13380 [(set (pc) 13381 (if_then_else (match_dup 1) 13382 (label_ref (match_operand 0 "" "")) 13383 (pc)))] 13384 "" 13385 "ix86_expand_branch (EQ, operands[0]); DONE;") 13386 13387(define_expand "bne" 13388 [(set (pc) 13389 (if_then_else (match_dup 1) 13390 (label_ref (match_operand 0 "" "")) 13391 (pc)))] 13392 "" 13393 "ix86_expand_branch (NE, operands[0]); DONE;") 13394 13395(define_expand "bgt" 13396 [(set (pc) 13397 (if_then_else (match_dup 1) 13398 (label_ref (match_operand 0 "" "")) 13399 (pc)))] 13400 "" 13401 "ix86_expand_branch (GT, operands[0]); DONE;") 13402 13403(define_expand "bgtu" 13404 [(set (pc) 13405 (if_then_else (match_dup 1) 13406 (label_ref (match_operand 0 "" "")) 13407 (pc)))] 13408 "" 13409 "ix86_expand_branch (GTU, operands[0]); DONE;") 13410 13411(define_expand "blt" 13412 [(set (pc) 13413 (if_then_else (match_dup 1) 13414 (label_ref (match_operand 0 "" "")) 13415 (pc)))] 13416 "" 13417 "ix86_expand_branch (LT, operands[0]); DONE;") 13418 13419(define_expand "bltu" 13420 [(set (pc) 13421 (if_then_else (match_dup 1) 13422 (label_ref (match_operand 0 "" "")) 13423 (pc)))] 13424 "" 13425 "ix86_expand_branch (LTU, operands[0]); DONE;") 13426 13427(define_expand "bge" 13428 [(set (pc) 13429 (if_then_else (match_dup 1) 13430 (label_ref (match_operand 0 "" "")) 13431 (pc)))] 13432 "" 13433 "ix86_expand_branch (GE, operands[0]); DONE;") 13434 13435(define_expand "bgeu" 13436 [(set (pc) 13437 (if_then_else (match_dup 1) 13438 (label_ref (match_operand 0 "" "")) 13439 (pc)))] 13440 "" 13441 "ix86_expand_branch (GEU, operands[0]); DONE;") 13442 13443(define_expand "ble" 13444 [(set (pc) 13445 (if_then_else (match_dup 1) 13446 (label_ref (match_operand 0 "" "")) 13447 (pc)))] 13448 "" 13449 "ix86_expand_branch (LE, operands[0]); DONE;") 13450 13451(define_expand "bleu" 13452 [(set (pc) 13453 (if_then_else (match_dup 1) 13454 (label_ref (match_operand 0 "" "")) 13455 (pc)))] 13456 "" 13457 "ix86_expand_branch (LEU, operands[0]); DONE;") 13458 13459(define_expand "bunordered" 13460 [(set (pc) 13461 (if_then_else (match_dup 1) 13462 (label_ref (match_operand 0 "" "")) 13463 (pc)))] 13464 "TARGET_80387 || TARGET_SSE_MATH" 13465 "ix86_expand_branch (UNORDERED, operands[0]); DONE;") 13466 13467(define_expand "bordered" 13468 [(set (pc) 13469 (if_then_else (match_dup 1) 13470 (label_ref (match_operand 0 "" "")) 13471 (pc)))] 13472 "TARGET_80387 || TARGET_SSE_MATH" 13473 "ix86_expand_branch (ORDERED, operands[0]); DONE;") 13474 13475(define_expand "buneq" 13476 [(set (pc) 13477 (if_then_else (match_dup 1) 13478 (label_ref (match_operand 0 "" "")) 13479 (pc)))] 13480 "TARGET_80387 || TARGET_SSE_MATH" 13481 "ix86_expand_branch (UNEQ, operands[0]); DONE;") 13482 13483(define_expand "bunge" 13484 [(set (pc) 13485 (if_then_else (match_dup 1) 13486 (label_ref (match_operand 0 "" "")) 13487 (pc)))] 13488 "TARGET_80387 || TARGET_SSE_MATH" 13489 "ix86_expand_branch (UNGE, operands[0]); DONE;") 13490 13491(define_expand "bungt" 13492 [(set (pc) 13493 (if_then_else (match_dup 1) 13494 (label_ref (match_operand 0 "" "")) 13495 (pc)))] 13496 "TARGET_80387 || TARGET_SSE_MATH" 13497 "ix86_expand_branch (UNGT, operands[0]); DONE;") 13498 13499(define_expand "bunle" 13500 [(set (pc) 13501 (if_then_else (match_dup 1) 13502 (label_ref (match_operand 0 "" "")) 13503 (pc)))] 13504 "TARGET_80387 || TARGET_SSE_MATH" 13505 "ix86_expand_branch (UNLE, operands[0]); DONE;") 13506 13507(define_expand "bunlt" 13508 [(set (pc) 13509 (if_then_else (match_dup 1) 13510 (label_ref (match_operand 0 "" "")) 13511 (pc)))] 13512 "TARGET_80387 || TARGET_SSE_MATH" 13513 "ix86_expand_branch (UNLT, operands[0]); DONE;") 13514 13515(define_expand "bltgt" 13516 [(set (pc) 13517 (if_then_else (match_dup 1) 13518 (label_ref (match_operand 0 "" "")) 13519 (pc)))] 13520 "TARGET_80387 || TARGET_SSE_MATH" 13521 "ix86_expand_branch (LTGT, operands[0]); DONE;") 13522 13523(define_insn "*jcc_1" 13524 [(set (pc) 13525 (if_then_else (match_operator 1 "ix86_comparison_operator" 13526 [(reg FLAGS_REG) (const_int 0)]) 13527 (label_ref (match_operand 0 "" "")) 13528 (pc)))] 13529 "" 13530 "%+j%C1\t%l0" 13531 [(set_attr "type" "ibr") 13532 (set_attr "modrm" "0") 13533 (set (attr "length") 13534 (if_then_else (and (ge (minus (match_dup 0) (pc)) 13535 (const_int -126)) 13536 (lt (minus (match_dup 0) (pc)) 13537 (const_int 128))) 13538 (const_int 2) 13539 (const_int 6)))]) 13540 13541(define_insn "*jcc_2" 13542 [(set (pc) 13543 (if_then_else (match_operator 1 "ix86_comparison_operator" 13544 [(reg FLAGS_REG) (const_int 0)]) 13545 (pc) 13546 (label_ref (match_operand 0 "" ""))))] 13547 "" 13548 "%+j%c1\t%l0" 13549 [(set_attr "type" "ibr") 13550 (set_attr "modrm" "0") 13551 (set (attr "length") 13552 (if_then_else (and (ge (minus (match_dup 0) (pc)) 13553 (const_int -126)) 13554 (lt (minus (match_dup 0) (pc)) 13555 (const_int 128))) 13556 (const_int 2) 13557 (const_int 6)))]) 13558 13559;; In general it is not safe to assume too much about CCmode registers, 13560;; so simplify-rtx stops when it sees a second one. Under certain 13561;; conditions this is safe on x86, so help combine not create 13562;; 13563;; seta %al 13564;; testb %al, %al 13565;; je Lfoo 13566 13567(define_split 13568 [(set (pc) 13569 (if_then_else (ne (match_operator 0 "ix86_comparison_operator" 13570 [(reg FLAGS_REG) (const_int 0)]) 13571 (const_int 0)) 13572 (label_ref (match_operand 1 "" "")) 13573 (pc)))] 13574 "" 13575 [(set (pc) 13576 (if_then_else (match_dup 0) 13577 (label_ref (match_dup 1)) 13578 (pc)))] 13579{ 13580 PUT_MODE (operands[0], VOIDmode); 13581}) 13582 13583(define_split 13584 [(set (pc) 13585 (if_then_else (eq (match_operator 0 "ix86_comparison_operator" 13586 [(reg FLAGS_REG) (const_int 0)]) 13587 (const_int 0)) 13588 (label_ref (match_operand 1 "" "")) 13589 (pc)))] 13590 "" 13591 [(set (pc) 13592 (if_then_else (match_dup 0) 13593 (label_ref (match_dup 1)) 13594 (pc)))] 13595{ 13596 rtx new_op0 = copy_rtx (operands[0]); 13597 operands[0] = new_op0; 13598 PUT_MODE (new_op0, VOIDmode); 13599 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0), 13600 GET_MODE (XEXP (new_op0, 0)))); 13601 13602 /* Make sure that (a) the CCmode we have for the flags is strong 13603 enough for the reversed compare or (b) we have a valid FP compare. */ 13604 if (! ix86_comparison_operator (new_op0, VOIDmode)) 13605 FAIL; 13606}) 13607 13608;; Define combination compare-and-branch fp compare instructions to use 13609;; during early optimization. Splitting the operation apart early makes 13610;; for bad code when we want to reverse the operation. 13611 13612(define_insn "*fp_jcc_1_mixed" 13613 [(set (pc) 13614 (if_then_else (match_operator 0 "comparison_operator" 13615 [(match_operand 1 "register_operand" "f,x") 13616 (match_operand 2 "nonimmediate_operand" "f,xm")]) 13617 (label_ref (match_operand 3 "" "")) 13618 (pc))) 13619 (clobber (reg:CCFP FPSR_REG)) 13620 (clobber (reg:CCFP FLAGS_REG))] 13621 "TARGET_MIX_SSE_I387 13622 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13623 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13624 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13625 "#") 13626 13627(define_insn "*fp_jcc_1_sse" 13628 [(set (pc) 13629 (if_then_else (match_operator 0 "comparison_operator" 13630 [(match_operand 1 "register_operand" "x") 13631 (match_operand 2 "nonimmediate_operand" "xm")]) 13632 (label_ref (match_operand 3 "" "")) 13633 (pc))) 13634 (clobber (reg:CCFP FPSR_REG)) 13635 (clobber (reg:CCFP FLAGS_REG))] 13636 "TARGET_SSE_MATH 13637 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13638 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13639 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13640 "#") 13641 13642(define_insn "*fp_jcc_1_387" 13643 [(set (pc) 13644 (if_then_else (match_operator 0 "comparison_operator" 13645 [(match_operand 1 "register_operand" "f") 13646 (match_operand 2 "register_operand" "f")]) 13647 (label_ref (match_operand 3 "" "")) 13648 (pc))) 13649 (clobber (reg:CCFP FPSR_REG)) 13650 (clobber (reg:CCFP FLAGS_REG))] 13651 "TARGET_CMOVE && TARGET_80387 13652 && FLOAT_MODE_P (GET_MODE (operands[1])) 13653 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13654 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13655 "#") 13656 13657(define_insn "*fp_jcc_2_mixed" 13658 [(set (pc) 13659 (if_then_else (match_operator 0 "comparison_operator" 13660 [(match_operand 1 "register_operand" "f,x") 13661 (match_operand 2 "nonimmediate_operand" "f,xm")]) 13662 (pc) 13663 (label_ref (match_operand 3 "" "")))) 13664 (clobber (reg:CCFP FPSR_REG)) 13665 (clobber (reg:CCFP FLAGS_REG))] 13666 "TARGET_MIX_SSE_I387 13667 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13668 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13669 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13670 "#") 13671 13672(define_insn "*fp_jcc_2_sse" 13673 [(set (pc) 13674 (if_then_else (match_operator 0 "comparison_operator" 13675 [(match_operand 1 "register_operand" "x") 13676 (match_operand 2 "nonimmediate_operand" "xm")]) 13677 (pc) 13678 (label_ref (match_operand 3 "" "")))) 13679 (clobber (reg:CCFP FPSR_REG)) 13680 (clobber (reg:CCFP FLAGS_REG))] 13681 "TARGET_SSE_MATH 13682 && SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 13683 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13684 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13685 "#") 13686 13687(define_insn "*fp_jcc_2_387" 13688 [(set (pc) 13689 (if_then_else (match_operator 0 "comparison_operator" 13690 [(match_operand 1 "register_operand" "f") 13691 (match_operand 2 "register_operand" "f")]) 13692 (pc) 13693 (label_ref (match_operand 3 "" "")))) 13694 (clobber (reg:CCFP FPSR_REG)) 13695 (clobber (reg:CCFP FLAGS_REG))] 13696 "TARGET_CMOVE && TARGET_80387 13697 && FLOAT_MODE_P (GET_MODE (operands[1])) 13698 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13699 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13700 "#") 13701 13702(define_insn "*fp_jcc_3_387" 13703 [(set (pc) 13704 (if_then_else (match_operator 0 "comparison_operator" 13705 [(match_operand 1 "register_operand" "f") 13706 (match_operand 2 "nonimmediate_operand" "fm")]) 13707 (label_ref (match_operand 3 "" "")) 13708 (pc))) 13709 (clobber (reg:CCFP FPSR_REG)) 13710 (clobber (reg:CCFP FLAGS_REG)) 13711 (clobber (match_scratch:HI 4 "=a"))] 13712 "TARGET_80387 13713 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) 13714 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13715 && !ix86_use_fcomi_compare (GET_CODE (operands[0])) 13716 && SELECT_CC_MODE (GET_CODE (operands[0]), 13717 operands[1], operands[2]) == CCFPmode 13718 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13719 "#") 13720 13721(define_insn "*fp_jcc_4_387" 13722 [(set (pc) 13723 (if_then_else (match_operator 0 "comparison_operator" 13724 [(match_operand 1 "register_operand" "f") 13725 (match_operand 2 "nonimmediate_operand" "fm")]) 13726 (pc) 13727 (label_ref (match_operand 3 "" "")))) 13728 (clobber (reg:CCFP FPSR_REG)) 13729 (clobber (reg:CCFP FLAGS_REG)) 13730 (clobber (match_scratch:HI 4 "=a"))] 13731 "TARGET_80387 13732 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode) 13733 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13734 && !ix86_use_fcomi_compare (GET_CODE (operands[0])) 13735 && SELECT_CC_MODE (GET_CODE (operands[0]), 13736 operands[1], operands[2]) == CCFPmode 13737 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13738 "#") 13739 13740(define_insn "*fp_jcc_5_387" 13741 [(set (pc) 13742 (if_then_else (match_operator 0 "comparison_operator" 13743 [(match_operand 1 "register_operand" "f") 13744 (match_operand 2 "register_operand" "f")]) 13745 (label_ref (match_operand 3 "" "")) 13746 (pc))) 13747 (clobber (reg:CCFP FPSR_REG)) 13748 (clobber (reg:CCFP FLAGS_REG)) 13749 (clobber (match_scratch:HI 4 "=a"))] 13750 "TARGET_80387 13751 && FLOAT_MODE_P (GET_MODE (operands[1])) 13752 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13753 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13754 "#") 13755 13756(define_insn "*fp_jcc_6_387" 13757 [(set (pc) 13758 (if_then_else (match_operator 0 "comparison_operator" 13759 [(match_operand 1 "register_operand" "f") 13760 (match_operand 2 "register_operand" "f")]) 13761 (pc) 13762 (label_ref (match_operand 3 "" "")))) 13763 (clobber (reg:CCFP FPSR_REG)) 13764 (clobber (reg:CCFP FLAGS_REG)) 13765 (clobber (match_scratch:HI 4 "=a"))] 13766 "TARGET_80387 13767 && FLOAT_MODE_P (GET_MODE (operands[1])) 13768 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13769 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13770 "#") 13771 13772(define_insn "*fp_jcc_7_387" 13773 [(set (pc) 13774 (if_then_else (match_operator 0 "comparison_operator" 13775 [(match_operand 1 "register_operand" "f") 13776 (match_operand 2 "const0_operand" "X")]) 13777 (label_ref (match_operand 3 "" "")) 13778 (pc))) 13779 (clobber (reg:CCFP FPSR_REG)) 13780 (clobber (reg:CCFP FLAGS_REG)) 13781 (clobber (match_scratch:HI 4 "=a"))] 13782 "TARGET_80387 13783 && FLOAT_MODE_P (GET_MODE (operands[1])) 13784 && GET_MODE (operands[1]) == GET_MODE (operands[2]) 13785 && !ix86_use_fcomi_compare (GET_CODE (operands[0])) 13786 && SELECT_CC_MODE (GET_CODE (operands[0]), 13787 operands[1], operands[2]) == CCFPmode 13788 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))" 13789 "#") 13790 13791;; The order of operands in *fp_jcc_8_387 is forced by combine in 13792;; simplify_comparison () function. Float operator is treated as RTX_OBJ 13793;; with a precedence over other operators and is always put in the first 13794;; place. Swap condition and operands to match ficom instruction. 13795 13796(define_insn "*fp_jcc_8<mode>_387" 13797 [(set (pc) 13798 (if_then_else (match_operator 0 "comparison_operator" 13799 [(match_operator 1 "float_operator" 13800 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")]) 13801 (match_operand 3 "register_operand" "f,f")]) 13802 (label_ref (match_operand 4 "" "")) 13803 (pc))) 13804 (clobber (reg:CCFP FPSR_REG)) 13805 (clobber (reg:CCFP FLAGS_REG)) 13806 (clobber (match_scratch:HI 5 "=a,a"))] 13807 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 13808 && FLOAT_MODE_P (GET_MODE (operands[3])) 13809 && GET_MODE (operands[1]) == GET_MODE (operands[3]) 13810 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0]))) 13811 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode 13812 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))" 13813 "#") 13814 13815(define_split 13816 [(set (pc) 13817 (if_then_else (match_operator 0 "comparison_operator" 13818 [(match_operand 1 "register_operand" "") 13819 (match_operand 2 "nonimmediate_operand" "")]) 13820 (match_operand 3 "" "") 13821 (match_operand 4 "" ""))) 13822 (clobber (reg:CCFP FPSR_REG)) 13823 (clobber (reg:CCFP FLAGS_REG))] 13824 "reload_completed" 13825 [(const_int 0)] 13826{ 13827 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 13828 operands[3], operands[4], NULL_RTX, NULL_RTX); 13829 DONE; 13830}) 13831 13832(define_split 13833 [(set (pc) 13834 (if_then_else (match_operator 0 "comparison_operator" 13835 [(match_operand 1 "register_operand" "") 13836 (match_operand 2 "general_operand" "")]) 13837 (match_operand 3 "" "") 13838 (match_operand 4 "" ""))) 13839 (clobber (reg:CCFP FPSR_REG)) 13840 (clobber (reg:CCFP FLAGS_REG)) 13841 (clobber (match_scratch:HI 5 "=a"))] 13842 "reload_completed" 13843 [(const_int 0)] 13844{ 13845 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 13846 operands[3], operands[4], operands[5], NULL_RTX); 13847 DONE; 13848}) 13849 13850(define_split 13851 [(set (pc) 13852 (if_then_else (match_operator 0 "comparison_operator" 13853 [(match_operator 1 "float_operator" 13854 [(match_operand:X87MODEI12 2 "memory_operand" "")]) 13855 (match_operand 3 "register_operand" "")]) 13856 (match_operand 4 "" "") 13857 (match_operand 5 "" ""))) 13858 (clobber (reg:CCFP FPSR_REG)) 13859 (clobber (reg:CCFP FLAGS_REG)) 13860 (clobber (match_scratch:HI 6 "=a"))] 13861 "reload_completed" 13862 [(const_int 0)] 13863{ 13864 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]); 13865 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), 13866 operands[3], operands[7], 13867 operands[4], operands[5], operands[6], NULL_RTX); 13868 DONE; 13869}) 13870 13871;; %%% Kill this when reload knows how to do it. 13872(define_split 13873 [(set (pc) 13874 (if_then_else (match_operator 0 "comparison_operator" 13875 [(match_operator 1 "float_operator" 13876 [(match_operand:X87MODEI12 2 "register_operand" "")]) 13877 (match_operand 3 "register_operand" "")]) 13878 (match_operand 4 "" "") 13879 (match_operand 5 "" ""))) 13880 (clobber (reg:CCFP FPSR_REG)) 13881 (clobber (reg:CCFP FLAGS_REG)) 13882 (clobber (match_scratch:HI 6 "=a"))] 13883 "reload_completed" 13884 [(const_int 0)] 13885{ 13886 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); 13887 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]); 13888 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), 13889 operands[3], operands[7], 13890 operands[4], operands[5], operands[6], operands[2]); 13891 DONE; 13892}) 13893 13894;; Unconditional and other jump instructions 13895 13896(define_insn "jump" 13897 [(set (pc) 13898 (label_ref (match_operand 0 "" "")))] 13899 "" 13900 "jmp\t%l0" 13901 [(set_attr "type" "ibr") 13902 (set (attr "length") 13903 (if_then_else (and (ge (minus (match_dup 0) (pc)) 13904 (const_int -126)) 13905 (lt (minus (match_dup 0) (pc)) 13906 (const_int 128))) 13907 (const_int 2) 13908 (const_int 5))) 13909 (set_attr "modrm" "0")]) 13910 13911(define_expand "indirect_jump" 13912 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))] 13913 "" 13914 "") 13915 13916(define_insn "*indirect_jump" 13917 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))] 13918 "!TARGET_64BIT" 13919 "jmp\t%A0" 13920 [(set_attr "type" "ibr") 13921 (set_attr "length_immediate" "0")]) 13922 13923(define_insn "*indirect_jump_rtx64" 13924 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))] 13925 "TARGET_64BIT" 13926 "jmp\t%A0" 13927 [(set_attr "type" "ibr") 13928 (set_attr "length_immediate" "0")]) 13929 13930(define_expand "tablejump" 13931 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm")) 13932 (use (label_ref (match_operand 1 "" "")))])] 13933 "" 13934{ 13935 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit) 13936 relative. Convert the relative address to an absolute address. */ 13937 if (flag_pic) 13938 { 13939 rtx op0, op1; 13940 enum rtx_code code; 13941 13942 if (TARGET_64BIT) 13943 { 13944 code = PLUS; 13945 op0 = operands[0]; 13946 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]); 13947 } 13948 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA) 13949 { 13950 code = PLUS; 13951 op0 = operands[0]; 13952 op1 = pic_offset_table_rtx; 13953 } 13954 else 13955 { 13956 code = MINUS; 13957 op0 = pic_offset_table_rtx; 13958 op1 = operands[0]; 13959 } 13960 13961 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0, 13962 OPTAB_DIRECT); 13963 } 13964}) 13965 13966(define_insn "*tablejump_1" 13967 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm")) 13968 (use (label_ref (match_operand 1 "" "")))] 13969 "!TARGET_64BIT" 13970 "jmp\t%A0" 13971 [(set_attr "type" "ibr") 13972 (set_attr "length_immediate" "0")]) 13973 13974(define_insn "*tablejump_1_rtx64" 13975 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm")) 13976 (use (label_ref (match_operand 1 "" "")))] 13977 "TARGET_64BIT" 13978 "jmp\t%A0" 13979 [(set_attr "type" "ibr") 13980 (set_attr "length_immediate" "0")]) 13981 13982;; Convert setcc + movzbl to xor + setcc if operands don't overlap. 13983 13984(define_peephole2 13985 [(set (reg FLAGS_REG) (match_operand 0 "" "")) 13986 (set (match_operand:QI 1 "register_operand" "") 13987 (match_operator:QI 2 "ix86_comparison_operator" 13988 [(reg FLAGS_REG) (const_int 0)])) 13989 (set (match_operand 3 "q_regs_operand" "") 13990 (zero_extend (match_dup 1)))] 13991 "(peep2_reg_dead_p (3, operands[1]) 13992 || operands_match_p (operands[1], operands[3])) 13993 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 13994 [(set (match_dup 4) (match_dup 0)) 13995 (set (strict_low_part (match_dup 5)) 13996 (match_dup 2))] 13997{ 13998 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 13999 operands[5] = gen_lowpart (QImode, operands[3]); 14000 ix86_expand_clear (operands[3]); 14001}) 14002 14003;; Similar, but match zero_extendhisi2_and, which adds a clobber. 14004 14005(define_peephole2 14006 [(set (reg FLAGS_REG) (match_operand 0 "" "")) 14007 (set (match_operand:QI 1 "register_operand" "") 14008 (match_operator:QI 2 "ix86_comparison_operator" 14009 [(reg FLAGS_REG) (const_int 0)])) 14010 (parallel [(set (match_operand 3 "q_regs_operand" "") 14011 (zero_extend (match_dup 1))) 14012 (clobber (reg:CC FLAGS_REG))])] 14013 "(peep2_reg_dead_p (3, operands[1]) 14014 || operands_match_p (operands[1], operands[3])) 14015 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 14016 [(set (match_dup 4) (match_dup 0)) 14017 (set (strict_low_part (match_dup 5)) 14018 (match_dup 2))] 14019{ 14020 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 14021 operands[5] = gen_lowpart (QImode, operands[3]); 14022 ix86_expand_clear (operands[3]); 14023}) 14024 14025;; Call instructions. 14026 14027;; The predicates normally associated with named expanders are not properly 14028;; checked for calls. This is a bug in the generic code, but it isn't that 14029;; easy to fix. Ignore it for now and be prepared to fix things up. 14030 14031;; Call subroutine returning no value. 14032 14033(define_expand "call_pop" 14034 [(parallel [(call (match_operand:QI 0 "" "") 14035 (match_operand:SI 1 "" "")) 14036 (set (reg:SI SP_REG) 14037 (plus:SI (reg:SI SP_REG) 14038 (match_operand:SI 3 "" "")))])] 14039 "!TARGET_64BIT" 14040{ 14041 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0); 14042 DONE; 14043}) 14044 14045(define_insn "*call_pop_0" 14046 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" "")) 14047 (match_operand:SI 1 "" "")) 14048 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 14049 (match_operand:SI 2 "immediate_operand" "")))] 14050 "!TARGET_64BIT" 14051{ 14052 if (SIBLING_CALL_P (insn)) 14053 return "jmp\t%P0"; 14054 else 14055 return "call\t%P0"; 14056} 14057 [(set_attr "type" "call")]) 14058 14059(define_insn "*call_pop_1" 14060 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm")) 14061 (match_operand:SI 1 "" "")) 14062 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 14063 (match_operand:SI 2 "immediate_operand" "i")))] 14064 "!TARGET_64BIT" 14065{ 14066 if (constant_call_address_operand (operands[0], Pmode)) 14067 { 14068 if (SIBLING_CALL_P (insn)) 14069 return "jmp\t%P0"; 14070 else 14071 return "call\t%P0"; 14072 } 14073 if (SIBLING_CALL_P (insn)) 14074 return "jmp\t%A0"; 14075 else 14076 return "call\t%A0"; 14077} 14078 [(set_attr "type" "call")]) 14079 14080(define_expand "call" 14081 [(call (match_operand:QI 0 "" "") 14082 (match_operand 1 "" "")) 14083 (use (match_operand 2 "" ""))] 14084 "" 14085{ 14086 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0); 14087 DONE; 14088}) 14089 14090(define_expand "sibcall" 14091 [(call (match_operand:QI 0 "" "") 14092 (match_operand 1 "" "")) 14093 (use (match_operand 2 "" ""))] 14094 "" 14095{ 14096 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1); 14097 DONE; 14098}) 14099 14100(define_insn "*call_0" 14101 [(call (mem:QI (match_operand 0 "constant_call_address_operand" "")) 14102 (match_operand 1 "" ""))] 14103 "" 14104{ 14105 if (SIBLING_CALL_P (insn)) 14106 return "jmp\t%P0"; 14107 else 14108 return "call\t%P0"; 14109} 14110 [(set_attr "type" "call")]) 14111 14112(define_insn "*call_1" 14113 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm")) 14114 (match_operand 1 "" ""))] 14115 "!SIBLING_CALL_P (insn) && !TARGET_64BIT" 14116{ 14117 if (constant_call_address_operand (operands[0], Pmode)) 14118 return "call\t%P0"; 14119 return "call\t%A0"; 14120} 14121 [(set_attr "type" "call")]) 14122 14123(define_insn "*sibcall_1" 14124 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a")) 14125 (match_operand 1 "" ""))] 14126 "SIBLING_CALL_P (insn) && !TARGET_64BIT" 14127{ 14128 if (constant_call_address_operand (operands[0], Pmode)) 14129 return "jmp\t%P0"; 14130 return "jmp\t%A0"; 14131} 14132 [(set_attr "type" "call")]) 14133 14134(define_insn "*call_1_rex64" 14135 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm")) 14136 (match_operand 1 "" ""))] 14137 "!SIBLING_CALL_P (insn) && TARGET_64BIT" 14138{ 14139 if (constant_call_address_operand (operands[0], Pmode)) 14140 return "call\t%P0"; 14141 return "call\t%A0"; 14142} 14143 [(set_attr "type" "call")]) 14144 14145(define_insn "*sibcall_1_rex64" 14146 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" "")) 14147 (match_operand 1 "" ""))] 14148 "SIBLING_CALL_P (insn) && TARGET_64BIT" 14149 "jmp\t%P0" 14150 [(set_attr "type" "call")]) 14151 14152(define_insn "*sibcall_1_rex64_v" 14153 [(call (mem:QI (reg:DI 40)) 14154 (match_operand 0 "" ""))] 14155 "SIBLING_CALL_P (insn) && TARGET_64BIT" 14156 "jmp\t*%%r11" 14157 [(set_attr "type" "call")]) 14158 14159 14160;; Call subroutine, returning value in operand 0 14161 14162(define_expand "call_value_pop" 14163 [(parallel [(set (match_operand 0 "" "") 14164 (call (match_operand:QI 1 "" "") 14165 (match_operand:SI 2 "" ""))) 14166 (set (reg:SI SP_REG) 14167 (plus:SI (reg:SI SP_REG) 14168 (match_operand:SI 4 "" "")))])] 14169 "!TARGET_64BIT" 14170{ 14171 ix86_expand_call (operands[0], operands[1], operands[2], 14172 operands[3], operands[4], 0); 14173 DONE; 14174}) 14175 14176(define_expand "call_value" 14177 [(set (match_operand 0 "" "") 14178 (call (match_operand:QI 1 "" "") 14179 (match_operand:SI 2 "" ""))) 14180 (use (match_operand:SI 3 "" ""))] 14181 ;; Operand 2 not used on the i386. 14182 "" 14183{ 14184 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0); 14185 DONE; 14186}) 14187 14188(define_expand "sibcall_value" 14189 [(set (match_operand 0 "" "") 14190 (call (match_operand:QI 1 "" "") 14191 (match_operand:SI 2 "" ""))) 14192 (use (match_operand:SI 3 "" ""))] 14193 ;; Operand 2 not used on the i386. 14194 "" 14195{ 14196 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1); 14197 DONE; 14198}) 14199 14200;; Call subroutine returning any type. 14201 14202(define_expand "untyped_call" 14203 [(parallel [(call (match_operand 0 "" "") 14204 (const_int 0)) 14205 (match_operand 1 "" "") 14206 (match_operand 2 "" "")])] 14207 "" 14208{ 14209 int i; 14210 14211 /* In order to give reg-stack an easier job in validating two 14212 coprocessor registers as containing a possible return value, 14213 simply pretend the untyped call returns a complex long double 14214 value. */ 14215 14216 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387 14217 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL), 14218 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1), 14219 NULL, 0); 14220 14221 for (i = 0; i < XVECLEN (operands[2], 0); i++) 14222 { 14223 rtx set = XVECEXP (operands[2], 0, i); 14224 emit_move_insn (SET_DEST (set), SET_SRC (set)); 14225 } 14226 14227 /* The optimizer does not know that the call sets the function value 14228 registers we stored in the result block. We avoid problems by 14229 claiming that all hard registers are used and clobbered at this 14230 point. */ 14231 emit_insn (gen_blockage (const0_rtx)); 14232 14233 DONE; 14234}) 14235 14236;; Prologue and epilogue instructions 14237 14238;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 14239;; all of memory. This blocks insns from being moved across this point. 14240 14241(define_insn "blockage" 14242 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)] 14243 "" 14244 "" 14245 [(set_attr "length" "0")]) 14246 14247;; Insn emitted into the body of a function to return from a function. 14248;; This is only done if the function's epilogue is known to be simple. 14249;; See comments for ix86_can_use_return_insn_p in i386.c. 14250 14251(define_expand "return" 14252 [(return)] 14253 "ix86_can_use_return_insn_p ()" 14254{ 14255 if (current_function_pops_args) 14256 { 14257 rtx popc = GEN_INT (current_function_pops_args); 14258 emit_jump_insn (gen_return_pop_internal (popc)); 14259 DONE; 14260 } 14261}) 14262 14263(define_insn "return_internal" 14264 [(return)] 14265 "reload_completed" 14266 "ret" 14267 [(set_attr "length" "1") 14268 (set_attr "length_immediate" "0") 14269 (set_attr "modrm" "0")]) 14270 14271;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET 14272;; instruction Athlon and K8 have. 14273 14274(define_insn "return_internal_long" 14275 [(return) 14276 (unspec [(const_int 0)] UNSPEC_REP)] 14277 "reload_completed" 14278 "rep {;} ret" 14279 [(set_attr "length" "1") 14280 (set_attr "length_immediate" "0") 14281 (set_attr "prefix_rep" "1") 14282 (set_attr "modrm" "0")]) 14283 14284(define_insn "return_pop_internal" 14285 [(return) 14286 (use (match_operand:SI 0 "const_int_operand" ""))] 14287 "reload_completed" 14288 "ret\t%0" 14289 [(set_attr "length" "3") 14290 (set_attr "length_immediate" "2") 14291 (set_attr "modrm" "0")]) 14292 14293(define_insn "return_indirect_internal" 14294 [(return) 14295 (use (match_operand:SI 0 "register_operand" "r"))] 14296 "reload_completed" 14297 "jmp\t%A0" 14298 [(set_attr "type" "ibr") 14299 (set_attr "length_immediate" "0")]) 14300 14301(define_insn "nop" 14302 [(const_int 0)] 14303 "" 14304 "nop" 14305 [(set_attr "length" "1") 14306 (set_attr "length_immediate" "0") 14307 (set_attr "modrm" "0")]) 14308 14309;; Align to 16-byte boundary, max skip in op0. Used to avoid 14310;; branch prediction penalty for the third jump in a 16-byte 14311;; block on K8. 14312 14313(define_insn "align" 14314 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)] 14315 "" 14316{ 14317#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN 14318 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0])); 14319#else 14320 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that. 14321 The align insn is used to avoid 3 jump instructions in the row to improve 14322 branch prediction and the benefits hardly outweigh the cost of extra 8 14323 nops on the average inserted by full alignment pseudo operation. */ 14324#endif 14325 return ""; 14326} 14327 [(set_attr "length" "16")]) 14328 14329(define_expand "prologue" 14330 [(const_int 1)] 14331 "" 14332 "ix86_expand_prologue (); DONE;") 14333 14334(define_insn "set_got" 14335 [(set (match_operand:SI 0 "register_operand" "=r") 14336 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 14337 (clobber (reg:CC FLAGS_REG))] 14338 "!TARGET_64BIT" 14339 { return output_set_got (operands[0], NULL_RTX); } 14340 [(set_attr "type" "multi") 14341 (set_attr "length" "12")]) 14342 14343(define_insn "set_got_labelled" 14344 [(set (match_operand:SI 0 "register_operand" "=r") 14345 (unspec:SI [(label_ref (match_operand 1 "" ""))] 14346 UNSPEC_SET_GOT)) 14347 (clobber (reg:CC FLAGS_REG))] 14348 "!TARGET_64BIT" 14349 { return output_set_got (operands[0], operands[1]); } 14350 [(set_attr "type" "multi") 14351 (set_attr "length" "12")]) 14352 14353(define_insn "set_got_rex64" 14354 [(set (match_operand:DI 0 "register_operand" "=r") 14355 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))] 14356 "TARGET_64BIT" 14357 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0" 14358 [(set_attr "type" "lea") 14359 (set_attr "length" "6")]) 14360 14361(define_expand "epilogue" 14362 [(const_int 1)] 14363 "" 14364 "ix86_expand_epilogue (1); DONE;") 14365 14366(define_expand "sibcall_epilogue" 14367 [(const_int 1)] 14368 "" 14369 "ix86_expand_epilogue (0); DONE;") 14370 14371(define_expand "eh_return" 14372 [(use (match_operand 0 "register_operand" ""))] 14373 "" 14374{ 14375 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0]; 14376 14377 /* Tricky bit: we write the address of the handler to which we will 14378 be returning into someone else's stack frame, one word below the 14379 stack address we wish to restore. */ 14380 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa); 14381 tmp = plus_constant (tmp, -UNITS_PER_WORD); 14382 tmp = gen_rtx_MEM (Pmode, tmp); 14383 emit_move_insn (tmp, ra); 14384 14385 if (Pmode == SImode) 14386 emit_jump_insn (gen_eh_return_si (sa)); 14387 else 14388 emit_jump_insn (gen_eh_return_di (sa)); 14389 emit_barrier (); 14390 DONE; 14391}) 14392 14393(define_insn_and_split "eh_return_si" 14394 [(set (pc) 14395 (unspec [(match_operand:SI 0 "register_operand" "c")] 14396 UNSPEC_EH_RETURN))] 14397 "!TARGET_64BIT" 14398 "#" 14399 "reload_completed" 14400 [(const_int 1)] 14401 "ix86_expand_epilogue (2); DONE;") 14402 14403(define_insn_and_split "eh_return_di" 14404 [(set (pc) 14405 (unspec [(match_operand:DI 0 "register_operand" "c")] 14406 UNSPEC_EH_RETURN))] 14407 "TARGET_64BIT" 14408 "#" 14409 "reload_completed" 14410 [(const_int 1)] 14411 "ix86_expand_epilogue (2); DONE;") 14412 14413(define_insn "leave" 14414 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4))) 14415 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG))) 14416 (clobber (mem:BLK (scratch)))] 14417 "!TARGET_64BIT" 14418 "leave" 14419 [(set_attr "type" "leave")]) 14420 14421(define_insn "leave_rex64" 14422 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8))) 14423 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG))) 14424 (clobber (mem:BLK (scratch)))] 14425 "TARGET_64BIT" 14426 "leave" 14427 [(set_attr "type" "leave")]) 14428 14429(define_expand "ffssi2" 14430 [(parallel 14431 [(set (match_operand:SI 0 "register_operand" "") 14432 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" ""))) 14433 (clobber (match_scratch:SI 2 "")) 14434 (clobber (reg:CC FLAGS_REG))])] 14435 "" 14436 "") 14437 14438(define_insn_and_split "*ffs_cmove" 14439 [(set (match_operand:SI 0 "register_operand" "=r") 14440 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 14441 (clobber (match_scratch:SI 2 "=&r")) 14442 (clobber (reg:CC FLAGS_REG))] 14443 "TARGET_CMOVE" 14444 "#" 14445 "&& reload_completed" 14446 [(set (match_dup 2) (const_int -1)) 14447 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0))) 14448 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 14449 (set (match_dup 0) (if_then_else:SI 14450 (eq (reg:CCZ FLAGS_REG) (const_int 0)) 14451 (match_dup 2) 14452 (match_dup 0))) 14453 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 14454 (clobber (reg:CC FLAGS_REG))])] 14455 "") 14456 14457(define_insn_and_split "*ffs_no_cmove" 14458 [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 14459 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 14460 (clobber (match_scratch:SI 2 "=&q")) 14461 (clobber (reg:CC FLAGS_REG))] 14462 "" 14463 "#" 14464 "reload_completed" 14465 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0))) 14466 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 14467 (set (strict_low_part (match_dup 3)) 14468 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0))) 14469 (parallel [(set (match_dup 2) (neg:SI (match_dup 2))) 14470 (clobber (reg:CC FLAGS_REG))]) 14471 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2))) 14472 (clobber (reg:CC FLAGS_REG))]) 14473 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 14474 (clobber (reg:CC FLAGS_REG))])] 14475{ 14476 operands[3] = gen_lowpart (QImode, operands[2]); 14477 ix86_expand_clear (operands[2]); 14478}) 14479 14480(define_insn "*ffssi_1" 14481 [(set (reg:CCZ FLAGS_REG) 14482 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm") 14483 (const_int 0))) 14484 (set (match_operand:SI 0 "register_operand" "=r") 14485 (ctz:SI (match_dup 1)))] 14486 "" 14487 "bsf{l}\t{%1, %0|%0, %1}" 14488 [(set_attr "prefix_0f" "1")]) 14489 14490(define_expand "ffsdi2" 14491 [(parallel 14492 [(set (match_operand:DI 0 "register_operand" "") 14493 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" ""))) 14494 (clobber (match_scratch:DI 2 "")) 14495 (clobber (reg:CC FLAGS_REG))])] 14496 "TARGET_64BIT && TARGET_CMOVE" 14497 "") 14498 14499(define_insn_and_split "*ffs_rex64" 14500 [(set (match_operand:DI 0 "register_operand" "=r") 14501 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))) 14502 (clobber (match_scratch:DI 2 "=&r")) 14503 (clobber (reg:CC FLAGS_REG))] 14504 "TARGET_64BIT && TARGET_CMOVE" 14505 "#" 14506 "&& reload_completed" 14507 [(set (match_dup 2) (const_int -1)) 14508 (parallel [(set (reg:CCZ FLAGS_REG) 14509 (compare:CCZ (match_dup 1) (const_int 0))) 14510 (set (match_dup 0) (ctz:DI (match_dup 1)))]) 14511 (set (match_dup 0) (if_then_else:DI 14512 (eq (reg:CCZ FLAGS_REG) (const_int 0)) 14513 (match_dup 2) 14514 (match_dup 0))) 14515 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1))) 14516 (clobber (reg:CC FLAGS_REG))])] 14517 "") 14518 14519(define_insn "*ffsdi_1" 14520 [(set (reg:CCZ FLAGS_REG) 14521 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm") 14522 (const_int 0))) 14523 (set (match_operand:DI 0 "register_operand" "=r") 14524 (ctz:DI (match_dup 1)))] 14525 "TARGET_64BIT" 14526 "bsf{q}\t{%1, %0|%0, %1}" 14527 [(set_attr "prefix_0f" "1")]) 14528 14529(define_insn "ctzsi2" 14530 [(set (match_operand:SI 0 "register_operand" "=r") 14531 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 14532 (clobber (reg:CC FLAGS_REG))] 14533 "" 14534 "bsf{l}\t{%1, %0|%0, %1}" 14535 [(set_attr "prefix_0f" "1")]) 14536 14537(define_insn "ctzdi2" 14538 [(set (match_operand:DI 0 "register_operand" "=r") 14539 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))) 14540 (clobber (reg:CC FLAGS_REG))] 14541 "TARGET_64BIT" 14542 "bsf{q}\t{%1, %0|%0, %1}" 14543 [(set_attr "prefix_0f" "1")]) 14544 14545(define_expand "clzsi2" 14546 [(parallel 14547 [(set (match_operand:SI 0 "register_operand" "") 14548 (minus:SI (const_int 31) 14549 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))) 14550 (clobber (reg:CC FLAGS_REG))]) 14551 (parallel 14552 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31))) 14553 (clobber (reg:CC FLAGS_REG))])] 14554 "" 14555 "") 14556 14557(define_insn "*bsr" 14558 [(set (match_operand:SI 0 "register_operand" "=r") 14559 (minus:SI (const_int 31) 14560 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))) 14561 (clobber (reg:CC FLAGS_REG))] 14562 "" 14563 "bsr{l}\t{%1, %0|%0, %1}" 14564 [(set_attr "prefix_0f" "1")]) 14565 14566(define_expand "clzdi2" 14567 [(parallel 14568 [(set (match_operand:DI 0 "register_operand" "") 14569 (minus:DI (const_int 63) 14570 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))) 14571 (clobber (reg:CC FLAGS_REG))]) 14572 (parallel 14573 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63))) 14574 (clobber (reg:CC FLAGS_REG))])] 14575 "TARGET_64BIT" 14576 "") 14577 14578(define_insn "*bsr_rex64" 14579 [(set (match_operand:DI 0 "register_operand" "=r") 14580 (minus:DI (const_int 63) 14581 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) 14582 (clobber (reg:CC FLAGS_REG))] 14583 "TARGET_64BIT" 14584 "bsr{q}\t{%1, %0|%0, %1}" 14585 [(set_attr "prefix_0f" "1")]) 14586 14587;; Thread-local storage patterns for ELF. 14588;; 14589;; Note that these code sequences must appear exactly as shown 14590;; in order to allow linker relaxation. 14591 14592(define_insn "*tls_global_dynamic_32_gnu" 14593 [(set (match_operand:SI 0 "register_operand" "=a") 14594 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14595 (match_operand:SI 2 "tls_symbolic_operand" "") 14596 (match_operand:SI 3 "call_insn_operand" "")] 14597 UNSPEC_TLS_GD)) 14598 (clobber (match_scratch:SI 4 "=d")) 14599 (clobber (match_scratch:SI 5 "=c")) 14600 (clobber (reg:CC FLAGS_REG))] 14601 "!TARGET_64BIT && TARGET_GNU_TLS" 14602 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3" 14603 [(set_attr "type" "multi") 14604 (set_attr "length" "12")]) 14605 14606(define_insn "*tls_global_dynamic_32_sun" 14607 [(set (match_operand:SI 0 "register_operand" "=a") 14608 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14609 (match_operand:SI 2 "tls_symbolic_operand" "") 14610 (match_operand:SI 3 "call_insn_operand" "")] 14611 UNSPEC_TLS_GD)) 14612 (clobber (match_scratch:SI 4 "=d")) 14613 (clobber (match_scratch:SI 5 "=c")) 14614 (clobber (reg:CC FLAGS_REG))] 14615 "!TARGET_64BIT && TARGET_SUN_TLS" 14616 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]} 14617 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop" 14618 [(set_attr "type" "multi") 14619 (set_attr "length" "14")]) 14620 14621(define_expand "tls_global_dynamic_32" 14622 [(parallel [(set (match_operand:SI 0 "register_operand" "") 14623 (unspec:SI 14624 [(match_dup 2) 14625 (match_operand:SI 1 "tls_symbolic_operand" "") 14626 (match_dup 3)] 14627 UNSPEC_TLS_GD)) 14628 (clobber (match_scratch:SI 4 "")) 14629 (clobber (match_scratch:SI 5 "")) 14630 (clobber (reg:CC FLAGS_REG))])] 14631 "" 14632{ 14633 if (flag_pic) 14634 operands[2] = pic_offset_table_rtx; 14635 else 14636 { 14637 operands[2] = gen_reg_rtx (Pmode); 14638 emit_insn (gen_set_got (operands[2])); 14639 } 14640 if (TARGET_GNU2_TLS) 14641 { 14642 emit_insn (gen_tls_dynamic_gnu2_32 14643 (operands[0], operands[1], operands[2])); 14644 DONE; 14645 } 14646 operands[3] = ix86_tls_get_addr (); 14647}) 14648 14649(define_insn "*tls_global_dynamic_64" 14650 [(set (match_operand:DI 0 "register_operand" "=a") 14651 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" "")) 14652 (match_operand:DI 3 "" ""))) 14653 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 14654 UNSPEC_TLS_GD)] 14655 "TARGET_64BIT" 14656 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2" 14657 [(set_attr "type" "multi") 14658 (set_attr "length" "16")]) 14659 14660(define_expand "tls_global_dynamic_64" 14661 [(parallel [(set (match_operand:DI 0 "register_operand" "") 14662 (call:DI (mem:QI (match_dup 2)) (const_int 0))) 14663 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 14664 UNSPEC_TLS_GD)])] 14665 "" 14666{ 14667 if (TARGET_GNU2_TLS) 14668 { 14669 emit_insn (gen_tls_dynamic_gnu2_64 14670 (operands[0], operands[1])); 14671 DONE; 14672 } 14673 operands[2] = ix86_tls_get_addr (); 14674}) 14675 14676(define_insn "*tls_local_dynamic_base_32_gnu" 14677 [(set (match_operand:SI 0 "register_operand" "=a") 14678 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14679 (match_operand:SI 2 "call_insn_operand" "")] 14680 UNSPEC_TLS_LD_BASE)) 14681 (clobber (match_scratch:SI 3 "=d")) 14682 (clobber (match_scratch:SI 4 "=c")) 14683 (clobber (reg:CC FLAGS_REG))] 14684 "!TARGET_64BIT && TARGET_GNU_TLS" 14685 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2" 14686 [(set_attr "type" "multi") 14687 (set_attr "length" "11")]) 14688 14689(define_insn "*tls_local_dynamic_base_32_sun" 14690 [(set (match_operand:SI 0 "register_operand" "=a") 14691 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14692 (match_operand:SI 2 "call_insn_operand" "")] 14693 UNSPEC_TLS_LD_BASE)) 14694 (clobber (match_scratch:SI 3 "=d")) 14695 (clobber (match_scratch:SI 4 "=c")) 14696 (clobber (reg:CC FLAGS_REG))] 14697 "!TARGET_64BIT && TARGET_SUN_TLS" 14698 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]} 14699 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3" 14700 [(set_attr "type" "multi") 14701 (set_attr "length" "13")]) 14702 14703(define_expand "tls_local_dynamic_base_32" 14704 [(parallel [(set (match_operand:SI 0 "register_operand" "") 14705 (unspec:SI [(match_dup 1) (match_dup 2)] 14706 UNSPEC_TLS_LD_BASE)) 14707 (clobber (match_scratch:SI 3 "")) 14708 (clobber (match_scratch:SI 4 "")) 14709 (clobber (reg:CC FLAGS_REG))])] 14710 "" 14711{ 14712 if (flag_pic) 14713 operands[1] = pic_offset_table_rtx; 14714 else 14715 { 14716 operands[1] = gen_reg_rtx (Pmode); 14717 emit_insn (gen_set_got (operands[1])); 14718 } 14719 if (TARGET_GNU2_TLS) 14720 { 14721 emit_insn (gen_tls_dynamic_gnu2_32 14722 (operands[0], ix86_tls_module_base (), operands[1])); 14723 DONE; 14724 } 14725 operands[2] = ix86_tls_get_addr (); 14726}) 14727 14728(define_insn "*tls_local_dynamic_base_64" 14729 [(set (match_operand:DI 0 "register_operand" "=a") 14730 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" "")) 14731 (match_operand:DI 2 "" ""))) 14732 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)] 14733 "TARGET_64BIT" 14734 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1" 14735 [(set_attr "type" "multi") 14736 (set_attr "length" "12")]) 14737 14738(define_expand "tls_local_dynamic_base_64" 14739 [(parallel [(set (match_operand:DI 0 "register_operand" "") 14740 (call:DI (mem:QI (match_dup 1)) (const_int 0))) 14741 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])] 14742 "" 14743{ 14744 if (TARGET_GNU2_TLS) 14745 { 14746 emit_insn (gen_tls_dynamic_gnu2_64 14747 (operands[0], ix86_tls_module_base ())); 14748 DONE; 14749 } 14750 operands[1] = ix86_tls_get_addr (); 14751}) 14752 14753;; Local dynamic of a single variable is a lose. Show combine how 14754;; to convert that back to global dynamic. 14755 14756(define_insn_and_split "*tls_local_dynamic_32_once" 14757 [(set (match_operand:SI 0 "register_operand" "=a") 14758 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14759 (match_operand:SI 2 "call_insn_operand" "")] 14760 UNSPEC_TLS_LD_BASE) 14761 (const:SI (unspec:SI 14762 [(match_operand:SI 3 "tls_symbolic_operand" "")] 14763 UNSPEC_DTPOFF)))) 14764 (clobber (match_scratch:SI 4 "=d")) 14765 (clobber (match_scratch:SI 5 "=c")) 14766 (clobber (reg:CC FLAGS_REG))] 14767 "" 14768 "#" 14769 "" 14770 [(parallel [(set (match_dup 0) 14771 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)] 14772 UNSPEC_TLS_GD)) 14773 (clobber (match_dup 4)) 14774 (clobber (match_dup 5)) 14775 (clobber (reg:CC FLAGS_REG))])] 14776 "") 14777 14778;; Load and add the thread base pointer from %gs:0. 14779 14780(define_insn "*load_tp_si" 14781 [(set (match_operand:SI 0 "register_operand" "=r") 14782 (unspec:SI [(const_int 0)] UNSPEC_TP))] 14783 "!TARGET_64BIT" 14784 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}" 14785 [(set_attr "type" "imov") 14786 (set_attr "modrm" "0") 14787 (set_attr "length" "7") 14788 (set_attr "memory" "load") 14789 (set_attr "imm_disp" "false")]) 14790 14791(define_insn "*add_tp_si" 14792 [(set (match_operand:SI 0 "register_operand" "=r") 14793 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) 14794 (match_operand:SI 1 "register_operand" "0"))) 14795 (clobber (reg:CC FLAGS_REG))] 14796 "!TARGET_64BIT" 14797 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}" 14798 [(set_attr "type" "alu") 14799 (set_attr "modrm" "0") 14800 (set_attr "length" "7") 14801 (set_attr "memory" "load") 14802 (set_attr "imm_disp" "false")]) 14803 14804(define_insn "*load_tp_di" 14805 [(set (match_operand:DI 0 "register_operand" "=r") 14806 (unspec:DI [(const_int 0)] UNSPEC_TP))] 14807 "TARGET_64BIT" 14808 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}" 14809 [(set_attr "type" "imov") 14810 (set_attr "modrm" "0") 14811 (set_attr "length" "7") 14812 (set_attr "memory" "load") 14813 (set_attr "imm_disp" "false")]) 14814 14815(define_insn "*add_tp_di" 14816 [(set (match_operand:DI 0 "register_operand" "=r") 14817 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP) 14818 (match_operand:DI 1 "register_operand" "0"))) 14819 (clobber (reg:CC FLAGS_REG))] 14820 "TARGET_64BIT" 14821 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}" 14822 [(set_attr "type" "alu") 14823 (set_attr "modrm" "0") 14824 (set_attr "length" "7") 14825 (set_attr "memory" "load") 14826 (set_attr "imm_disp" "false")]) 14827 14828;; GNU2 TLS patterns can be split. 14829 14830(define_expand "tls_dynamic_gnu2_32" 14831 [(set (match_dup 3) 14832 (plus:SI (match_operand:SI 2 "register_operand" "") 14833 (const:SI 14834 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")] 14835 UNSPEC_TLSDESC)))) 14836 (parallel 14837 [(set (match_operand:SI 0 "register_operand" "") 14838 (unspec:SI [(match_dup 1) (match_dup 3) 14839 (match_dup 2) (reg:SI SP_REG)] 14840 UNSPEC_TLSDESC)) 14841 (clobber (reg:CC FLAGS_REG))])] 14842 "!TARGET_64BIT && TARGET_GNU2_TLS" 14843{ 14844 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); 14845 ix86_tls_descriptor_calls_expanded_in_cfun = true; 14846}) 14847 14848(define_insn "*tls_dynamic_lea_32" 14849 [(set (match_operand:SI 0 "register_operand" "=r") 14850 (plus:SI (match_operand:SI 1 "register_operand" "b") 14851 (const:SI 14852 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")] 14853 UNSPEC_TLSDESC))))] 14854 "!TARGET_64BIT && TARGET_GNU2_TLS" 14855 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}" 14856 [(set_attr "type" "lea") 14857 (set_attr "mode" "SI") 14858 (set_attr "length" "6") 14859 (set_attr "length_address" "4")]) 14860 14861(define_insn "*tls_dynamic_call_32" 14862 [(set (match_operand:SI 0 "register_operand" "=a") 14863 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "") 14864 (match_operand:SI 2 "register_operand" "0") 14865 ;; we have to make sure %ebx still points to the GOT 14866 (match_operand:SI 3 "register_operand" "b") 14867 (reg:SI SP_REG)] 14868 UNSPEC_TLSDESC)) 14869 (clobber (reg:CC FLAGS_REG))] 14870 "!TARGET_64BIT && TARGET_GNU2_TLS" 14871 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}" 14872 [(set_attr "type" "call") 14873 (set_attr "length" "2") 14874 (set_attr "length_address" "0")]) 14875 14876(define_insn_and_split "*tls_dynamic_gnu2_combine_32" 14877 [(set (match_operand:SI 0 "register_operand" "=&a") 14878 (plus:SI 14879 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "") 14880 (match_operand:SI 4 "" "") 14881 (match_operand:SI 2 "register_operand" "b") 14882 (reg:SI SP_REG)] 14883 UNSPEC_TLSDESC) 14884 (const:SI (unspec:SI 14885 [(match_operand:SI 1 "tls_symbolic_operand" "")] 14886 UNSPEC_DTPOFF)))) 14887 (clobber (reg:CC FLAGS_REG))] 14888 "!TARGET_64BIT && TARGET_GNU2_TLS" 14889 "#" 14890 "" 14891 [(set (match_dup 0) (match_dup 5))] 14892{ 14893 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); 14894 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2])); 14895}) 14896 14897(define_expand "tls_dynamic_gnu2_64" 14898 [(set (match_dup 2) 14899 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 14900 UNSPEC_TLSDESC)) 14901 (parallel 14902 [(set (match_operand:DI 0 "register_operand" "") 14903 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)] 14904 UNSPEC_TLSDESC)) 14905 (clobber (reg:CC FLAGS_REG))])] 14906 "TARGET_64BIT && TARGET_GNU2_TLS" 14907{ 14908 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); 14909 ix86_tls_descriptor_calls_expanded_in_cfun = true; 14910}) 14911 14912(define_insn "*tls_dynamic_lea_64" 14913 [(set (match_operand:DI 0 "register_operand" "=r") 14914 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")] 14915 UNSPEC_TLSDESC))] 14916 "TARGET_64BIT && TARGET_GNU2_TLS" 14917 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}" 14918 [(set_attr "type" "lea") 14919 (set_attr "mode" "DI") 14920 (set_attr "length" "7") 14921 (set_attr "length_address" "4")]) 14922 14923(define_insn "*tls_dynamic_call_64" 14924 [(set (match_operand:DI 0 "register_operand" "=a") 14925 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "") 14926 (match_operand:DI 2 "register_operand" "0") 14927 (reg:DI SP_REG)] 14928 UNSPEC_TLSDESC)) 14929 (clobber (reg:CC FLAGS_REG))] 14930 "TARGET_64BIT && TARGET_GNU2_TLS" 14931 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}" 14932 [(set_attr "type" "call") 14933 (set_attr "length" "2") 14934 (set_attr "length_address" "0")]) 14935 14936(define_insn_and_split "*tls_dynamic_gnu2_combine_64" 14937 [(set (match_operand:DI 0 "register_operand" "=&a") 14938 (plus:DI 14939 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "") 14940 (match_operand:DI 3 "" "") 14941 (reg:DI SP_REG)] 14942 UNSPEC_TLSDESC) 14943 (const:DI (unspec:DI 14944 [(match_operand:DI 1 "tls_symbolic_operand" "")] 14945 UNSPEC_DTPOFF)))) 14946 (clobber (reg:CC FLAGS_REG))] 14947 "TARGET_64BIT && TARGET_GNU2_TLS" 14948 "#" 14949 "" 14950 [(set (match_dup 0) (match_dup 4))] 14951{ 14952 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode); 14953 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1])); 14954}) 14955 14956;; 14957 14958;; These patterns match the binary 387 instructions for addM3, subM3, 14959;; mulM3 and divM3. There are three patterns for each of DFmode and 14960;; SFmode. The first is the normal insn, the second the same insn but 14961;; with one operand a conversion, and the third the same insn but with 14962;; the other operand a conversion. The conversion may be SFmode or 14963;; SImode if the target mode DFmode, but only SImode if the target mode 14964;; is SFmode. 14965 14966;; Gcc is slightly more smart about handling normal two address instructions 14967;; so use special patterns for add and mull. 14968 14969(define_insn "*fop_sf_comm_mixed" 14970 [(set (match_operand:SF 0 "register_operand" "=f,x") 14971 (match_operator:SF 3 "binary_fp_operator" 14972 [(match_operand:SF 1 "nonimmediate_operand" "%0,0") 14973 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))] 14974 "TARGET_MIX_SSE_I387 14975 && COMMUTATIVE_ARITH_P (operands[3]) 14976 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 14977 "* return output_387_binary_op (insn, operands);" 14978 [(set (attr "type") 14979 (if_then_else (eq_attr "alternative" "1") 14980 (if_then_else (match_operand:SF 3 "mult_operator" "") 14981 (const_string "ssemul") 14982 (const_string "sseadd")) 14983 (if_then_else (match_operand:SF 3 "mult_operator" "") 14984 (const_string "fmul") 14985 (const_string "fop")))) 14986 (set_attr "mode" "SF")]) 14987 14988(define_insn "*fop_sf_comm_sse" 14989 [(set (match_operand:SF 0 "register_operand" "=x") 14990 (match_operator:SF 3 "binary_fp_operator" 14991 [(match_operand:SF 1 "nonimmediate_operand" "%0") 14992 (match_operand:SF 2 "nonimmediate_operand" "xm")]))] 14993 "TARGET_SSE_MATH 14994 && COMMUTATIVE_ARITH_P (operands[3]) 14995 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 14996 "* return output_387_binary_op (insn, operands);" 14997 [(set (attr "type") 14998 (if_then_else (match_operand:SF 3 "mult_operator" "") 14999 (const_string "ssemul") 15000 (const_string "sseadd"))) 15001 (set_attr "mode" "SF")]) 15002 15003(define_insn "*fop_sf_comm_i387" 15004 [(set (match_operand:SF 0 "register_operand" "=f") 15005 (match_operator:SF 3 "binary_fp_operator" 15006 [(match_operand:SF 1 "nonimmediate_operand" "%0") 15007 (match_operand:SF 2 "nonimmediate_operand" "fm")]))] 15008 "TARGET_80387 15009 && COMMUTATIVE_ARITH_P (operands[3]) 15010 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15011 "* return output_387_binary_op (insn, operands);" 15012 [(set (attr "type") 15013 (if_then_else (match_operand:SF 3 "mult_operator" "") 15014 (const_string "fmul") 15015 (const_string "fop"))) 15016 (set_attr "mode" "SF")]) 15017 15018(define_insn "*fop_sf_1_mixed" 15019 [(set (match_operand:SF 0 "register_operand" "=f,f,x") 15020 (match_operator:SF 3 "binary_fp_operator" 15021 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0") 15022 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))] 15023 "TARGET_MIX_SSE_I387 15024 && !COMMUTATIVE_ARITH_P (operands[3]) 15025 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15026 "* return output_387_binary_op (insn, operands);" 15027 [(set (attr "type") 15028 (cond [(and (eq_attr "alternative" "2") 15029 (match_operand:SF 3 "mult_operator" "")) 15030 (const_string "ssemul") 15031 (and (eq_attr "alternative" "2") 15032 (match_operand:SF 3 "div_operator" "")) 15033 (const_string "ssediv") 15034 (eq_attr "alternative" "2") 15035 (const_string "sseadd") 15036 (match_operand:SF 3 "mult_operator" "") 15037 (const_string "fmul") 15038 (match_operand:SF 3 "div_operator" "") 15039 (const_string "fdiv") 15040 ] 15041 (const_string "fop"))) 15042 (set_attr "mode" "SF")]) 15043 15044(define_insn "*fop_sf_1_sse" 15045 [(set (match_operand:SF 0 "register_operand" "=x") 15046 (match_operator:SF 3 "binary_fp_operator" 15047 [(match_operand:SF 1 "register_operand" "0") 15048 (match_operand:SF 2 "nonimmediate_operand" "xm")]))] 15049 "TARGET_SSE_MATH 15050 && !COMMUTATIVE_ARITH_P (operands[3])" 15051 "* return output_387_binary_op (insn, operands);" 15052 [(set (attr "type") 15053 (cond [(match_operand:SF 3 "mult_operator" "") 15054 (const_string "ssemul") 15055 (match_operand:SF 3 "div_operator" "") 15056 (const_string "ssediv") 15057 ] 15058 (const_string "sseadd"))) 15059 (set_attr "mode" "SF")]) 15060 15061;; This pattern is not fully shadowed by the pattern above. 15062(define_insn "*fop_sf_1_i387" 15063 [(set (match_operand:SF 0 "register_operand" "=f,f") 15064 (match_operator:SF 3 "binary_fp_operator" 15065 [(match_operand:SF 1 "nonimmediate_operand" "0,fm") 15066 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))] 15067 "TARGET_80387 && !TARGET_SSE_MATH 15068 && !COMMUTATIVE_ARITH_P (operands[3]) 15069 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15070 "* return output_387_binary_op (insn, operands);" 15071 [(set (attr "type") 15072 (cond [(match_operand:SF 3 "mult_operator" "") 15073 (const_string "fmul") 15074 (match_operand:SF 3 "div_operator" "") 15075 (const_string "fdiv") 15076 ] 15077 (const_string "fop"))) 15078 (set_attr "mode" "SF")]) 15079 15080;; ??? Add SSE splitters for these! 15081(define_insn "*fop_sf_2<mode>_i387" 15082 [(set (match_operand:SF 0 "register_operand" "=f,f") 15083 (match_operator:SF 3 "binary_fp_operator" 15084 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r")) 15085 (match_operand:SF 2 "register_operand" "0,0")]))] 15086 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH" 15087 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15088 [(set (attr "type") 15089 (cond [(match_operand:SF 3 "mult_operator" "") 15090 (const_string "fmul") 15091 (match_operand:SF 3 "div_operator" "") 15092 (const_string "fdiv") 15093 ] 15094 (const_string "fop"))) 15095 (set_attr "fp_int_src" "true") 15096 (set_attr "mode" "<MODE>")]) 15097 15098(define_insn "*fop_sf_3<mode>_i387" 15099 [(set (match_operand:SF 0 "register_operand" "=f,f") 15100 (match_operator:SF 3 "binary_fp_operator" 15101 [(match_operand:SF 1 "register_operand" "0,0") 15102 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))] 15103 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH" 15104 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15105 [(set (attr "type") 15106 (cond [(match_operand:SF 3 "mult_operator" "") 15107 (const_string "fmul") 15108 (match_operand:SF 3 "div_operator" "") 15109 (const_string "fdiv") 15110 ] 15111 (const_string "fop"))) 15112 (set_attr "fp_int_src" "true") 15113 (set_attr "mode" "<MODE>")]) 15114 15115(define_insn "*fop_df_comm_mixed" 15116 [(set (match_operand:DF 0 "register_operand" "=f,Y") 15117 (match_operator:DF 3 "binary_fp_operator" 15118 [(match_operand:DF 1 "nonimmediate_operand" "%0,0") 15119 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))] 15120 "TARGET_SSE2 && TARGET_MIX_SSE_I387 15121 && COMMUTATIVE_ARITH_P (operands[3]) 15122 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15123 "* return output_387_binary_op (insn, operands);" 15124 [(set (attr "type") 15125 (if_then_else (eq_attr "alternative" "1") 15126 (if_then_else (match_operand:DF 3 "mult_operator" "") 15127 (const_string "ssemul") 15128 (const_string "sseadd")) 15129 (if_then_else (match_operand:DF 3 "mult_operator" "") 15130 (const_string "fmul") 15131 (const_string "fop")))) 15132 (set_attr "mode" "DF")]) 15133 15134(define_insn "*fop_df_comm_sse" 15135 [(set (match_operand:DF 0 "register_operand" "=Y") 15136 (match_operator:DF 3 "binary_fp_operator" 15137 [(match_operand:DF 1 "nonimmediate_operand" "%0") 15138 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))] 15139 "TARGET_SSE2 && TARGET_SSE_MATH 15140 && COMMUTATIVE_ARITH_P (operands[3]) 15141 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15142 "* return output_387_binary_op (insn, operands);" 15143 [(set (attr "type") 15144 (if_then_else (match_operand:DF 3 "mult_operator" "") 15145 (const_string "ssemul") 15146 (const_string "sseadd"))) 15147 (set_attr "mode" "DF")]) 15148 15149(define_insn "*fop_df_comm_i387" 15150 [(set (match_operand:DF 0 "register_operand" "=f") 15151 (match_operator:DF 3 "binary_fp_operator" 15152 [(match_operand:DF 1 "nonimmediate_operand" "%0") 15153 (match_operand:DF 2 "nonimmediate_operand" "fm")]))] 15154 "TARGET_80387 15155 && COMMUTATIVE_ARITH_P (operands[3]) 15156 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15157 "* return output_387_binary_op (insn, operands);" 15158 [(set (attr "type") 15159 (if_then_else (match_operand:DF 3 "mult_operator" "") 15160 (const_string "fmul") 15161 (const_string "fop"))) 15162 (set_attr "mode" "DF")]) 15163 15164(define_insn "*fop_df_1_mixed" 15165 [(set (match_operand:DF 0 "register_operand" "=f,f,Y") 15166 (match_operator:DF 3 "binary_fp_operator" 15167 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0") 15168 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))] 15169 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387 15170 && !COMMUTATIVE_ARITH_P (operands[3]) 15171 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15172 "* return output_387_binary_op (insn, operands);" 15173 [(set (attr "type") 15174 (cond [(and (eq_attr "alternative" "2") 15175 (match_operand:DF 3 "mult_operator" "")) 15176 (const_string "ssemul") 15177 (and (eq_attr "alternative" "2") 15178 (match_operand:DF 3 "div_operator" "")) 15179 (const_string "ssediv") 15180 (eq_attr "alternative" "2") 15181 (const_string "sseadd") 15182 (match_operand:DF 3 "mult_operator" "") 15183 (const_string "fmul") 15184 (match_operand:DF 3 "div_operator" "") 15185 (const_string "fdiv") 15186 ] 15187 (const_string "fop"))) 15188 (set_attr "mode" "DF")]) 15189 15190(define_insn "*fop_df_1_sse" 15191 [(set (match_operand:DF 0 "register_operand" "=Y") 15192 (match_operator:DF 3 "binary_fp_operator" 15193 [(match_operand:DF 1 "register_operand" "0") 15194 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))] 15195 "TARGET_SSE2 && TARGET_SSE_MATH 15196 && !COMMUTATIVE_ARITH_P (operands[3])" 15197 "* return output_387_binary_op (insn, operands);" 15198 [(set_attr "mode" "DF") 15199 (set (attr "type") 15200 (cond [(match_operand:DF 3 "mult_operator" "") 15201 (const_string "ssemul") 15202 (match_operand:DF 3 "div_operator" "") 15203 (const_string "ssediv") 15204 ] 15205 (const_string "sseadd")))]) 15206 15207;; This pattern is not fully shadowed by the pattern above. 15208(define_insn "*fop_df_1_i387" 15209 [(set (match_operand:DF 0 "register_operand" "=f,f") 15210 (match_operator:DF 3 "binary_fp_operator" 15211 [(match_operand:DF 1 "nonimmediate_operand" "0,fm") 15212 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))] 15213 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH) 15214 && !COMMUTATIVE_ARITH_P (operands[3]) 15215 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15216 "* return output_387_binary_op (insn, operands);" 15217 [(set (attr "type") 15218 (cond [(match_operand:DF 3 "mult_operator" "") 15219 (const_string "fmul") 15220 (match_operand:DF 3 "div_operator" "") 15221 (const_string "fdiv") 15222 ] 15223 (const_string "fop"))) 15224 (set_attr "mode" "DF")]) 15225 15226;; ??? Add SSE splitters for these! 15227(define_insn "*fop_df_2<mode>_i387" 15228 [(set (match_operand:DF 0 "register_operand" "=f,f") 15229 (match_operator:DF 3 "binary_fp_operator" 15230 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r")) 15231 (match_operand:DF 2 "register_operand" "0,0")]))] 15232 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 15233 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15234 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15235 [(set (attr "type") 15236 (cond [(match_operand:DF 3 "mult_operator" "") 15237 (const_string "fmul") 15238 (match_operand:DF 3 "div_operator" "") 15239 (const_string "fdiv") 15240 ] 15241 (const_string "fop"))) 15242 (set_attr "fp_int_src" "true") 15243 (set_attr "mode" "<MODE>")]) 15244 15245(define_insn "*fop_df_3<mode>_i387" 15246 [(set (match_operand:DF 0 "register_operand" "=f,f") 15247 (match_operator:DF 3 "binary_fp_operator" 15248 [(match_operand:DF 1 "register_operand" "0,0") 15249 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))] 15250 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP 15251 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15252 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15253 [(set (attr "type") 15254 (cond [(match_operand:DF 3 "mult_operator" "") 15255 (const_string "fmul") 15256 (match_operand:DF 3 "div_operator" "") 15257 (const_string "fdiv") 15258 ] 15259 (const_string "fop"))) 15260 (set_attr "fp_int_src" "true") 15261 (set_attr "mode" "<MODE>")]) 15262 15263(define_insn "*fop_df_4_i387" 15264 [(set (match_operand:DF 0 "register_operand" "=f,f") 15265 (match_operator:DF 3 "binary_fp_operator" 15266 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0")) 15267 (match_operand:DF 2 "register_operand" "0,f")]))] 15268 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH) 15269 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" 15270 "* return output_387_binary_op (insn, operands);" 15271 [(set (attr "type") 15272 (cond [(match_operand:DF 3 "mult_operator" "") 15273 (const_string "fmul") 15274 (match_operand:DF 3 "div_operator" "") 15275 (const_string "fdiv") 15276 ] 15277 (const_string "fop"))) 15278 (set_attr "mode" "SF")]) 15279 15280(define_insn "*fop_df_5_i387" 15281 [(set (match_operand:DF 0 "register_operand" "=f,f") 15282 (match_operator:DF 3 "binary_fp_operator" 15283 [(match_operand:DF 1 "register_operand" "0,f") 15284 (float_extend:DF 15285 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15286 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15287 "* return output_387_binary_op (insn, operands);" 15288 [(set (attr "type") 15289 (cond [(match_operand:DF 3 "mult_operator" "") 15290 (const_string "fmul") 15291 (match_operand:DF 3 "div_operator" "") 15292 (const_string "fdiv") 15293 ] 15294 (const_string "fop"))) 15295 (set_attr "mode" "SF")]) 15296 15297(define_insn "*fop_df_6_i387" 15298 [(set (match_operand:DF 0 "register_operand" "=f,f") 15299 (match_operator:DF 3 "binary_fp_operator" 15300 [(float_extend:DF 15301 (match_operand:SF 1 "register_operand" "0,f")) 15302 (float_extend:DF 15303 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15304 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 15305 "* return output_387_binary_op (insn, operands);" 15306 [(set (attr "type") 15307 (cond [(match_operand:DF 3 "mult_operator" "") 15308 (const_string "fmul") 15309 (match_operand:DF 3 "div_operator" "") 15310 (const_string "fdiv") 15311 ] 15312 (const_string "fop"))) 15313 (set_attr "mode" "SF")]) 15314 15315(define_insn "*fop_xf_comm_i387" 15316 [(set (match_operand:XF 0 "register_operand" "=f") 15317 (match_operator:XF 3 "binary_fp_operator" 15318 [(match_operand:XF 1 "register_operand" "%0") 15319 (match_operand:XF 2 "register_operand" "f")]))] 15320 "TARGET_80387 15321 && COMMUTATIVE_ARITH_P (operands[3])" 15322 "* return output_387_binary_op (insn, operands);" 15323 [(set (attr "type") 15324 (if_then_else (match_operand:XF 3 "mult_operator" "") 15325 (const_string "fmul") 15326 (const_string "fop"))) 15327 (set_attr "mode" "XF")]) 15328 15329(define_insn "*fop_xf_1_i387" 15330 [(set (match_operand:XF 0 "register_operand" "=f,f") 15331 (match_operator:XF 3 "binary_fp_operator" 15332 [(match_operand:XF 1 "register_operand" "0,f") 15333 (match_operand:XF 2 "register_operand" "f,0")]))] 15334 "TARGET_80387 15335 && !COMMUTATIVE_ARITH_P (operands[3])" 15336 "* return output_387_binary_op (insn, operands);" 15337 [(set (attr "type") 15338 (cond [(match_operand:XF 3 "mult_operator" "") 15339 (const_string "fmul") 15340 (match_operand:XF 3 "div_operator" "") 15341 (const_string "fdiv") 15342 ] 15343 (const_string "fop"))) 15344 (set_attr "mode" "XF")]) 15345 15346(define_insn "*fop_xf_2<mode>_i387" 15347 [(set (match_operand:XF 0 "register_operand" "=f,f") 15348 (match_operator:XF 3 "binary_fp_operator" 15349 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r")) 15350 (match_operand:XF 2 "register_operand" "0,0")]))] 15351 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP" 15352 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15353 [(set (attr "type") 15354 (cond [(match_operand:XF 3 "mult_operator" "") 15355 (const_string "fmul") 15356 (match_operand:XF 3 "div_operator" "") 15357 (const_string "fdiv") 15358 ] 15359 (const_string "fop"))) 15360 (set_attr "fp_int_src" "true") 15361 (set_attr "mode" "<MODE>")]) 15362 15363(define_insn "*fop_xf_3<mode>_i387" 15364 [(set (match_operand:XF 0 "register_operand" "=f,f") 15365 (match_operator:XF 3 "binary_fp_operator" 15366 [(match_operand:XF 1 "register_operand" "0,0") 15367 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))] 15368 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP" 15369 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);" 15370 [(set (attr "type") 15371 (cond [(match_operand:XF 3 "mult_operator" "") 15372 (const_string "fmul") 15373 (match_operand:XF 3 "div_operator" "") 15374 (const_string "fdiv") 15375 ] 15376 (const_string "fop"))) 15377 (set_attr "fp_int_src" "true") 15378 (set_attr "mode" "<MODE>")]) 15379 15380(define_insn "*fop_xf_4_i387" 15381 [(set (match_operand:XF 0 "register_operand" "=f,f") 15382 (match_operator:XF 3 "binary_fp_operator" 15383 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0")) 15384 (match_operand:XF 2 "register_operand" "0,f")]))] 15385 "TARGET_80387" 15386 "* return output_387_binary_op (insn, operands);" 15387 [(set (attr "type") 15388 (cond [(match_operand:XF 3 "mult_operator" "") 15389 (const_string "fmul") 15390 (match_operand:XF 3 "div_operator" "") 15391 (const_string "fdiv") 15392 ] 15393 (const_string "fop"))) 15394 (set_attr "mode" "SF")]) 15395 15396(define_insn "*fop_xf_5_i387" 15397 [(set (match_operand:XF 0 "register_operand" "=f,f") 15398 (match_operator:XF 3 "binary_fp_operator" 15399 [(match_operand:XF 1 "register_operand" "0,f") 15400 (float_extend:XF 15401 (match_operand 2 "nonimmediate_operand" "fm,0"))]))] 15402 "TARGET_80387" 15403 "* return output_387_binary_op (insn, operands);" 15404 [(set (attr "type") 15405 (cond [(match_operand:XF 3 "mult_operator" "") 15406 (const_string "fmul") 15407 (match_operand:XF 3 "div_operator" "") 15408 (const_string "fdiv") 15409 ] 15410 (const_string "fop"))) 15411 (set_attr "mode" "SF")]) 15412 15413(define_insn "*fop_xf_6_i387" 15414 [(set (match_operand:XF 0 "register_operand" "=f,f") 15415 (match_operator:XF 3 "binary_fp_operator" 15416 [(float_extend:XF 15417 (match_operand 1 "register_operand" "0,f")) 15418 (float_extend:XF 15419 (match_operand 2 "nonimmediate_operand" "fm,0"))]))] 15420 "TARGET_80387" 15421 "* return output_387_binary_op (insn, operands);" 15422 [(set (attr "type") 15423 (cond [(match_operand:XF 3 "mult_operator" "") 15424 (const_string "fmul") 15425 (match_operand:XF 3 "div_operator" "") 15426 (const_string "fdiv") 15427 ] 15428 (const_string "fop"))) 15429 (set_attr "mode" "SF")]) 15430 15431(define_split 15432 [(set (match_operand 0 "register_operand" "") 15433 (match_operator 3 "binary_fp_operator" 15434 [(float (match_operand:X87MODEI12 1 "register_operand" "")) 15435 (match_operand 2 "register_operand" "")]))] 15436 "TARGET_80387 && reload_completed 15437 && FLOAT_MODE_P (GET_MODE (operands[0]))" 15438 [(const_int 0)] 15439{ 15440 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]); 15441 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); 15442 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 15443 gen_rtx_fmt_ee (GET_CODE (operands[3]), 15444 GET_MODE (operands[3]), 15445 operands[4], 15446 operands[2]))); 15447 ix86_free_from_memory (GET_MODE (operands[1])); 15448 DONE; 15449}) 15450 15451(define_split 15452 [(set (match_operand 0 "register_operand" "") 15453 (match_operator 3 "binary_fp_operator" 15454 [(match_operand 1 "register_operand" "") 15455 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))] 15456 "TARGET_80387 && reload_completed 15457 && FLOAT_MODE_P (GET_MODE (operands[0]))" 15458 [(const_int 0)] 15459{ 15460 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]); 15461 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]); 15462 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 15463 gen_rtx_fmt_ee (GET_CODE (operands[3]), 15464 GET_MODE (operands[3]), 15465 operands[1], 15466 operands[4]))); 15467 ix86_free_from_memory (GET_MODE (operands[2])); 15468 DONE; 15469}) 15470 15471;; FPU special functions. 15472 15473(define_expand "sqrtsf2" 15474 [(set (match_operand:SF 0 "register_operand" "") 15475 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))] 15476 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH" 15477{ 15478 if (!TARGET_SSE_MATH) 15479 operands[1] = force_reg (SFmode, operands[1]); 15480}) 15481 15482(define_insn "*sqrtsf2_mixed" 15483 [(set (match_operand:SF 0 "register_operand" "=f,x") 15484 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))] 15485 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387" 15486 "@ 15487 fsqrt 15488 sqrtss\t{%1, %0|%0, %1}" 15489 [(set_attr "type" "fpspc,sse") 15490 (set_attr "mode" "SF,SF") 15491 (set_attr "athlon_decode" "direct,*")]) 15492 15493(define_insn "*sqrtsf2_sse" 15494 [(set (match_operand:SF 0 "register_operand" "=x") 15495 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))] 15496 "TARGET_SSE_MATH" 15497 "sqrtss\t{%1, %0|%0, %1}" 15498 [(set_attr "type" "sse") 15499 (set_attr "mode" "SF") 15500 (set_attr "athlon_decode" "*")]) 15501 15502(define_insn "*sqrtsf2_i387" 15503 [(set (match_operand:SF 0 "register_operand" "=f") 15504 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))] 15505 "TARGET_USE_FANCY_MATH_387" 15506 "fsqrt" 15507 [(set_attr "type" "fpspc") 15508 (set_attr "mode" "SF") 15509 (set_attr "athlon_decode" "direct")]) 15510 15511(define_expand "sqrtdf2" 15512 [(set (match_operand:DF 0 "register_operand" "") 15513 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))] 15514 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 15515{ 15516 if (!(TARGET_SSE2 && TARGET_SSE_MATH)) 15517 operands[1] = force_reg (DFmode, operands[1]); 15518}) 15519 15520(define_insn "*sqrtdf2_mixed" 15521 [(set (match_operand:DF 0 "register_operand" "=f,Y") 15522 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))] 15523 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387" 15524 "@ 15525 fsqrt 15526 sqrtsd\t{%1, %0|%0, %1}" 15527 [(set_attr "type" "fpspc,sse") 15528 (set_attr "mode" "DF,DF") 15529 (set_attr "athlon_decode" "direct,*")]) 15530 15531(define_insn "*sqrtdf2_sse" 15532 [(set (match_operand:DF 0 "register_operand" "=Y") 15533 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))] 15534 "TARGET_SSE2 && TARGET_SSE_MATH" 15535 "sqrtsd\t{%1, %0|%0, %1}" 15536 [(set_attr "type" "sse") 15537 (set_attr "mode" "DF") 15538 (set_attr "athlon_decode" "*")]) 15539 15540(define_insn "*sqrtdf2_i387" 15541 [(set (match_operand:DF 0 "register_operand" "=f") 15542 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))] 15543 "TARGET_USE_FANCY_MATH_387" 15544 "fsqrt" 15545 [(set_attr "type" "fpspc") 15546 (set_attr "mode" "DF") 15547 (set_attr "athlon_decode" "direct")]) 15548 15549(define_insn "*sqrtextendsfdf2_i387" 15550 [(set (match_operand:DF 0 "register_operand" "=f") 15551 (sqrt:DF (float_extend:DF 15552 (match_operand:SF 1 "register_operand" "0"))))] 15553 "TARGET_USE_FANCY_MATH_387 15554 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)" 15555 "fsqrt" 15556 [(set_attr "type" "fpspc") 15557 (set_attr "mode" "DF") 15558 (set_attr "athlon_decode" "direct")]) 15559 15560(define_insn "sqrtxf2" 15561 [(set (match_operand:XF 0 "register_operand" "=f") 15562 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] 15563 "TARGET_USE_FANCY_MATH_387" 15564 "fsqrt" 15565 [(set_attr "type" "fpspc") 15566 (set_attr "mode" "XF") 15567 (set_attr "athlon_decode" "direct")]) 15568 15569(define_insn "*sqrtextendsfxf2_i387" 15570 [(set (match_operand:XF 0 "register_operand" "=f") 15571 (sqrt:XF (float_extend:XF 15572 (match_operand:SF 1 "register_operand" "0"))))] 15573 "TARGET_USE_FANCY_MATH_387" 15574 "fsqrt" 15575 [(set_attr "type" "fpspc") 15576 (set_attr "mode" "XF") 15577 (set_attr "athlon_decode" "direct")]) 15578 15579(define_insn "*sqrtextenddfxf2_i387" 15580 [(set (match_operand:XF 0 "register_operand" "=f") 15581 (sqrt:XF (float_extend:XF 15582 (match_operand:DF 1 "register_operand" "0"))))] 15583 "TARGET_USE_FANCY_MATH_387" 15584 "fsqrt" 15585 [(set_attr "type" "fpspc") 15586 (set_attr "mode" "XF") 15587 (set_attr "athlon_decode" "direct")]) 15588 15589(define_insn "fpremxf4" 15590 [(set (match_operand:XF 0 "register_operand" "=f") 15591 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15592 (match_operand:XF 3 "register_operand" "1")] 15593 UNSPEC_FPREM_F)) 15594 (set (match_operand:XF 1 "register_operand" "=u") 15595 (unspec:XF [(match_dup 2) (match_dup 3)] 15596 UNSPEC_FPREM_U)) 15597 (set (reg:CCFP FPSR_REG) 15598 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))] 15599 "TARGET_USE_FANCY_MATH_387 15600 && flag_unsafe_math_optimizations" 15601 "fprem" 15602 [(set_attr "type" "fpspc") 15603 (set_attr "mode" "XF")]) 15604 15605(define_expand "fmodsf3" 15606 [(use (match_operand:SF 0 "register_operand" "")) 15607 (use (match_operand:SF 1 "register_operand" "")) 15608 (use (match_operand:SF 2 "register_operand" ""))] 15609 "TARGET_USE_FANCY_MATH_387 15610 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15611 && flag_unsafe_math_optimizations" 15612{ 15613 rtx label = gen_label_rtx (); 15614 15615 rtx op1 = gen_reg_rtx (XFmode); 15616 rtx op2 = gen_reg_rtx (XFmode); 15617 15618 emit_insn(gen_extendsfxf2 (op1, operands[1])); 15619 emit_insn(gen_extendsfxf2 (op2, operands[2])); 15620 15621 emit_label (label); 15622 15623 emit_insn (gen_fpremxf4 (op1, op2, op1, op2)); 15624 ix86_emit_fp_unordered_jump (label); 15625 15626 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1)); 15627 DONE; 15628}) 15629 15630(define_expand "fmoddf3" 15631 [(use (match_operand:DF 0 "register_operand" "")) 15632 (use (match_operand:DF 1 "register_operand" "")) 15633 (use (match_operand:DF 2 "register_operand" ""))] 15634 "TARGET_USE_FANCY_MATH_387 15635 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15636 && flag_unsafe_math_optimizations" 15637{ 15638 rtx label = gen_label_rtx (); 15639 15640 rtx op1 = gen_reg_rtx (XFmode); 15641 rtx op2 = gen_reg_rtx (XFmode); 15642 15643 emit_insn (gen_extenddfxf2 (op1, operands[1])); 15644 emit_insn (gen_extenddfxf2 (op2, operands[2])); 15645 15646 emit_label (label); 15647 15648 emit_insn (gen_fpremxf4 (op1, op2, op1, op2)); 15649 ix86_emit_fp_unordered_jump (label); 15650 15651 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1)); 15652 DONE; 15653}) 15654 15655(define_expand "fmodxf3" 15656 [(use (match_operand:XF 0 "register_operand" "")) 15657 (use (match_operand:XF 1 "register_operand" "")) 15658 (use (match_operand:XF 2 "register_operand" ""))] 15659 "TARGET_USE_FANCY_MATH_387 15660 && flag_unsafe_math_optimizations" 15661{ 15662 rtx label = gen_label_rtx (); 15663 15664 emit_label (label); 15665 15666 emit_insn (gen_fpremxf4 (operands[1], operands[2], 15667 operands[1], operands[2])); 15668 ix86_emit_fp_unordered_jump (label); 15669 15670 emit_move_insn (operands[0], operands[1]); 15671 DONE; 15672}) 15673 15674(define_insn "fprem1xf4" 15675 [(set (match_operand:XF 0 "register_operand" "=f") 15676 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15677 (match_operand:XF 3 "register_operand" "1")] 15678 UNSPEC_FPREM1_F)) 15679 (set (match_operand:XF 1 "register_operand" "=u") 15680 (unspec:XF [(match_dup 2) (match_dup 3)] 15681 UNSPEC_FPREM1_U)) 15682 (set (reg:CCFP FPSR_REG) 15683 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))] 15684 "TARGET_USE_FANCY_MATH_387 15685 && flag_unsafe_math_optimizations" 15686 "fprem1" 15687 [(set_attr "type" "fpspc") 15688 (set_attr "mode" "XF")]) 15689 15690(define_expand "dremsf3" 15691 [(use (match_operand:SF 0 "register_operand" "")) 15692 (use (match_operand:SF 1 "register_operand" "")) 15693 (use (match_operand:SF 2 "register_operand" ""))] 15694 "TARGET_USE_FANCY_MATH_387 15695 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15696 && flag_unsafe_math_optimizations" 15697{ 15698 rtx label = gen_label_rtx (); 15699 15700 rtx op1 = gen_reg_rtx (XFmode); 15701 rtx op2 = gen_reg_rtx (XFmode); 15702 15703 emit_insn(gen_extendsfxf2 (op1, operands[1])); 15704 emit_insn(gen_extendsfxf2 (op2, operands[2])); 15705 15706 emit_label (label); 15707 15708 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2)); 15709 ix86_emit_fp_unordered_jump (label); 15710 15711 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1)); 15712 DONE; 15713}) 15714 15715(define_expand "dremdf3" 15716 [(use (match_operand:DF 0 "register_operand" "")) 15717 (use (match_operand:DF 1 "register_operand" "")) 15718 (use (match_operand:DF 2 "register_operand" ""))] 15719 "TARGET_USE_FANCY_MATH_387 15720 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15721 && flag_unsafe_math_optimizations" 15722{ 15723 rtx label = gen_label_rtx (); 15724 15725 rtx op1 = gen_reg_rtx (XFmode); 15726 rtx op2 = gen_reg_rtx (XFmode); 15727 15728 emit_insn (gen_extenddfxf2 (op1, operands[1])); 15729 emit_insn (gen_extenddfxf2 (op2, operands[2])); 15730 15731 emit_label (label); 15732 15733 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2)); 15734 ix86_emit_fp_unordered_jump (label); 15735 15736 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1)); 15737 DONE; 15738}) 15739 15740(define_expand "dremxf3" 15741 [(use (match_operand:XF 0 "register_operand" "")) 15742 (use (match_operand:XF 1 "register_operand" "")) 15743 (use (match_operand:XF 2 "register_operand" ""))] 15744 "TARGET_USE_FANCY_MATH_387 15745 && flag_unsafe_math_optimizations" 15746{ 15747 rtx label = gen_label_rtx (); 15748 15749 emit_label (label); 15750 15751 emit_insn (gen_fprem1xf4 (operands[1], operands[2], 15752 operands[1], operands[2])); 15753 ix86_emit_fp_unordered_jump (label); 15754 15755 emit_move_insn (operands[0], operands[1]); 15756 DONE; 15757}) 15758 15759(define_insn "*sindf2" 15760 [(set (match_operand:DF 0 "register_operand" "=f") 15761 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))] 15762 "TARGET_USE_FANCY_MATH_387 15763 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15764 && flag_unsafe_math_optimizations" 15765 "fsin" 15766 [(set_attr "type" "fpspc") 15767 (set_attr "mode" "DF")]) 15768 15769(define_insn "*sinsf2" 15770 [(set (match_operand:SF 0 "register_operand" "=f") 15771 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))] 15772 "TARGET_USE_FANCY_MATH_387 15773 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15774 && flag_unsafe_math_optimizations" 15775 "fsin" 15776 [(set_attr "type" "fpspc") 15777 (set_attr "mode" "SF")]) 15778 15779(define_insn "*sinextendsfdf2" 15780 [(set (match_operand:DF 0 "register_operand" "=f") 15781 (unspec:DF [(float_extend:DF 15782 (match_operand:SF 1 "register_operand" "0"))] 15783 UNSPEC_SIN))] 15784 "TARGET_USE_FANCY_MATH_387 15785 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15786 && flag_unsafe_math_optimizations" 15787 "fsin" 15788 [(set_attr "type" "fpspc") 15789 (set_attr "mode" "DF")]) 15790 15791(define_insn "*sinxf2" 15792 [(set (match_operand:XF 0 "register_operand" "=f") 15793 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))] 15794 "TARGET_USE_FANCY_MATH_387 15795 && flag_unsafe_math_optimizations" 15796 "fsin" 15797 [(set_attr "type" "fpspc") 15798 (set_attr "mode" "XF")]) 15799 15800(define_insn "*cosdf2" 15801 [(set (match_operand:DF 0 "register_operand" "=f") 15802 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))] 15803 "TARGET_USE_FANCY_MATH_387 15804 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15805 && flag_unsafe_math_optimizations" 15806 "fcos" 15807 [(set_attr "type" "fpspc") 15808 (set_attr "mode" "DF")]) 15809 15810(define_insn "*cossf2" 15811 [(set (match_operand:SF 0 "register_operand" "=f") 15812 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))] 15813 "TARGET_USE_FANCY_MATH_387 15814 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15815 && flag_unsafe_math_optimizations" 15816 "fcos" 15817 [(set_attr "type" "fpspc") 15818 (set_attr "mode" "SF")]) 15819 15820(define_insn "*cosextendsfdf2" 15821 [(set (match_operand:DF 0 "register_operand" "=f") 15822 (unspec:DF [(float_extend:DF 15823 (match_operand:SF 1 "register_operand" "0"))] 15824 UNSPEC_COS))] 15825 "TARGET_USE_FANCY_MATH_387 15826 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15827 && flag_unsafe_math_optimizations" 15828 "fcos" 15829 [(set_attr "type" "fpspc") 15830 (set_attr "mode" "DF")]) 15831 15832(define_insn "*cosxf2" 15833 [(set (match_operand:XF 0 "register_operand" "=f") 15834 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))] 15835 "TARGET_USE_FANCY_MATH_387 15836 && flag_unsafe_math_optimizations" 15837 "fcos" 15838 [(set_attr "type" "fpspc") 15839 (set_attr "mode" "XF")]) 15840 15841;; With sincos pattern defined, sin and cos builtin function will be 15842;; expanded to sincos pattern with one of its outputs left unused. 15843;; Cse pass will detected, if two sincos patterns can be combined, 15844;; otherwise sincos pattern will be split back to sin or cos pattern, 15845;; depending on the unused output. 15846 15847(define_insn "sincosdf3" 15848 [(set (match_operand:DF 0 "register_operand" "=f") 15849 (unspec:DF [(match_operand:DF 2 "register_operand" "0")] 15850 UNSPEC_SINCOS_COS)) 15851 (set (match_operand:DF 1 "register_operand" "=u") 15852 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15853 "TARGET_USE_FANCY_MATH_387 15854 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15855 && flag_unsafe_math_optimizations" 15856 "fsincos" 15857 [(set_attr "type" "fpspc") 15858 (set_attr "mode" "DF")]) 15859 15860(define_split 15861 [(set (match_operand:DF 0 "register_operand" "") 15862 (unspec:DF [(match_operand:DF 2 "register_operand" "")] 15863 UNSPEC_SINCOS_COS)) 15864 (set (match_operand:DF 1 "register_operand" "") 15865 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15866 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15867 && !reload_completed && !reload_in_progress" 15868 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))] 15869 "") 15870 15871(define_split 15872 [(set (match_operand:DF 0 "register_operand" "") 15873 (unspec:DF [(match_operand:DF 2 "register_operand" "")] 15874 UNSPEC_SINCOS_COS)) 15875 (set (match_operand:DF 1 "register_operand" "") 15876 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15877 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15878 && !reload_completed && !reload_in_progress" 15879 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))] 15880 "") 15881 15882(define_insn "sincossf3" 15883 [(set (match_operand:SF 0 "register_operand" "=f") 15884 (unspec:SF [(match_operand:SF 2 "register_operand" "0")] 15885 UNSPEC_SINCOS_COS)) 15886 (set (match_operand:SF 1 "register_operand" "=u") 15887 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15888 "TARGET_USE_FANCY_MATH_387 15889 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15890 && flag_unsafe_math_optimizations" 15891 "fsincos" 15892 [(set_attr "type" "fpspc") 15893 (set_attr "mode" "SF")]) 15894 15895(define_split 15896 [(set (match_operand:SF 0 "register_operand" "") 15897 (unspec:SF [(match_operand:SF 2 "register_operand" "")] 15898 UNSPEC_SINCOS_COS)) 15899 (set (match_operand:SF 1 "register_operand" "") 15900 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15901 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15902 && !reload_completed && !reload_in_progress" 15903 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))] 15904 "") 15905 15906(define_split 15907 [(set (match_operand:SF 0 "register_operand" "") 15908 (unspec:SF [(match_operand:SF 2 "register_operand" "")] 15909 UNSPEC_SINCOS_COS)) 15910 (set (match_operand:SF 1 "register_operand" "") 15911 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15912 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15913 && !reload_completed && !reload_in_progress" 15914 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))] 15915 "") 15916 15917(define_insn "*sincosextendsfdf3" 15918 [(set (match_operand:DF 0 "register_operand" "=f") 15919 (unspec:DF [(float_extend:DF 15920 (match_operand:SF 2 "register_operand" "0"))] 15921 UNSPEC_SINCOS_COS)) 15922 (set (match_operand:DF 1 "register_operand" "=u") 15923 (unspec:DF [(float_extend:DF 15924 (match_dup 2))] UNSPEC_SINCOS_SIN))] 15925 "TARGET_USE_FANCY_MATH_387 15926 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 15927 && flag_unsafe_math_optimizations" 15928 "fsincos" 15929 [(set_attr "type" "fpspc") 15930 (set_attr "mode" "DF")]) 15931 15932(define_split 15933 [(set (match_operand:DF 0 "register_operand" "") 15934 (unspec:DF [(float_extend:DF 15935 (match_operand:SF 2 "register_operand" ""))] 15936 UNSPEC_SINCOS_COS)) 15937 (set (match_operand:DF 1 "register_operand" "") 15938 (unspec:DF [(float_extend:DF 15939 (match_dup 2))] UNSPEC_SINCOS_SIN))] 15940 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15941 && !reload_completed && !reload_in_progress" 15942 [(set (match_dup 1) (unspec:DF [(float_extend:DF 15943 (match_dup 2))] UNSPEC_SIN))] 15944 "") 15945 15946(define_split 15947 [(set (match_operand:DF 0 "register_operand" "") 15948 (unspec:DF [(float_extend:DF 15949 (match_operand:SF 2 "register_operand" ""))] 15950 UNSPEC_SINCOS_COS)) 15951 (set (match_operand:DF 1 "register_operand" "") 15952 (unspec:DF [(float_extend:DF 15953 (match_dup 2))] UNSPEC_SINCOS_SIN))] 15954 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15955 && !reload_completed && !reload_in_progress" 15956 [(set (match_dup 0) (unspec:DF [(float_extend:DF 15957 (match_dup 2))] UNSPEC_COS))] 15958 "") 15959 15960(define_insn "sincosxf3" 15961 [(set (match_operand:XF 0 "register_operand" "=f") 15962 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 15963 UNSPEC_SINCOS_COS)) 15964 (set (match_operand:XF 1 "register_operand" "=u") 15965 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15966 "TARGET_USE_FANCY_MATH_387 15967 && flag_unsafe_math_optimizations" 15968 "fsincos" 15969 [(set_attr "type" "fpspc") 15970 (set_attr "mode" "XF")]) 15971 15972(define_split 15973 [(set (match_operand:XF 0 "register_operand" "") 15974 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 15975 UNSPEC_SINCOS_COS)) 15976 (set (match_operand:XF 1 "register_operand" "") 15977 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15978 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15979 && !reload_completed && !reload_in_progress" 15980 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))] 15981 "") 15982 15983(define_split 15984 [(set (match_operand:XF 0 "register_operand" "") 15985 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 15986 UNSPEC_SINCOS_COS)) 15987 (set (match_operand:XF 1 "register_operand" "") 15988 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15989 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15990 && !reload_completed && !reload_in_progress" 15991 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))] 15992 "") 15993 15994(define_insn "*tandf3_1" 15995 [(set (match_operand:DF 0 "register_operand" "=f") 15996 (unspec:DF [(match_operand:DF 2 "register_operand" "0")] 15997 UNSPEC_TAN_ONE)) 15998 (set (match_operand:DF 1 "register_operand" "=u") 15999 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))] 16000 "TARGET_USE_FANCY_MATH_387 16001 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16002 && flag_unsafe_math_optimizations" 16003 "fptan" 16004 [(set_attr "type" "fpspc") 16005 (set_attr "mode" "DF")]) 16006 16007;; optimize sequence: fptan 16008;; fstp %st(0) 16009;; fld1 16010;; into fptan insn. 16011 16012(define_peephole2 16013 [(parallel[(set (match_operand:DF 0 "register_operand" "") 16014 (unspec:DF [(match_operand:DF 2 "register_operand" "")] 16015 UNSPEC_TAN_ONE)) 16016 (set (match_operand:DF 1 "register_operand" "") 16017 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]) 16018 (set (match_dup 0) 16019 (match_operand:DF 3 "immediate_operand" ""))] 16020 "standard_80387_constant_p (operands[3]) == 2" 16021 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE)) 16022 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])] 16023 "") 16024 16025(define_expand "tandf2" 16026 [(parallel [(set (match_dup 2) 16027 (unspec:DF [(match_operand:DF 1 "register_operand" "")] 16028 UNSPEC_TAN_ONE)) 16029 (set (match_operand:DF 0 "register_operand" "") 16030 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])] 16031 "TARGET_USE_FANCY_MATH_387 16032 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16033 && flag_unsafe_math_optimizations" 16034{ 16035 operands[2] = gen_reg_rtx (DFmode); 16036}) 16037 16038(define_insn "*tansf3_1" 16039 [(set (match_operand:SF 0 "register_operand" "=f") 16040 (unspec:SF [(match_operand:SF 2 "register_operand" "0")] 16041 UNSPEC_TAN_ONE)) 16042 (set (match_operand:SF 1 "register_operand" "=u") 16043 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))] 16044 "TARGET_USE_FANCY_MATH_387 16045 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16046 && flag_unsafe_math_optimizations" 16047 "fptan" 16048 [(set_attr "type" "fpspc") 16049 (set_attr "mode" "SF")]) 16050 16051;; optimize sequence: fptan 16052;; fstp %st(0) 16053;; fld1 16054;; into fptan insn. 16055 16056(define_peephole2 16057 [(parallel[(set (match_operand:SF 0 "register_operand" "") 16058 (unspec:SF [(match_operand:SF 2 "register_operand" "")] 16059 UNSPEC_TAN_ONE)) 16060 (set (match_operand:SF 1 "register_operand" "") 16061 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]) 16062 (set (match_dup 0) 16063 (match_operand:SF 3 "immediate_operand" ""))] 16064 "standard_80387_constant_p (operands[3]) == 2" 16065 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE)) 16066 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])] 16067 "") 16068 16069(define_expand "tansf2" 16070 [(parallel [(set (match_dup 2) 16071 (unspec:SF [(match_operand:SF 1 "register_operand" "")] 16072 UNSPEC_TAN_ONE)) 16073 (set (match_operand:SF 0 "register_operand" "") 16074 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])] 16075 "TARGET_USE_FANCY_MATH_387 16076 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16077 && flag_unsafe_math_optimizations" 16078{ 16079 operands[2] = gen_reg_rtx (SFmode); 16080}) 16081 16082(define_insn "*tanxf3_1" 16083 [(set (match_operand:XF 0 "register_operand" "=f") 16084 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 16085 UNSPEC_TAN_ONE)) 16086 (set (match_operand:XF 1 "register_operand" "=u") 16087 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))] 16088 "TARGET_USE_FANCY_MATH_387 16089 && flag_unsafe_math_optimizations" 16090 "fptan" 16091 [(set_attr "type" "fpspc") 16092 (set_attr "mode" "XF")]) 16093 16094;; optimize sequence: fptan 16095;; fstp %st(0) 16096;; fld1 16097;; into fptan insn. 16098 16099(define_peephole2 16100 [(parallel[(set (match_operand:XF 0 "register_operand" "") 16101 (unspec:XF [(match_operand:XF 2 "register_operand" "")] 16102 UNSPEC_TAN_ONE)) 16103 (set (match_operand:XF 1 "register_operand" "") 16104 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]) 16105 (set (match_dup 0) 16106 (match_operand:XF 3 "immediate_operand" ""))] 16107 "standard_80387_constant_p (operands[3]) == 2" 16108 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE)) 16109 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])] 16110 "") 16111 16112(define_expand "tanxf2" 16113 [(parallel [(set (match_dup 2) 16114 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 16115 UNSPEC_TAN_ONE)) 16116 (set (match_operand:XF 0 "register_operand" "") 16117 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])] 16118 "TARGET_USE_FANCY_MATH_387 16119 && flag_unsafe_math_optimizations" 16120{ 16121 operands[2] = gen_reg_rtx (XFmode); 16122}) 16123 16124(define_insn "atan2df3_1" 16125 [(set (match_operand:DF 0 "register_operand" "=f") 16126 (unspec:DF [(match_operand:DF 2 "register_operand" "0") 16127 (match_operand:DF 1 "register_operand" "u")] 16128 UNSPEC_FPATAN)) 16129 (clobber (match_scratch:DF 3 "=1"))] 16130 "TARGET_USE_FANCY_MATH_387 16131 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16132 && flag_unsafe_math_optimizations" 16133 "fpatan" 16134 [(set_attr "type" "fpspc") 16135 (set_attr "mode" "DF")]) 16136 16137(define_expand "atan2df3" 16138 [(use (match_operand:DF 0 "register_operand" "")) 16139 (use (match_operand:DF 2 "register_operand" "")) 16140 (use (match_operand:DF 1 "register_operand" ""))] 16141 "TARGET_USE_FANCY_MATH_387 16142 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16143 && flag_unsafe_math_optimizations" 16144{ 16145 rtx copy = gen_reg_rtx (DFmode); 16146 emit_move_insn (copy, operands[1]); 16147 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2])); 16148 DONE; 16149}) 16150 16151(define_expand "atandf2" 16152 [(parallel [(set (match_operand:DF 0 "register_operand" "") 16153 (unspec:DF [(match_dup 2) 16154 (match_operand:DF 1 "register_operand" "")] 16155 UNSPEC_FPATAN)) 16156 (clobber (match_scratch:DF 3 ""))])] 16157 "TARGET_USE_FANCY_MATH_387 16158 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16159 && flag_unsafe_math_optimizations" 16160{ 16161 operands[2] = gen_reg_rtx (DFmode); 16162 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */ 16163}) 16164 16165(define_insn "atan2sf3_1" 16166 [(set (match_operand:SF 0 "register_operand" "=f") 16167 (unspec:SF [(match_operand:SF 2 "register_operand" "0") 16168 (match_operand:SF 1 "register_operand" "u")] 16169 UNSPEC_FPATAN)) 16170 (clobber (match_scratch:SF 3 "=1"))] 16171 "TARGET_USE_FANCY_MATH_387 16172 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16173 && flag_unsafe_math_optimizations" 16174 "fpatan" 16175 [(set_attr "type" "fpspc") 16176 (set_attr "mode" "SF")]) 16177 16178(define_expand "atan2sf3" 16179 [(use (match_operand:SF 0 "register_operand" "")) 16180 (use (match_operand:SF 2 "register_operand" "")) 16181 (use (match_operand:SF 1 "register_operand" ""))] 16182 "TARGET_USE_FANCY_MATH_387 16183 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16184 && flag_unsafe_math_optimizations" 16185{ 16186 rtx copy = gen_reg_rtx (SFmode); 16187 emit_move_insn (copy, operands[1]); 16188 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2])); 16189 DONE; 16190}) 16191 16192(define_expand "atansf2" 16193 [(parallel [(set (match_operand:SF 0 "register_operand" "") 16194 (unspec:SF [(match_dup 2) 16195 (match_operand:SF 1 "register_operand" "")] 16196 UNSPEC_FPATAN)) 16197 (clobber (match_scratch:SF 3 ""))])] 16198 "TARGET_USE_FANCY_MATH_387 16199 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16200 && flag_unsafe_math_optimizations" 16201{ 16202 operands[2] = gen_reg_rtx (SFmode); 16203 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */ 16204}) 16205 16206(define_insn "atan2xf3_1" 16207 [(set (match_operand:XF 0 "register_operand" "=f") 16208 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16209 (match_operand:XF 1 "register_operand" "u")] 16210 UNSPEC_FPATAN)) 16211 (clobber (match_scratch:XF 3 "=1"))] 16212 "TARGET_USE_FANCY_MATH_387 16213 && flag_unsafe_math_optimizations" 16214 "fpatan" 16215 [(set_attr "type" "fpspc") 16216 (set_attr "mode" "XF")]) 16217 16218(define_expand "atan2xf3" 16219 [(use (match_operand:XF 0 "register_operand" "")) 16220 (use (match_operand:XF 2 "register_operand" "")) 16221 (use (match_operand:XF 1 "register_operand" ""))] 16222 "TARGET_USE_FANCY_MATH_387 16223 && flag_unsafe_math_optimizations" 16224{ 16225 rtx copy = gen_reg_rtx (XFmode); 16226 emit_move_insn (copy, operands[1]); 16227 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2])); 16228 DONE; 16229}) 16230 16231(define_expand "atanxf2" 16232 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16233 (unspec:XF [(match_dup 2) 16234 (match_operand:XF 1 "register_operand" "")] 16235 UNSPEC_FPATAN)) 16236 (clobber (match_scratch:XF 3 ""))])] 16237 "TARGET_USE_FANCY_MATH_387 16238 && flag_unsafe_math_optimizations" 16239{ 16240 operands[2] = gen_reg_rtx (XFmode); 16241 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 16242}) 16243 16244(define_expand "asindf2" 16245 [(set (match_dup 2) 16246 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16247 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16248 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16249 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16250 (parallel [(set (match_dup 7) 16251 (unspec:XF [(match_dup 6) (match_dup 2)] 16252 UNSPEC_FPATAN)) 16253 (clobber (match_scratch:XF 8 ""))]) 16254 (set (match_operand:DF 0 "register_operand" "") 16255 (float_truncate:DF (match_dup 7)))] 16256 "TARGET_USE_FANCY_MATH_387 16257 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16258 && flag_unsafe_math_optimizations" 16259{ 16260 int i; 16261 16262 for (i=2; i<8; i++) 16263 operands[i] = gen_reg_rtx (XFmode); 16264 16265 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16266}) 16267 16268(define_expand "asinsf2" 16269 [(set (match_dup 2) 16270 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16271 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16272 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16273 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16274 (parallel [(set (match_dup 7) 16275 (unspec:XF [(match_dup 6) (match_dup 2)] 16276 UNSPEC_FPATAN)) 16277 (clobber (match_scratch:XF 8 ""))]) 16278 (set (match_operand:SF 0 "register_operand" "") 16279 (float_truncate:SF (match_dup 7)))] 16280 "TARGET_USE_FANCY_MATH_387 16281 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16282 && flag_unsafe_math_optimizations" 16283{ 16284 int i; 16285 16286 for (i=2; i<8; i++) 16287 operands[i] = gen_reg_rtx (XFmode); 16288 16289 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16290}) 16291 16292(define_expand "asinxf2" 16293 [(set (match_dup 2) 16294 (mult:XF (match_operand:XF 1 "register_operand" "") 16295 (match_dup 1))) 16296 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 16297 (set (match_dup 5) (sqrt:XF (match_dup 4))) 16298 (parallel [(set (match_operand:XF 0 "register_operand" "") 16299 (unspec:XF [(match_dup 5) (match_dup 1)] 16300 UNSPEC_FPATAN)) 16301 (clobber (match_scratch:XF 6 ""))])] 16302 "TARGET_USE_FANCY_MATH_387 16303 && flag_unsafe_math_optimizations" 16304{ 16305 int i; 16306 16307 for (i=2; i<6; i++) 16308 operands[i] = gen_reg_rtx (XFmode); 16309 16310 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16311}) 16312 16313(define_expand "acosdf2" 16314 [(set (match_dup 2) 16315 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16316 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16317 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16318 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16319 (parallel [(set (match_dup 7) 16320 (unspec:XF [(match_dup 2) (match_dup 6)] 16321 UNSPEC_FPATAN)) 16322 (clobber (match_scratch:XF 8 ""))]) 16323 (set (match_operand:DF 0 "register_operand" "") 16324 (float_truncate:DF (match_dup 7)))] 16325 "TARGET_USE_FANCY_MATH_387 16326 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16327 && flag_unsafe_math_optimizations" 16328{ 16329 int i; 16330 16331 for (i=2; i<8; i++) 16332 operands[i] = gen_reg_rtx (XFmode); 16333 16334 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16335}) 16336 16337(define_expand "acossf2" 16338 [(set (match_dup 2) 16339 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16340 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2))) 16341 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3))) 16342 (set (match_dup 6) (sqrt:XF (match_dup 5))) 16343 (parallel [(set (match_dup 7) 16344 (unspec:XF [(match_dup 2) (match_dup 6)] 16345 UNSPEC_FPATAN)) 16346 (clobber (match_scratch:XF 8 ""))]) 16347 (set (match_operand:SF 0 "register_operand" "") 16348 (float_truncate:SF (match_dup 7)))] 16349 "TARGET_USE_FANCY_MATH_387 16350 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16351 && flag_unsafe_math_optimizations" 16352{ 16353 int i; 16354 16355 for (i=2; i<8; i++) 16356 operands[i] = gen_reg_rtx (XFmode); 16357 16358 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */ 16359}) 16360 16361(define_expand "acosxf2" 16362 [(set (match_dup 2) 16363 (mult:XF (match_operand:XF 1 "register_operand" "") 16364 (match_dup 1))) 16365 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 16366 (set (match_dup 5) (sqrt:XF (match_dup 4))) 16367 (parallel [(set (match_operand:XF 0 "register_operand" "") 16368 (unspec:XF [(match_dup 1) (match_dup 5)] 16369 UNSPEC_FPATAN)) 16370 (clobber (match_scratch:XF 6 ""))])] 16371 "TARGET_USE_FANCY_MATH_387 16372 && flag_unsafe_math_optimizations" 16373{ 16374 int i; 16375 16376 for (i=2; i<6; i++) 16377 operands[i] = gen_reg_rtx (XFmode); 16378 16379 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16380}) 16381 16382(define_insn "fyl2x_xf3" 16383 [(set (match_operand:XF 0 "register_operand" "=f") 16384 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16385 (match_operand:XF 1 "register_operand" "u")] 16386 UNSPEC_FYL2X)) 16387 (clobber (match_scratch:XF 3 "=1"))] 16388 "TARGET_USE_FANCY_MATH_387 16389 && flag_unsafe_math_optimizations" 16390 "fyl2x" 16391 [(set_attr "type" "fpspc") 16392 (set_attr "mode" "XF")]) 16393 16394(define_expand "logsf2" 16395 [(set (match_dup 2) 16396 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16397 (parallel [(set (match_dup 4) 16398 (unspec:XF [(match_dup 2) 16399 (match_dup 3)] UNSPEC_FYL2X)) 16400 (clobber (match_scratch:XF 5 ""))]) 16401 (set (match_operand:SF 0 "register_operand" "") 16402 (float_truncate:SF (match_dup 4)))] 16403 "TARGET_USE_FANCY_MATH_387 16404 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16405 && flag_unsafe_math_optimizations" 16406{ 16407 rtx temp; 16408 16409 operands[2] = gen_reg_rtx (XFmode); 16410 operands[3] = gen_reg_rtx (XFmode); 16411 operands[4] = gen_reg_rtx (XFmode); 16412 16413 temp = standard_80387_constant_rtx (4); /* fldln2 */ 16414 emit_move_insn (operands[3], temp); 16415}) 16416 16417(define_expand "logdf2" 16418 [(set (match_dup 2) 16419 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16420 (parallel [(set (match_dup 4) 16421 (unspec:XF [(match_dup 2) 16422 (match_dup 3)] UNSPEC_FYL2X)) 16423 (clobber (match_scratch:XF 5 ""))]) 16424 (set (match_operand:DF 0 "register_operand" "") 16425 (float_truncate:DF (match_dup 4)))] 16426 "TARGET_USE_FANCY_MATH_387 16427 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16428 && flag_unsafe_math_optimizations" 16429{ 16430 rtx temp; 16431 16432 operands[2] = gen_reg_rtx (XFmode); 16433 operands[3] = gen_reg_rtx (XFmode); 16434 operands[4] = gen_reg_rtx (XFmode); 16435 16436 temp = standard_80387_constant_rtx (4); /* fldln2 */ 16437 emit_move_insn (operands[3], temp); 16438}) 16439 16440(define_expand "logxf2" 16441 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16442 (unspec:XF [(match_operand:XF 1 "register_operand" "") 16443 (match_dup 2)] UNSPEC_FYL2X)) 16444 (clobber (match_scratch:XF 3 ""))])] 16445 "TARGET_USE_FANCY_MATH_387 16446 && flag_unsafe_math_optimizations" 16447{ 16448 rtx temp; 16449 16450 operands[2] = gen_reg_rtx (XFmode); 16451 temp = standard_80387_constant_rtx (4); /* fldln2 */ 16452 emit_move_insn (operands[2], temp); 16453}) 16454 16455(define_expand "log10sf2" 16456 [(set (match_dup 2) 16457 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16458 (parallel [(set (match_dup 4) 16459 (unspec:XF [(match_dup 2) 16460 (match_dup 3)] UNSPEC_FYL2X)) 16461 (clobber (match_scratch:XF 5 ""))]) 16462 (set (match_operand:SF 0 "register_operand" "") 16463 (float_truncate:SF (match_dup 4)))] 16464 "TARGET_USE_FANCY_MATH_387 16465 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16466 && flag_unsafe_math_optimizations" 16467{ 16468 rtx temp; 16469 16470 operands[2] = gen_reg_rtx (XFmode); 16471 operands[3] = gen_reg_rtx (XFmode); 16472 operands[4] = gen_reg_rtx (XFmode); 16473 16474 temp = standard_80387_constant_rtx (3); /* fldlg2 */ 16475 emit_move_insn (operands[3], temp); 16476}) 16477 16478(define_expand "log10df2" 16479 [(set (match_dup 2) 16480 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16481 (parallel [(set (match_dup 4) 16482 (unspec:XF [(match_dup 2) 16483 (match_dup 3)] UNSPEC_FYL2X)) 16484 (clobber (match_scratch:XF 5 ""))]) 16485 (set (match_operand:DF 0 "register_operand" "") 16486 (float_truncate:DF (match_dup 4)))] 16487 "TARGET_USE_FANCY_MATH_387 16488 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16489 && flag_unsafe_math_optimizations" 16490{ 16491 rtx temp; 16492 16493 operands[2] = gen_reg_rtx (XFmode); 16494 operands[3] = gen_reg_rtx (XFmode); 16495 operands[4] = gen_reg_rtx (XFmode); 16496 16497 temp = standard_80387_constant_rtx (3); /* fldlg2 */ 16498 emit_move_insn (operands[3], temp); 16499}) 16500 16501(define_expand "log10xf2" 16502 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16503 (unspec:XF [(match_operand:XF 1 "register_operand" "") 16504 (match_dup 2)] UNSPEC_FYL2X)) 16505 (clobber (match_scratch:XF 3 ""))])] 16506 "TARGET_USE_FANCY_MATH_387 16507 && flag_unsafe_math_optimizations" 16508{ 16509 rtx temp; 16510 16511 operands[2] = gen_reg_rtx (XFmode); 16512 temp = standard_80387_constant_rtx (3); /* fldlg2 */ 16513 emit_move_insn (operands[2], temp); 16514}) 16515 16516(define_expand "log2sf2" 16517 [(set (match_dup 2) 16518 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16519 (parallel [(set (match_dup 4) 16520 (unspec:XF [(match_dup 2) 16521 (match_dup 3)] UNSPEC_FYL2X)) 16522 (clobber (match_scratch:XF 5 ""))]) 16523 (set (match_operand:SF 0 "register_operand" "") 16524 (float_truncate:SF (match_dup 4)))] 16525 "TARGET_USE_FANCY_MATH_387 16526 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16527 && flag_unsafe_math_optimizations" 16528{ 16529 operands[2] = gen_reg_rtx (XFmode); 16530 operands[3] = gen_reg_rtx (XFmode); 16531 operands[4] = gen_reg_rtx (XFmode); 16532 16533 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16534}) 16535 16536(define_expand "log2df2" 16537 [(set (match_dup 2) 16538 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16539 (parallel [(set (match_dup 4) 16540 (unspec:XF [(match_dup 2) 16541 (match_dup 3)] UNSPEC_FYL2X)) 16542 (clobber (match_scratch:XF 5 ""))]) 16543 (set (match_operand:DF 0 "register_operand" "") 16544 (float_truncate:DF (match_dup 4)))] 16545 "TARGET_USE_FANCY_MATH_387 16546 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16547 && flag_unsafe_math_optimizations" 16548{ 16549 operands[2] = gen_reg_rtx (XFmode); 16550 operands[3] = gen_reg_rtx (XFmode); 16551 operands[4] = gen_reg_rtx (XFmode); 16552 16553 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 16554}) 16555 16556(define_expand "log2xf2" 16557 [(parallel [(set (match_operand:XF 0 "register_operand" "") 16558 (unspec:XF [(match_operand:XF 1 "register_operand" "") 16559 (match_dup 2)] UNSPEC_FYL2X)) 16560 (clobber (match_scratch:XF 3 ""))])] 16561 "TARGET_USE_FANCY_MATH_387 16562 && flag_unsafe_math_optimizations" 16563{ 16564 operands[2] = gen_reg_rtx (XFmode); 16565 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 16566}) 16567 16568(define_insn "fyl2xp1_xf3" 16569 [(set (match_operand:XF 0 "register_operand" "=f") 16570 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16571 (match_operand:XF 1 "register_operand" "u")] 16572 UNSPEC_FYL2XP1)) 16573 (clobber (match_scratch:XF 3 "=1"))] 16574 "TARGET_USE_FANCY_MATH_387 16575 && flag_unsafe_math_optimizations" 16576 "fyl2xp1" 16577 [(set_attr "type" "fpspc") 16578 (set_attr "mode" "XF")]) 16579 16580(define_expand "log1psf2" 16581 [(use (match_operand:SF 0 "register_operand" "")) 16582 (use (match_operand:SF 1 "register_operand" ""))] 16583 "TARGET_USE_FANCY_MATH_387 16584 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16585 && flag_unsafe_math_optimizations" 16586{ 16587 rtx op0 = gen_reg_rtx (XFmode); 16588 rtx op1 = gen_reg_rtx (XFmode); 16589 16590 emit_insn (gen_extendsfxf2 (op1, operands[1])); 16591 ix86_emit_i387_log1p (op0, op1); 16592 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 16593 DONE; 16594}) 16595 16596(define_expand "log1pdf2" 16597 [(use (match_operand:DF 0 "register_operand" "")) 16598 (use (match_operand:DF 1 "register_operand" ""))] 16599 "TARGET_USE_FANCY_MATH_387 16600 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16601 && flag_unsafe_math_optimizations" 16602{ 16603 rtx op0 = gen_reg_rtx (XFmode); 16604 rtx op1 = gen_reg_rtx (XFmode); 16605 16606 emit_insn (gen_extenddfxf2 (op1, operands[1])); 16607 ix86_emit_i387_log1p (op0, op1); 16608 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 16609 DONE; 16610}) 16611 16612(define_expand "log1pxf2" 16613 [(use (match_operand:XF 0 "register_operand" "")) 16614 (use (match_operand:XF 1 "register_operand" ""))] 16615 "TARGET_USE_FANCY_MATH_387 16616 && flag_unsafe_math_optimizations" 16617{ 16618 ix86_emit_i387_log1p (operands[0], operands[1]); 16619 DONE; 16620}) 16621 16622(define_insn "*fxtractxf3" 16623 [(set (match_operand:XF 0 "register_operand" "=f") 16624 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 16625 UNSPEC_XTRACT_FRACT)) 16626 (set (match_operand:XF 1 "register_operand" "=u") 16627 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))] 16628 "TARGET_USE_FANCY_MATH_387 16629 && flag_unsafe_math_optimizations" 16630 "fxtract" 16631 [(set_attr "type" "fpspc") 16632 (set_attr "mode" "XF")]) 16633 16634(define_expand "logbsf2" 16635 [(set (match_dup 2) 16636 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16637 (parallel [(set (match_dup 3) 16638 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT)) 16639 (set (match_dup 4) 16640 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]) 16641 (set (match_operand:SF 0 "register_operand" "") 16642 (float_truncate:SF (match_dup 4)))] 16643 "TARGET_USE_FANCY_MATH_387 16644 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16645 && flag_unsafe_math_optimizations" 16646{ 16647 operands[2] = gen_reg_rtx (XFmode); 16648 operands[3] = gen_reg_rtx (XFmode); 16649 operands[4] = gen_reg_rtx (XFmode); 16650}) 16651 16652(define_expand "logbdf2" 16653 [(set (match_dup 2) 16654 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16655 (parallel [(set (match_dup 3) 16656 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT)) 16657 (set (match_dup 4) 16658 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]) 16659 (set (match_operand:DF 0 "register_operand" "") 16660 (float_truncate:DF (match_dup 4)))] 16661 "TARGET_USE_FANCY_MATH_387 16662 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16663 && flag_unsafe_math_optimizations" 16664{ 16665 operands[2] = gen_reg_rtx (XFmode); 16666 operands[3] = gen_reg_rtx (XFmode); 16667 operands[4] = gen_reg_rtx (XFmode); 16668}) 16669 16670(define_expand "logbxf2" 16671 [(parallel [(set (match_dup 2) 16672 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 16673 UNSPEC_XTRACT_FRACT)) 16674 (set (match_operand:XF 0 "register_operand" "") 16675 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 16676 "TARGET_USE_FANCY_MATH_387 16677 && flag_unsafe_math_optimizations" 16678{ 16679 operands[2] = gen_reg_rtx (XFmode); 16680}) 16681 16682(define_expand "ilogbsi2" 16683 [(parallel [(set (match_dup 2) 16684 (unspec:XF [(match_operand:XF 1 "register_operand" "")] 16685 UNSPEC_XTRACT_FRACT)) 16686 (set (match_operand:XF 3 "register_operand" "") 16687 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))]) 16688 (parallel [(set (match_operand:SI 0 "register_operand" "") 16689 (fix:SI (match_dup 3))) 16690 (clobber (reg:CC FLAGS_REG))])] 16691 "TARGET_USE_FANCY_MATH_387 16692 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16693 && flag_unsafe_math_optimizations" 16694{ 16695 operands[2] = gen_reg_rtx (XFmode); 16696 operands[3] = gen_reg_rtx (XFmode); 16697}) 16698 16699(define_insn "*f2xm1xf2" 16700 [(set (match_operand:XF 0 "register_operand" "=f") 16701 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16702 UNSPEC_F2XM1))] 16703 "TARGET_USE_FANCY_MATH_387 16704 && flag_unsafe_math_optimizations" 16705 "f2xm1" 16706 [(set_attr "type" "fpspc") 16707 (set_attr "mode" "XF")]) 16708 16709(define_insn "*fscalexf4" 16710 [(set (match_operand:XF 0 "register_operand" "=f") 16711 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16712 (match_operand:XF 3 "register_operand" "1")] 16713 UNSPEC_FSCALE_FRACT)) 16714 (set (match_operand:XF 1 "register_operand" "=u") 16715 (unspec:XF [(match_dup 2) (match_dup 3)] 16716 UNSPEC_FSCALE_EXP))] 16717 "TARGET_USE_FANCY_MATH_387 16718 && flag_unsafe_math_optimizations" 16719 "fscale" 16720 [(set_attr "type" "fpspc") 16721 (set_attr "mode" "XF")]) 16722 16723(define_expand "expsf2" 16724 [(set (match_dup 2) 16725 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16726 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16727 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16728 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16729 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16730 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 16731 (parallel [(set (match_dup 10) 16732 (unspec:XF [(match_dup 9) (match_dup 5)] 16733 UNSPEC_FSCALE_FRACT)) 16734 (set (match_dup 11) 16735 (unspec:XF [(match_dup 9) (match_dup 5)] 16736 UNSPEC_FSCALE_EXP))]) 16737 (set (match_operand:SF 0 "register_operand" "") 16738 (float_truncate:SF (match_dup 10)))] 16739 "TARGET_USE_FANCY_MATH_387 16740 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16741 && flag_unsafe_math_optimizations" 16742{ 16743 rtx temp; 16744 int i; 16745 16746 for (i=2; i<12; i++) 16747 operands[i] = gen_reg_rtx (XFmode); 16748 temp = standard_80387_constant_rtx (5); /* fldl2e */ 16749 emit_move_insn (operands[3], temp); 16750 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 16751}) 16752 16753(define_expand "expdf2" 16754 [(set (match_dup 2) 16755 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16756 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16757 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16758 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16759 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16760 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 16761 (parallel [(set (match_dup 10) 16762 (unspec:XF [(match_dup 9) (match_dup 5)] 16763 UNSPEC_FSCALE_FRACT)) 16764 (set (match_dup 11) 16765 (unspec:XF [(match_dup 9) (match_dup 5)] 16766 UNSPEC_FSCALE_EXP))]) 16767 (set (match_operand:DF 0 "register_operand" "") 16768 (float_truncate:DF (match_dup 10)))] 16769 "TARGET_USE_FANCY_MATH_387 16770 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16771 && flag_unsafe_math_optimizations" 16772{ 16773 rtx temp; 16774 int i; 16775 16776 for (i=2; i<12; i++) 16777 operands[i] = gen_reg_rtx (XFmode); 16778 temp = standard_80387_constant_rtx (5); /* fldl2e */ 16779 emit_move_insn (operands[3], temp); 16780 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 16781}) 16782 16783(define_expand "expxf2" 16784 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 16785 (match_dup 2))) 16786 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 16787 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 16788 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 16789 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 16790 (parallel [(set (match_operand:XF 0 "register_operand" "") 16791 (unspec:XF [(match_dup 8) (match_dup 4)] 16792 UNSPEC_FSCALE_FRACT)) 16793 (set (match_dup 9) 16794 (unspec:XF [(match_dup 8) (match_dup 4)] 16795 UNSPEC_FSCALE_EXP))])] 16796 "TARGET_USE_FANCY_MATH_387 16797 && flag_unsafe_math_optimizations" 16798{ 16799 rtx temp; 16800 int i; 16801 16802 for (i=2; i<10; i++) 16803 operands[i] = gen_reg_rtx (XFmode); 16804 temp = standard_80387_constant_rtx (5); /* fldl2e */ 16805 emit_move_insn (operands[2], temp); 16806 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ 16807}) 16808 16809(define_expand "exp10sf2" 16810 [(set (match_dup 2) 16811 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16812 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16813 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16814 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16815 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16816 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 16817 (parallel [(set (match_dup 10) 16818 (unspec:XF [(match_dup 9) (match_dup 5)] 16819 UNSPEC_FSCALE_FRACT)) 16820 (set (match_dup 11) 16821 (unspec:XF [(match_dup 9) (match_dup 5)] 16822 UNSPEC_FSCALE_EXP))]) 16823 (set (match_operand:SF 0 "register_operand" "") 16824 (float_truncate:SF (match_dup 10)))] 16825 "TARGET_USE_FANCY_MATH_387 16826 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16827 && flag_unsafe_math_optimizations" 16828{ 16829 rtx temp; 16830 int i; 16831 16832 for (i=2; i<12; i++) 16833 operands[i] = gen_reg_rtx (XFmode); 16834 temp = standard_80387_constant_rtx (6); /* fldl2t */ 16835 emit_move_insn (operands[3], temp); 16836 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 16837}) 16838 16839(define_expand "exp10df2" 16840 [(set (match_dup 2) 16841 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16842 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16843 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16844 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16845 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16846 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8))) 16847 (parallel [(set (match_dup 10) 16848 (unspec:XF [(match_dup 9) (match_dup 5)] 16849 UNSPEC_FSCALE_FRACT)) 16850 (set (match_dup 11) 16851 (unspec:XF [(match_dup 9) (match_dup 5)] 16852 UNSPEC_FSCALE_EXP))]) 16853 (set (match_operand:DF 0 "register_operand" "") 16854 (float_truncate:DF (match_dup 10)))] 16855 "TARGET_USE_FANCY_MATH_387 16856 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16857 && flag_unsafe_math_optimizations" 16858{ 16859 rtx temp; 16860 int i; 16861 16862 for (i=2; i<12; i++) 16863 operands[i] = gen_reg_rtx (XFmode); 16864 temp = standard_80387_constant_rtx (6); /* fldl2t */ 16865 emit_move_insn (operands[3], temp); 16866 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */ 16867}) 16868 16869(define_expand "exp10xf2" 16870 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 16871 (match_dup 2))) 16872 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 16873 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 16874 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 16875 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 16876 (parallel [(set (match_operand:XF 0 "register_operand" "") 16877 (unspec:XF [(match_dup 8) (match_dup 4)] 16878 UNSPEC_FSCALE_FRACT)) 16879 (set (match_dup 9) 16880 (unspec:XF [(match_dup 8) (match_dup 4)] 16881 UNSPEC_FSCALE_EXP))])] 16882 "TARGET_USE_FANCY_MATH_387 16883 && flag_unsafe_math_optimizations" 16884{ 16885 rtx temp; 16886 int i; 16887 16888 for (i=2; i<10; i++) 16889 operands[i] = gen_reg_rtx (XFmode); 16890 temp = standard_80387_constant_rtx (6); /* fldl2t */ 16891 emit_move_insn (operands[2], temp); 16892 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ 16893}) 16894 16895(define_expand "exp2sf2" 16896 [(set (match_dup 2) 16897 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 16898 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT)) 16899 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3))) 16900 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1)) 16901 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6))) 16902 (parallel [(set (match_dup 8) 16903 (unspec:XF [(match_dup 7) (match_dup 3)] 16904 UNSPEC_FSCALE_FRACT)) 16905 (set (match_dup 9) 16906 (unspec:XF [(match_dup 7) (match_dup 3)] 16907 UNSPEC_FSCALE_EXP))]) 16908 (set (match_operand:SF 0 "register_operand" "") 16909 (float_truncate:SF (match_dup 8)))] 16910 "TARGET_USE_FANCY_MATH_387 16911 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16912 && flag_unsafe_math_optimizations" 16913{ 16914 int i; 16915 16916 for (i=2; i<10; i++) 16917 operands[i] = gen_reg_rtx (XFmode); 16918 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */ 16919}) 16920 16921(define_expand "exp2df2" 16922 [(set (match_dup 2) 16923 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16924 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT)) 16925 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3))) 16926 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1)) 16927 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6))) 16928 (parallel [(set (match_dup 8) 16929 (unspec:XF [(match_dup 7) (match_dup 3)] 16930 UNSPEC_FSCALE_FRACT)) 16931 (set (match_dup 9) 16932 (unspec:XF [(match_dup 7) (match_dup 3)] 16933 UNSPEC_FSCALE_EXP))]) 16934 (set (match_operand:DF 0 "register_operand" "") 16935 (float_truncate:DF (match_dup 8)))] 16936 "TARGET_USE_FANCY_MATH_387 16937 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16938 && flag_unsafe_math_optimizations" 16939{ 16940 int i; 16941 16942 for (i=2; i<10; i++) 16943 operands[i] = gen_reg_rtx (XFmode); 16944 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */ 16945}) 16946 16947(define_expand "exp2xf2" 16948 [(set (match_dup 2) (match_operand:XF 1 "register_operand" "")) 16949 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT)) 16950 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3))) 16951 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1)) 16952 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6))) 16953 (parallel [(set (match_operand:XF 0 "register_operand" "") 16954 (unspec:XF [(match_dup 7) (match_dup 3)] 16955 UNSPEC_FSCALE_FRACT)) 16956 (set (match_dup 8) 16957 (unspec:XF [(match_dup 7) (match_dup 3)] 16958 UNSPEC_FSCALE_EXP))])] 16959 "TARGET_USE_FANCY_MATH_387 16960 && flag_unsafe_math_optimizations" 16961{ 16962 int i; 16963 16964 for (i=2; i<9; i++) 16965 operands[i] = gen_reg_rtx (XFmode); 16966 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */ 16967}) 16968 16969(define_expand "expm1df2" 16970 [(set (match_dup 2) 16971 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 16972 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 16973 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 16974 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 16975 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 16976 (parallel [(set (match_dup 8) 16977 (unspec:XF [(match_dup 7) (match_dup 5)] 16978 UNSPEC_FSCALE_FRACT)) 16979 (set (match_dup 9) 16980 (unspec:XF [(match_dup 7) (match_dup 5)] 16981 UNSPEC_FSCALE_EXP))]) 16982 (parallel [(set (match_dup 11) 16983 (unspec:XF [(match_dup 10) (match_dup 9)] 16984 UNSPEC_FSCALE_FRACT)) 16985 (set (match_dup 12) 16986 (unspec:XF [(match_dup 10) (match_dup 9)] 16987 UNSPEC_FSCALE_EXP))]) 16988 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10))) 16989 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8))) 16990 (set (match_operand:DF 0 "register_operand" "") 16991 (float_truncate:DF (match_dup 14)))] 16992 "TARGET_USE_FANCY_MATH_387 16993 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 16994 && flag_unsafe_math_optimizations" 16995{ 16996 rtx temp; 16997 int i; 16998 16999 for (i=2; i<15; i++) 17000 operands[i] = gen_reg_rtx (XFmode); 17001 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17002 emit_move_insn (operands[3], temp); 17003 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */ 17004}) 17005 17006(define_expand "expm1sf2" 17007 [(set (match_dup 2) 17008 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 17009 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3))) 17010 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT)) 17011 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5))) 17012 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1)) 17013 (parallel [(set (match_dup 8) 17014 (unspec:XF [(match_dup 7) (match_dup 5)] 17015 UNSPEC_FSCALE_FRACT)) 17016 (set (match_dup 9) 17017 (unspec:XF [(match_dup 7) (match_dup 5)] 17018 UNSPEC_FSCALE_EXP))]) 17019 (parallel [(set (match_dup 11) 17020 (unspec:XF [(match_dup 10) (match_dup 9)] 17021 UNSPEC_FSCALE_FRACT)) 17022 (set (match_dup 12) 17023 (unspec:XF [(match_dup 10) (match_dup 9)] 17024 UNSPEC_FSCALE_EXP))]) 17025 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10))) 17026 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8))) 17027 (set (match_operand:SF 0 "register_operand" "") 17028 (float_truncate:SF (match_dup 14)))] 17029 "TARGET_USE_FANCY_MATH_387 17030 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17031 && flag_unsafe_math_optimizations" 17032{ 17033 rtx temp; 17034 int i; 17035 17036 for (i=2; i<15; i++) 17037 operands[i] = gen_reg_rtx (XFmode); 17038 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17039 emit_move_insn (operands[3], temp); 17040 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */ 17041}) 17042 17043(define_expand "expm1xf2" 17044 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "") 17045 (match_dup 2))) 17046 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 17047 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 17048 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 17049 (parallel [(set (match_dup 7) 17050 (unspec:XF [(match_dup 6) (match_dup 4)] 17051 UNSPEC_FSCALE_FRACT)) 17052 (set (match_dup 8) 17053 (unspec:XF [(match_dup 6) (match_dup 4)] 17054 UNSPEC_FSCALE_EXP))]) 17055 (parallel [(set (match_dup 10) 17056 (unspec:XF [(match_dup 9) (match_dup 8)] 17057 UNSPEC_FSCALE_FRACT)) 17058 (set (match_dup 11) 17059 (unspec:XF [(match_dup 9) (match_dup 8)] 17060 UNSPEC_FSCALE_EXP))]) 17061 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9))) 17062 (set (match_operand:XF 0 "register_operand" "") 17063 (plus:XF (match_dup 12) (match_dup 7)))] 17064 "TARGET_USE_FANCY_MATH_387 17065 && flag_unsafe_math_optimizations" 17066{ 17067 rtx temp; 17068 int i; 17069 17070 for (i=2; i<13; i++) 17071 operands[i] = gen_reg_rtx (XFmode); 17072 temp = standard_80387_constant_rtx (5); /* fldl2e */ 17073 emit_move_insn (operands[2], temp); 17074 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */ 17075}) 17076 17077(define_expand "ldexpdf3" 17078 [(set (match_dup 3) 17079 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 17080 (set (match_dup 4) 17081 (float:XF (match_operand:SI 2 "register_operand" ""))) 17082 (parallel [(set (match_dup 5) 17083 (unspec:XF [(match_dup 3) (match_dup 4)] 17084 UNSPEC_FSCALE_FRACT)) 17085 (set (match_dup 6) 17086 (unspec:XF [(match_dup 3) (match_dup 4)] 17087 UNSPEC_FSCALE_EXP))]) 17088 (set (match_operand:DF 0 "register_operand" "") 17089 (float_truncate:DF (match_dup 5)))] 17090 "TARGET_USE_FANCY_MATH_387 17091 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17092 && flag_unsafe_math_optimizations" 17093{ 17094 int i; 17095 17096 for (i=3; i<7; i++) 17097 operands[i] = gen_reg_rtx (XFmode); 17098}) 17099 17100(define_expand "ldexpsf3" 17101 [(set (match_dup 3) 17102 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 17103 (set (match_dup 4) 17104 (float:XF (match_operand:SI 2 "register_operand" ""))) 17105 (parallel [(set (match_dup 5) 17106 (unspec:XF [(match_dup 3) (match_dup 4)] 17107 UNSPEC_FSCALE_FRACT)) 17108 (set (match_dup 6) 17109 (unspec:XF [(match_dup 3) (match_dup 4)] 17110 UNSPEC_FSCALE_EXP))]) 17111 (set (match_operand:SF 0 "register_operand" "") 17112 (float_truncate:SF (match_dup 5)))] 17113 "TARGET_USE_FANCY_MATH_387 17114 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17115 && flag_unsafe_math_optimizations" 17116{ 17117 int i; 17118 17119 for (i=3; i<7; i++) 17120 operands[i] = gen_reg_rtx (XFmode); 17121}) 17122 17123(define_expand "ldexpxf3" 17124 [(set (match_dup 3) 17125 (float:XF (match_operand:SI 2 "register_operand" ""))) 17126 (parallel [(set (match_operand:XF 0 " register_operand" "") 17127 (unspec:XF [(match_operand:XF 1 "register_operand" "") 17128 (match_dup 3)] 17129 UNSPEC_FSCALE_FRACT)) 17130 (set (match_dup 4) 17131 (unspec:XF [(match_dup 1) (match_dup 3)] 17132 UNSPEC_FSCALE_EXP))])] 17133 "TARGET_USE_FANCY_MATH_387 17134 && flag_unsafe_math_optimizations" 17135{ 17136 int i; 17137 17138 for (i=3; i<5; i++) 17139 operands[i] = gen_reg_rtx (XFmode); 17140}) 17141 17142 17143(define_insn "frndintxf2" 17144 [(set (match_operand:XF 0 "register_operand" "=f") 17145 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17146 UNSPEC_FRNDINT))] 17147 "TARGET_USE_FANCY_MATH_387 17148 && flag_unsafe_math_optimizations" 17149 "frndint" 17150 [(set_attr "type" "fpspc") 17151 (set_attr "mode" "XF")]) 17152 17153(define_expand "rintdf2" 17154 [(use (match_operand:DF 0 "register_operand" "")) 17155 (use (match_operand:DF 1 "register_operand" ""))] 17156 "TARGET_USE_FANCY_MATH_387 17157 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17158 && flag_unsafe_math_optimizations" 17159{ 17160 rtx op0 = gen_reg_rtx (XFmode); 17161 rtx op1 = gen_reg_rtx (XFmode); 17162 17163 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17164 emit_insn (gen_frndintxf2 (op0, op1)); 17165 17166 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17167 DONE; 17168}) 17169 17170(define_expand "rintsf2" 17171 [(use (match_operand:SF 0 "register_operand" "")) 17172 (use (match_operand:SF 1 "register_operand" ""))] 17173 "TARGET_USE_FANCY_MATH_387 17174 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17175 && flag_unsafe_math_optimizations" 17176{ 17177 rtx op0 = gen_reg_rtx (XFmode); 17178 rtx op1 = gen_reg_rtx (XFmode); 17179 17180 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17181 emit_insn (gen_frndintxf2 (op0, op1)); 17182 17183 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17184 DONE; 17185}) 17186 17187(define_expand "rintxf2" 17188 [(use (match_operand:XF 0 "register_operand" "")) 17189 (use (match_operand:XF 1 "register_operand" ""))] 17190 "TARGET_USE_FANCY_MATH_387 17191 && flag_unsafe_math_optimizations" 17192{ 17193 emit_insn (gen_frndintxf2 (operands[0], operands[1])); 17194 DONE; 17195}) 17196 17197(define_insn_and_split "*fistdi2_1" 17198 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17199 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17200 UNSPEC_FIST))] 17201 "TARGET_USE_FANCY_MATH_387 17202 && flag_unsafe_math_optimizations 17203 && !(reload_completed || reload_in_progress)" 17204 "#" 17205 "&& 1" 17206 [(const_int 0)] 17207{ 17208 if (memory_operand (operands[0], VOIDmode)) 17209 emit_insn (gen_fistdi2 (operands[0], operands[1])); 17210 else 17211 { 17212 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP); 17213 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1], 17214 operands[2])); 17215 } 17216 DONE; 17217} 17218 [(set_attr "type" "fpspc") 17219 (set_attr "mode" "DI")]) 17220 17221(define_insn "fistdi2" 17222 [(set (match_operand:DI 0 "memory_operand" "=m") 17223 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 17224 UNSPEC_FIST)) 17225 (clobber (match_scratch:XF 2 "=&1f"))] 17226 "TARGET_USE_FANCY_MATH_387 17227 && flag_unsafe_math_optimizations" 17228 "* return output_fix_trunc (insn, operands, 0);" 17229 [(set_attr "type" "fpspc") 17230 (set_attr "mode" "DI")]) 17231 17232(define_insn "fistdi2_with_temp" 17233 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17234 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17235 UNSPEC_FIST)) 17236 (clobber (match_operand:DI 2 "memory_operand" "=m,m")) 17237 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 17238 "TARGET_USE_FANCY_MATH_387 17239 && flag_unsafe_math_optimizations" 17240 "#" 17241 [(set_attr "type" "fpspc") 17242 (set_attr "mode" "DI")]) 17243 17244(define_split 17245 [(set (match_operand:DI 0 "register_operand" "") 17246 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17247 UNSPEC_FIST)) 17248 (clobber (match_operand:DI 2 "memory_operand" "")) 17249 (clobber (match_scratch 3 ""))] 17250 "reload_completed" 17251 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 17252 (clobber (match_dup 3))]) 17253 (set (match_dup 0) (match_dup 2))] 17254 "") 17255 17256(define_split 17257 [(set (match_operand:DI 0 "memory_operand" "") 17258 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17259 UNSPEC_FIST)) 17260 (clobber (match_operand:DI 2 "memory_operand" "")) 17261 (clobber (match_scratch 3 ""))] 17262 "reload_completed" 17263 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 17264 (clobber (match_dup 3))])] 17265 "") 17266 17267(define_insn_and_split "*fist<mode>2_1" 17268 [(set (match_operand:X87MODEI12 0 "register_operand" "=r") 17269 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17270 UNSPEC_FIST))] 17271 "TARGET_USE_FANCY_MATH_387 17272 && flag_unsafe_math_optimizations 17273 && !(reload_completed || reload_in_progress)" 17274 "#" 17275 "&& 1" 17276 [(const_int 0)] 17277{ 17278 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17279 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1], 17280 operands[2])); 17281 DONE; 17282} 17283 [(set_attr "type" "fpspc") 17284 (set_attr "mode" "<MODE>")]) 17285 17286(define_insn "fist<mode>2" 17287 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 17288 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17289 UNSPEC_FIST))] 17290 "TARGET_USE_FANCY_MATH_387 17291 && flag_unsafe_math_optimizations" 17292 "* return output_fix_trunc (insn, operands, 0);" 17293 [(set_attr "type" "fpspc") 17294 (set_attr "mode" "<MODE>")]) 17295 17296(define_insn "fist<mode>2_with_temp" 17297 [(set (match_operand:X87MODEI12 0 "register_operand" "=r") 17298 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17299 UNSPEC_FIST)) 17300 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))] 17301 "TARGET_USE_FANCY_MATH_387 17302 && flag_unsafe_math_optimizations" 17303 "#" 17304 [(set_attr "type" "fpspc") 17305 (set_attr "mode" "<MODE>")]) 17306 17307(define_split 17308 [(set (match_operand:X87MODEI12 0 "register_operand" "") 17309 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17310 UNSPEC_FIST)) 17311 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))] 17312 "reload_completed" 17313 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] 17314 UNSPEC_FIST)) 17315 (set (match_dup 0) (match_dup 2))] 17316 "") 17317 17318(define_split 17319 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 17320 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17321 UNSPEC_FIST)) 17322 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))] 17323 "reload_completed" 17324 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] 17325 UNSPEC_FIST))] 17326 "") 17327 17328(define_expand "lrint<mode>2" 17329 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") 17330 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] 17331 UNSPEC_FIST))] 17332 "TARGET_USE_FANCY_MATH_387 17333 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17334 && flag_unsafe_math_optimizations" 17335 "") 17336 17337;; Rounding mode control word calculation could clobber FLAGS_REG. 17338(define_insn_and_split "frndintxf2_floor" 17339 [(set (match_operand:XF 0 "register_operand" "=f") 17340 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17341 UNSPEC_FRNDINT_FLOOR)) 17342 (clobber (reg:CC FLAGS_REG))] 17343 "TARGET_USE_FANCY_MATH_387 17344 && flag_unsafe_math_optimizations 17345 && !(reload_completed || reload_in_progress)" 17346 "#" 17347 "&& 1" 17348 [(const_int 0)] 17349{ 17350 ix86_optimize_mode_switching[I387_FLOOR] = 1; 17351 17352 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17353 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); 17354 17355 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1], 17356 operands[2], operands[3])); 17357 DONE; 17358} 17359 [(set_attr "type" "frndint") 17360 (set_attr "i387_cw" "floor") 17361 (set_attr "mode" "XF")]) 17362 17363(define_insn "frndintxf2_floor_i387" 17364 [(set (match_operand:XF 0 "register_operand" "=f") 17365 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17366 UNSPEC_FRNDINT_FLOOR)) 17367 (use (match_operand:HI 2 "memory_operand" "m")) 17368 (use (match_operand:HI 3 "memory_operand" "m"))] 17369 "TARGET_USE_FANCY_MATH_387 17370 && flag_unsafe_math_optimizations" 17371 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 17372 [(set_attr "type" "frndint") 17373 (set_attr "i387_cw" "floor") 17374 (set_attr "mode" "XF")]) 17375 17376(define_expand "floorxf2" 17377 [(use (match_operand:XF 0 "register_operand" "")) 17378 (use (match_operand:XF 1 "register_operand" ""))] 17379 "TARGET_USE_FANCY_MATH_387 17380 && flag_unsafe_math_optimizations" 17381{ 17382 emit_insn (gen_frndintxf2_floor (operands[0], operands[1])); 17383 DONE; 17384}) 17385 17386(define_expand "floordf2" 17387 [(use (match_operand:DF 0 "register_operand" "")) 17388 (use (match_operand:DF 1 "register_operand" ""))] 17389 "TARGET_USE_FANCY_MATH_387 17390 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17391 && flag_unsafe_math_optimizations" 17392{ 17393 rtx op0 = gen_reg_rtx (XFmode); 17394 rtx op1 = gen_reg_rtx (XFmode); 17395 17396 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17397 emit_insn (gen_frndintxf2_floor (op0, op1)); 17398 17399 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17400 DONE; 17401}) 17402 17403(define_expand "floorsf2" 17404 [(use (match_operand:SF 0 "register_operand" "")) 17405 (use (match_operand:SF 1 "register_operand" ""))] 17406 "TARGET_USE_FANCY_MATH_387 17407 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17408 && flag_unsafe_math_optimizations" 17409{ 17410 rtx op0 = gen_reg_rtx (XFmode); 17411 rtx op1 = gen_reg_rtx (XFmode); 17412 17413 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17414 emit_insn (gen_frndintxf2_floor (op0, op1)); 17415 17416 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17417 DONE; 17418}) 17419 17420(define_insn_and_split "*fist<mode>2_floor_1" 17421 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 17422 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")] 17423 UNSPEC_FIST_FLOOR)) 17424 (clobber (reg:CC FLAGS_REG))] 17425 "TARGET_USE_FANCY_MATH_387 17426 && flag_unsafe_math_optimizations 17427 && !(reload_completed || reload_in_progress)" 17428 "#" 17429 "&& 1" 17430 [(const_int 0)] 17431{ 17432 ix86_optimize_mode_switching[I387_FLOOR] = 1; 17433 17434 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17435 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); 17436 if (memory_operand (operands[0], VOIDmode)) 17437 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1], 17438 operands[2], operands[3])); 17439 else 17440 { 17441 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17442 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1], 17443 operands[2], operands[3], 17444 operands[4])); 17445 } 17446 DONE; 17447} 17448 [(set_attr "type" "fistp") 17449 (set_attr "i387_cw" "floor") 17450 (set_attr "mode" "<MODE>")]) 17451 17452(define_insn "fistdi2_floor" 17453 [(set (match_operand:DI 0 "memory_operand" "=m") 17454 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 17455 UNSPEC_FIST_FLOOR)) 17456 (use (match_operand:HI 2 "memory_operand" "m")) 17457 (use (match_operand:HI 3 "memory_operand" "m")) 17458 (clobber (match_scratch:XF 4 "=&1f"))] 17459 "TARGET_USE_FANCY_MATH_387 17460 && flag_unsafe_math_optimizations" 17461 "* return output_fix_trunc (insn, operands, 0);" 17462 [(set_attr "type" "fistp") 17463 (set_attr "i387_cw" "floor") 17464 (set_attr "mode" "DI")]) 17465 17466(define_insn "fistdi2_floor_with_temp" 17467 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17468 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17469 UNSPEC_FIST_FLOOR)) 17470 (use (match_operand:HI 2 "memory_operand" "m,m")) 17471 (use (match_operand:HI 3 "memory_operand" "m,m")) 17472 (clobber (match_operand:DI 4 "memory_operand" "=m,m")) 17473 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 17474 "TARGET_USE_FANCY_MATH_387 17475 && flag_unsafe_math_optimizations" 17476 "#" 17477 [(set_attr "type" "fistp") 17478 (set_attr "i387_cw" "floor") 17479 (set_attr "mode" "DI")]) 17480 17481(define_split 17482 [(set (match_operand:DI 0 "register_operand" "") 17483 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17484 UNSPEC_FIST_FLOOR)) 17485 (use (match_operand:HI 2 "memory_operand" "")) 17486 (use (match_operand:HI 3 "memory_operand" "")) 17487 (clobber (match_operand:DI 4 "memory_operand" "")) 17488 (clobber (match_scratch 5 ""))] 17489 "reload_completed" 17490 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) 17491 (use (match_dup 2)) 17492 (use (match_dup 3)) 17493 (clobber (match_dup 5))]) 17494 (set (match_dup 0) (match_dup 4))] 17495 "") 17496 17497(define_split 17498 [(set (match_operand:DI 0 "memory_operand" "") 17499 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17500 UNSPEC_FIST_FLOOR)) 17501 (use (match_operand:HI 2 "memory_operand" "")) 17502 (use (match_operand:HI 3 "memory_operand" "")) 17503 (clobber (match_operand:DI 4 "memory_operand" "")) 17504 (clobber (match_scratch 5 ""))] 17505 "reload_completed" 17506 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) 17507 (use (match_dup 2)) 17508 (use (match_dup 3)) 17509 (clobber (match_dup 5))])] 17510 "") 17511 17512(define_insn "fist<mode>2_floor" 17513 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 17514 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17515 UNSPEC_FIST_FLOOR)) 17516 (use (match_operand:HI 2 "memory_operand" "m")) 17517 (use (match_operand:HI 3 "memory_operand" "m"))] 17518 "TARGET_USE_FANCY_MATH_387 17519 && flag_unsafe_math_optimizations" 17520 "* return output_fix_trunc (insn, operands, 0);" 17521 [(set_attr "type" "fistp") 17522 (set_attr "i387_cw" "floor") 17523 (set_attr "mode" "<MODE>")]) 17524 17525(define_insn "fist<mode>2_floor_with_temp" 17526 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") 17527 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")] 17528 UNSPEC_FIST_FLOOR)) 17529 (use (match_operand:HI 2 "memory_operand" "m,m")) 17530 (use (match_operand:HI 3 "memory_operand" "m,m")) 17531 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))] 17532 "TARGET_USE_FANCY_MATH_387 17533 && flag_unsafe_math_optimizations" 17534 "#" 17535 [(set_attr "type" "fistp") 17536 (set_attr "i387_cw" "floor") 17537 (set_attr "mode" "<MODE>")]) 17538 17539(define_split 17540 [(set (match_operand:X87MODEI12 0 "register_operand" "") 17541 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17542 UNSPEC_FIST_FLOOR)) 17543 (use (match_operand:HI 2 "memory_operand" "")) 17544 (use (match_operand:HI 3 "memory_operand" "")) 17545 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 17546 "reload_completed" 17547 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)] 17548 UNSPEC_FIST_FLOOR)) 17549 (use (match_dup 2)) 17550 (use (match_dup 3))]) 17551 (set (match_dup 0) (match_dup 4))] 17552 "") 17553 17554(define_split 17555 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 17556 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17557 UNSPEC_FIST_FLOOR)) 17558 (use (match_operand:HI 2 "memory_operand" "")) 17559 (use (match_operand:HI 3 "memory_operand" "")) 17560 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 17561 "reload_completed" 17562 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] 17563 UNSPEC_FIST_FLOOR)) 17564 (use (match_dup 2)) 17565 (use (match_dup 3))])] 17566 "") 17567 17568(define_expand "lfloor<mode>2" 17569 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") 17570 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] 17571 UNSPEC_FIST_FLOOR)) 17572 (clobber (reg:CC FLAGS_REG))])] 17573 "TARGET_USE_FANCY_MATH_387 17574 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17575 && flag_unsafe_math_optimizations" 17576 "") 17577 17578;; Rounding mode control word calculation could clobber FLAGS_REG. 17579(define_insn_and_split "frndintxf2_ceil" 17580 [(set (match_operand:XF 0 "register_operand" "=f") 17581 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17582 UNSPEC_FRNDINT_CEIL)) 17583 (clobber (reg:CC FLAGS_REG))] 17584 "TARGET_USE_FANCY_MATH_387 17585 && flag_unsafe_math_optimizations 17586 && !(reload_completed || reload_in_progress)" 17587 "#" 17588 "&& 1" 17589 [(const_int 0)] 17590{ 17591 ix86_optimize_mode_switching[I387_CEIL] = 1; 17592 17593 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17594 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); 17595 17596 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1], 17597 operands[2], operands[3])); 17598 DONE; 17599} 17600 [(set_attr "type" "frndint") 17601 (set_attr "i387_cw" "ceil") 17602 (set_attr "mode" "XF")]) 17603 17604(define_insn "frndintxf2_ceil_i387" 17605 [(set (match_operand:XF 0 "register_operand" "=f") 17606 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17607 UNSPEC_FRNDINT_CEIL)) 17608 (use (match_operand:HI 2 "memory_operand" "m")) 17609 (use (match_operand:HI 3 "memory_operand" "m"))] 17610 "TARGET_USE_FANCY_MATH_387 17611 && flag_unsafe_math_optimizations" 17612 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 17613 [(set_attr "type" "frndint") 17614 (set_attr "i387_cw" "ceil") 17615 (set_attr "mode" "XF")]) 17616 17617(define_expand "ceilxf2" 17618 [(use (match_operand:XF 0 "register_operand" "")) 17619 (use (match_operand:XF 1 "register_operand" ""))] 17620 "TARGET_USE_FANCY_MATH_387 17621 && flag_unsafe_math_optimizations" 17622{ 17623 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1])); 17624 DONE; 17625}) 17626 17627(define_expand "ceildf2" 17628 [(use (match_operand:DF 0 "register_operand" "")) 17629 (use (match_operand:DF 1 "register_operand" ""))] 17630 "TARGET_USE_FANCY_MATH_387 17631 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17632 && flag_unsafe_math_optimizations" 17633{ 17634 rtx op0 = gen_reg_rtx (XFmode); 17635 rtx op1 = gen_reg_rtx (XFmode); 17636 17637 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17638 emit_insn (gen_frndintxf2_ceil (op0, op1)); 17639 17640 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17641 DONE; 17642}) 17643 17644(define_expand "ceilsf2" 17645 [(use (match_operand:SF 0 "register_operand" "")) 17646 (use (match_operand:SF 1 "register_operand" ""))] 17647 "TARGET_USE_FANCY_MATH_387 17648 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17649 && flag_unsafe_math_optimizations" 17650{ 17651 rtx op0 = gen_reg_rtx (XFmode); 17652 rtx op1 = gen_reg_rtx (XFmode); 17653 17654 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17655 emit_insn (gen_frndintxf2_ceil (op0, op1)); 17656 17657 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17658 DONE; 17659}) 17660 17661(define_insn_and_split "*fist<mode>2_ceil_1" 17662 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r") 17663 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")] 17664 UNSPEC_FIST_CEIL)) 17665 (clobber (reg:CC FLAGS_REG))] 17666 "TARGET_USE_FANCY_MATH_387 17667 && flag_unsafe_math_optimizations 17668 && !(reload_completed || reload_in_progress)" 17669 "#" 17670 "&& 1" 17671 [(const_int 0)] 17672{ 17673 ix86_optimize_mode_switching[I387_CEIL] = 1; 17674 17675 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17676 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); 17677 if (memory_operand (operands[0], VOIDmode)) 17678 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1], 17679 operands[2], operands[3])); 17680 else 17681 { 17682 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17683 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1], 17684 operands[2], operands[3], 17685 operands[4])); 17686 } 17687 DONE; 17688} 17689 [(set_attr "type" "fistp") 17690 (set_attr "i387_cw" "ceil") 17691 (set_attr "mode" "<MODE>")]) 17692 17693(define_insn "fistdi2_ceil" 17694 [(set (match_operand:DI 0 "memory_operand" "=m") 17695 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 17696 UNSPEC_FIST_CEIL)) 17697 (use (match_operand:HI 2 "memory_operand" "m")) 17698 (use (match_operand:HI 3 "memory_operand" "m")) 17699 (clobber (match_scratch:XF 4 "=&1f"))] 17700 "TARGET_USE_FANCY_MATH_387 17701 && flag_unsafe_math_optimizations" 17702 "* return output_fix_trunc (insn, operands, 0);" 17703 [(set_attr "type" "fistp") 17704 (set_attr "i387_cw" "ceil") 17705 (set_attr "mode" "DI")]) 17706 17707(define_insn "fistdi2_ceil_with_temp" 17708 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 17709 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 17710 UNSPEC_FIST_CEIL)) 17711 (use (match_operand:HI 2 "memory_operand" "m,m")) 17712 (use (match_operand:HI 3 "memory_operand" "m,m")) 17713 (clobber (match_operand:DI 4 "memory_operand" "=m,m")) 17714 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 17715 "TARGET_USE_FANCY_MATH_387 17716 && flag_unsafe_math_optimizations" 17717 "#" 17718 [(set_attr "type" "fistp") 17719 (set_attr "i387_cw" "ceil") 17720 (set_attr "mode" "DI")]) 17721 17722(define_split 17723 [(set (match_operand:DI 0 "register_operand" "") 17724 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17725 UNSPEC_FIST_CEIL)) 17726 (use (match_operand:HI 2 "memory_operand" "")) 17727 (use (match_operand:HI 3 "memory_operand" "")) 17728 (clobber (match_operand:DI 4 "memory_operand" "")) 17729 (clobber (match_scratch 5 ""))] 17730 "reload_completed" 17731 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) 17732 (use (match_dup 2)) 17733 (use (match_dup 3)) 17734 (clobber (match_dup 5))]) 17735 (set (match_dup 0) (match_dup 4))] 17736 "") 17737 17738(define_split 17739 [(set (match_operand:DI 0 "memory_operand" "") 17740 (unspec:DI [(match_operand:XF 1 "register_operand" "")] 17741 UNSPEC_FIST_CEIL)) 17742 (use (match_operand:HI 2 "memory_operand" "")) 17743 (use (match_operand:HI 3 "memory_operand" "")) 17744 (clobber (match_operand:DI 4 "memory_operand" "")) 17745 (clobber (match_scratch 5 ""))] 17746 "reload_completed" 17747 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) 17748 (use (match_dup 2)) 17749 (use (match_dup 3)) 17750 (clobber (match_dup 5))])] 17751 "") 17752 17753(define_insn "fist<mode>2_ceil" 17754 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m") 17755 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")] 17756 UNSPEC_FIST_CEIL)) 17757 (use (match_operand:HI 2 "memory_operand" "m")) 17758 (use (match_operand:HI 3 "memory_operand" "m"))] 17759 "TARGET_USE_FANCY_MATH_387 17760 && flag_unsafe_math_optimizations" 17761 "* return output_fix_trunc (insn, operands, 0);" 17762 [(set_attr "type" "fistp") 17763 (set_attr "i387_cw" "ceil") 17764 (set_attr "mode" "<MODE>")]) 17765 17766(define_insn "fist<mode>2_ceil_with_temp" 17767 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r") 17768 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")] 17769 UNSPEC_FIST_CEIL)) 17770 (use (match_operand:HI 2 "memory_operand" "m,m")) 17771 (use (match_operand:HI 3 "memory_operand" "m,m")) 17772 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))] 17773 "TARGET_USE_FANCY_MATH_387 17774 && flag_unsafe_math_optimizations" 17775 "#" 17776 [(set_attr "type" "fistp") 17777 (set_attr "i387_cw" "ceil") 17778 (set_attr "mode" "<MODE>")]) 17779 17780(define_split 17781 [(set (match_operand:X87MODEI12 0 "register_operand" "") 17782 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17783 UNSPEC_FIST_CEIL)) 17784 (use (match_operand:HI 2 "memory_operand" "")) 17785 (use (match_operand:HI 3 "memory_operand" "")) 17786 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 17787 "reload_completed" 17788 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)] 17789 UNSPEC_FIST_CEIL)) 17790 (use (match_dup 2)) 17791 (use (match_dup 3))]) 17792 (set (match_dup 0) (match_dup 4))] 17793 "") 17794 17795(define_split 17796 [(set (match_operand:X87MODEI12 0 "memory_operand" "") 17797 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")] 17798 UNSPEC_FIST_CEIL)) 17799 (use (match_operand:HI 2 "memory_operand" "")) 17800 (use (match_operand:HI 3 "memory_operand" "")) 17801 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))] 17802 "reload_completed" 17803 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] 17804 UNSPEC_FIST_CEIL)) 17805 (use (match_dup 2)) 17806 (use (match_dup 3))])] 17807 "") 17808 17809(define_expand "lceil<mode>2" 17810 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "") 17811 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")] 17812 UNSPEC_FIST_CEIL)) 17813 (clobber (reg:CC FLAGS_REG))])] 17814 "TARGET_USE_FANCY_MATH_387 17815 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17816 && flag_unsafe_math_optimizations" 17817 "") 17818 17819;; Rounding mode control word calculation could clobber FLAGS_REG. 17820(define_insn_and_split "frndintxf2_trunc" 17821 [(set (match_operand:XF 0 "register_operand" "=f") 17822 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17823 UNSPEC_FRNDINT_TRUNC)) 17824 (clobber (reg:CC FLAGS_REG))] 17825 "TARGET_USE_FANCY_MATH_387 17826 && flag_unsafe_math_optimizations 17827 && !(reload_completed || reload_in_progress)" 17828 "#" 17829 "&& 1" 17830 [(const_int 0)] 17831{ 17832 ix86_optimize_mode_switching[I387_TRUNC] = 1; 17833 17834 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17835 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 17836 17837 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1], 17838 operands[2], operands[3])); 17839 DONE; 17840} 17841 [(set_attr "type" "frndint") 17842 (set_attr "i387_cw" "trunc") 17843 (set_attr "mode" "XF")]) 17844 17845(define_insn "frndintxf2_trunc_i387" 17846 [(set (match_operand:XF 0 "register_operand" "=f") 17847 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17848 UNSPEC_FRNDINT_TRUNC)) 17849 (use (match_operand:HI 2 "memory_operand" "m")) 17850 (use (match_operand:HI 3 "memory_operand" "m"))] 17851 "TARGET_USE_FANCY_MATH_387 17852 && flag_unsafe_math_optimizations" 17853 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 17854 [(set_attr "type" "frndint") 17855 (set_attr "i387_cw" "trunc") 17856 (set_attr "mode" "XF")]) 17857 17858(define_expand "btruncxf2" 17859 [(use (match_operand:XF 0 "register_operand" "")) 17860 (use (match_operand:XF 1 "register_operand" ""))] 17861 "TARGET_USE_FANCY_MATH_387 17862 && flag_unsafe_math_optimizations" 17863{ 17864 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1])); 17865 DONE; 17866}) 17867 17868(define_expand "btruncdf2" 17869 [(use (match_operand:DF 0 "register_operand" "")) 17870 (use (match_operand:DF 1 "register_operand" ""))] 17871 "TARGET_USE_FANCY_MATH_387 17872 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17873 && flag_unsafe_math_optimizations" 17874{ 17875 rtx op0 = gen_reg_rtx (XFmode); 17876 rtx op1 = gen_reg_rtx (XFmode); 17877 17878 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17879 emit_insn (gen_frndintxf2_trunc (op0, op1)); 17880 17881 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17882 DONE; 17883}) 17884 17885(define_expand "btruncsf2" 17886 [(use (match_operand:SF 0 "register_operand" "")) 17887 (use (match_operand:SF 1 "register_operand" ""))] 17888 "TARGET_USE_FANCY_MATH_387 17889 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17890 && flag_unsafe_math_optimizations" 17891{ 17892 rtx op0 = gen_reg_rtx (XFmode); 17893 rtx op1 = gen_reg_rtx (XFmode); 17894 17895 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17896 emit_insn (gen_frndintxf2_trunc (op0, op1)); 17897 17898 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17899 DONE; 17900}) 17901 17902;; Rounding mode control word calculation could clobber FLAGS_REG. 17903(define_insn_and_split "frndintxf2_mask_pm" 17904 [(set (match_operand:XF 0 "register_operand" "=f") 17905 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17906 UNSPEC_FRNDINT_MASK_PM)) 17907 (clobber (reg:CC FLAGS_REG))] 17908 "TARGET_USE_FANCY_MATH_387 17909 && flag_unsafe_math_optimizations 17910 && !(reload_completed || reload_in_progress)" 17911 "#" 17912 "&& 1" 17913 [(const_int 0)] 17914{ 17915 ix86_optimize_mode_switching[I387_MASK_PM] = 1; 17916 17917 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17918 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM); 17919 17920 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1], 17921 operands[2], operands[3])); 17922 DONE; 17923} 17924 [(set_attr "type" "frndint") 17925 (set_attr "i387_cw" "mask_pm") 17926 (set_attr "mode" "XF")]) 17927 17928(define_insn "frndintxf2_mask_pm_i387" 17929 [(set (match_operand:XF 0 "register_operand" "=f") 17930 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 17931 UNSPEC_FRNDINT_MASK_PM)) 17932 (use (match_operand:HI 2 "memory_operand" "m")) 17933 (use (match_operand:HI 3 "memory_operand" "m"))] 17934 "TARGET_USE_FANCY_MATH_387 17935 && flag_unsafe_math_optimizations" 17936 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2" 17937 [(set_attr "type" "frndint") 17938 (set_attr "i387_cw" "mask_pm") 17939 (set_attr "mode" "XF")]) 17940 17941(define_expand "nearbyintxf2" 17942 [(use (match_operand:XF 0 "register_operand" "")) 17943 (use (match_operand:XF 1 "register_operand" ""))] 17944 "TARGET_USE_FANCY_MATH_387 17945 && flag_unsafe_math_optimizations" 17946{ 17947 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1])); 17948 17949 DONE; 17950}) 17951 17952(define_expand "nearbyintdf2" 17953 [(use (match_operand:DF 0 "register_operand" "")) 17954 (use (match_operand:DF 1 "register_operand" ""))] 17955 "TARGET_USE_FANCY_MATH_387 17956 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) 17957 && flag_unsafe_math_optimizations" 17958{ 17959 rtx op0 = gen_reg_rtx (XFmode); 17960 rtx op1 = gen_reg_rtx (XFmode); 17961 17962 emit_insn (gen_extenddfxf2 (op1, operands[1])); 17963 emit_insn (gen_frndintxf2_mask_pm (op0, op1)); 17964 17965 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0)); 17966 DONE; 17967}) 17968 17969(define_expand "nearbyintsf2" 17970 [(use (match_operand:SF 0 "register_operand" "")) 17971 (use (match_operand:SF 1 "register_operand" ""))] 17972 "TARGET_USE_FANCY_MATH_387 17973 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17974 && flag_unsafe_math_optimizations" 17975{ 17976 rtx op0 = gen_reg_rtx (XFmode); 17977 rtx op1 = gen_reg_rtx (XFmode); 17978 17979 emit_insn (gen_extendsfxf2 (op1, operands[1])); 17980 emit_insn (gen_frndintxf2_mask_pm (op0, op1)); 17981 17982 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0)); 17983 DONE; 17984}) 17985 17986 17987;; Block operation instructions 17988 17989(define_insn "cld" 17990 [(set (reg:SI DIRFLAG_REG) (const_int 0))] 17991 "" 17992 "cld" 17993 [(set_attr "type" "cld")]) 17994 17995(define_expand "movmemsi" 17996 [(use (match_operand:BLK 0 "memory_operand" "")) 17997 (use (match_operand:BLK 1 "memory_operand" "")) 17998 (use (match_operand:SI 2 "nonmemory_operand" "")) 17999 (use (match_operand:SI 3 "const_int_operand" ""))] 18000 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS" 18001{ 18002 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3])) 18003 DONE; 18004 else 18005 FAIL; 18006}) 18007 18008(define_expand "movmemdi" 18009 [(use (match_operand:BLK 0 "memory_operand" "")) 18010 (use (match_operand:BLK 1 "memory_operand" "")) 18011 (use (match_operand:DI 2 "nonmemory_operand" "")) 18012 (use (match_operand:DI 3 "const_int_operand" ""))] 18013 "TARGET_64BIT" 18014{ 18015 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3])) 18016 DONE; 18017 else 18018 FAIL; 18019}) 18020 18021;; Most CPUs don't like single string operations 18022;; Handle this case here to simplify previous expander. 18023 18024(define_expand "strmov" 18025 [(set (match_dup 4) (match_operand 3 "memory_operand" "")) 18026 (set (match_operand 1 "memory_operand" "") (match_dup 4)) 18027 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5)) 18028 (clobber (reg:CC FLAGS_REG))]) 18029 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6)) 18030 (clobber (reg:CC FLAGS_REG))])] 18031 "" 18032{ 18033 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1]))); 18034 18035 /* If .md ever supports :P for Pmode, these can be directly 18036 in the pattern above. */ 18037 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust); 18038 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust); 18039 18040 if (TARGET_SINGLE_STRINGOP || optimize_size) 18041 { 18042 emit_insn (gen_strmov_singleop (operands[0], operands[1], 18043 operands[2], operands[3], 18044 operands[5], operands[6])); 18045 DONE; 18046 } 18047 18048 operands[4] = gen_reg_rtx (GET_MODE (operands[1])); 18049}) 18050 18051(define_expand "strmov_singleop" 18052 [(parallel [(set (match_operand 1 "memory_operand" "") 18053 (match_operand 3 "memory_operand" "")) 18054 (set (match_operand 0 "register_operand" "") 18055 (match_operand 4 "" "")) 18056 (set (match_operand 2 "register_operand" "") 18057 (match_operand 5 "" "")) 18058 (use (reg:SI DIRFLAG_REG))])] 18059 "TARGET_SINGLE_STRINGOP || optimize_size" 18060 "") 18061 18062(define_insn "*strmovdi_rex_1" 18063 [(set (mem:DI (match_operand:DI 2 "register_operand" "0")) 18064 (mem:DI (match_operand:DI 3 "register_operand" "1"))) 18065 (set (match_operand:DI 0 "register_operand" "=D") 18066 (plus:DI (match_dup 2) 18067 (const_int 8))) 18068 (set (match_operand:DI 1 "register_operand" "=S") 18069 (plus:DI (match_dup 3) 18070 (const_int 8))) 18071 (use (reg:SI DIRFLAG_REG))] 18072 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18073 "movsq" 18074 [(set_attr "type" "str") 18075 (set_attr "mode" "DI") 18076 (set_attr "memory" "both")]) 18077 18078(define_insn "*strmovsi_1" 18079 [(set (mem:SI (match_operand:SI 2 "register_operand" "0")) 18080 (mem:SI (match_operand:SI 3 "register_operand" "1"))) 18081 (set (match_operand:SI 0 "register_operand" "=D") 18082 (plus:SI (match_dup 2) 18083 (const_int 4))) 18084 (set (match_operand:SI 1 "register_operand" "=S") 18085 (plus:SI (match_dup 3) 18086 (const_int 4))) 18087 (use (reg:SI DIRFLAG_REG))] 18088 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18089 "{movsl|movsd}" 18090 [(set_attr "type" "str") 18091 (set_attr "mode" "SI") 18092 (set_attr "memory" "both")]) 18093 18094(define_insn "*strmovsi_rex_1" 18095 [(set (mem:SI (match_operand:DI 2 "register_operand" "0")) 18096 (mem:SI (match_operand:DI 3 "register_operand" "1"))) 18097 (set (match_operand:DI 0 "register_operand" "=D") 18098 (plus:DI (match_dup 2) 18099 (const_int 4))) 18100 (set (match_operand:DI 1 "register_operand" "=S") 18101 (plus:DI (match_dup 3) 18102 (const_int 4))) 18103 (use (reg:SI DIRFLAG_REG))] 18104 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18105 "{movsl|movsd}" 18106 [(set_attr "type" "str") 18107 (set_attr "mode" "SI") 18108 (set_attr "memory" "both")]) 18109 18110(define_insn "*strmovhi_1" 18111 [(set (mem:HI (match_operand:SI 2 "register_operand" "0")) 18112 (mem:HI (match_operand:SI 3 "register_operand" "1"))) 18113 (set (match_operand:SI 0 "register_operand" "=D") 18114 (plus:SI (match_dup 2) 18115 (const_int 2))) 18116 (set (match_operand:SI 1 "register_operand" "=S") 18117 (plus:SI (match_dup 3) 18118 (const_int 2))) 18119 (use (reg:SI DIRFLAG_REG))] 18120 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18121 "movsw" 18122 [(set_attr "type" "str") 18123 (set_attr "memory" "both") 18124 (set_attr "mode" "HI")]) 18125 18126(define_insn "*strmovhi_rex_1" 18127 [(set (mem:HI (match_operand:DI 2 "register_operand" "0")) 18128 (mem:HI (match_operand:DI 3 "register_operand" "1"))) 18129 (set (match_operand:DI 0 "register_operand" "=D") 18130 (plus:DI (match_dup 2) 18131 (const_int 2))) 18132 (set (match_operand:DI 1 "register_operand" "=S") 18133 (plus:DI (match_dup 3) 18134 (const_int 2))) 18135 (use (reg:SI DIRFLAG_REG))] 18136 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18137 "movsw" 18138 [(set_attr "type" "str") 18139 (set_attr "memory" "both") 18140 (set_attr "mode" "HI")]) 18141 18142(define_insn "*strmovqi_1" 18143 [(set (mem:QI (match_operand:SI 2 "register_operand" "0")) 18144 (mem:QI (match_operand:SI 3 "register_operand" "1"))) 18145 (set (match_operand:SI 0 "register_operand" "=D") 18146 (plus:SI (match_dup 2) 18147 (const_int 1))) 18148 (set (match_operand:SI 1 "register_operand" "=S") 18149 (plus:SI (match_dup 3) 18150 (const_int 1))) 18151 (use (reg:SI DIRFLAG_REG))] 18152 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18153 "movsb" 18154 [(set_attr "type" "str") 18155 (set_attr "memory" "both") 18156 (set_attr "mode" "QI")]) 18157 18158(define_insn "*strmovqi_rex_1" 18159 [(set (mem:QI (match_operand:DI 2 "register_operand" "0")) 18160 (mem:QI (match_operand:DI 3 "register_operand" "1"))) 18161 (set (match_operand:DI 0 "register_operand" "=D") 18162 (plus:DI (match_dup 2) 18163 (const_int 1))) 18164 (set (match_operand:DI 1 "register_operand" "=S") 18165 (plus:DI (match_dup 3) 18166 (const_int 1))) 18167 (use (reg:SI DIRFLAG_REG))] 18168 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18169 "movsb" 18170 [(set_attr "type" "str") 18171 (set_attr "memory" "both") 18172 (set_attr "mode" "QI")]) 18173 18174(define_expand "rep_mov" 18175 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0)) 18176 (set (match_operand 0 "register_operand" "") 18177 (match_operand 5 "" "")) 18178 (set (match_operand 2 "register_operand" "") 18179 (match_operand 6 "" "")) 18180 (set (match_operand 1 "memory_operand" "") 18181 (match_operand 3 "memory_operand" "")) 18182 (use (match_dup 4)) 18183 (use (reg:SI DIRFLAG_REG))])] 18184 "" 18185 "") 18186 18187(define_insn "*rep_movdi_rex64" 18188 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) 18189 (set (match_operand:DI 0 "register_operand" "=D") 18190 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2") 18191 (const_int 3)) 18192 (match_operand:DI 3 "register_operand" "0"))) 18193 (set (match_operand:DI 1 "register_operand" "=S") 18194 (plus:DI (ashift:DI (match_dup 5) (const_int 3)) 18195 (match_operand:DI 4 "register_operand" "1"))) 18196 (set (mem:BLK (match_dup 3)) 18197 (mem:BLK (match_dup 4))) 18198 (use (match_dup 5)) 18199 (use (reg:SI DIRFLAG_REG))] 18200 "TARGET_64BIT" 18201 "{rep\;movsq|rep movsq}" 18202 [(set_attr "type" "str") 18203 (set_attr "prefix_rep" "1") 18204 (set_attr "memory" "both") 18205 (set_attr "mode" "DI")]) 18206 18207(define_insn "*rep_movsi" 18208 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0)) 18209 (set (match_operand:SI 0 "register_operand" "=D") 18210 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2") 18211 (const_int 2)) 18212 (match_operand:SI 3 "register_operand" "0"))) 18213 (set (match_operand:SI 1 "register_operand" "=S") 18214 (plus:SI (ashift:SI (match_dup 5) (const_int 2)) 18215 (match_operand:SI 4 "register_operand" "1"))) 18216 (set (mem:BLK (match_dup 3)) 18217 (mem:BLK (match_dup 4))) 18218 (use (match_dup 5)) 18219 (use (reg:SI DIRFLAG_REG))] 18220 "!TARGET_64BIT" 18221 "{rep\;movsl|rep movsd}" 18222 [(set_attr "type" "str") 18223 (set_attr "prefix_rep" "1") 18224 (set_attr "memory" "both") 18225 (set_attr "mode" "SI")]) 18226 18227(define_insn "*rep_movsi_rex64" 18228 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) 18229 (set (match_operand:DI 0 "register_operand" "=D") 18230 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2") 18231 (const_int 2)) 18232 (match_operand:DI 3 "register_operand" "0"))) 18233 (set (match_operand:DI 1 "register_operand" "=S") 18234 (plus:DI (ashift:DI (match_dup 5) (const_int 2)) 18235 (match_operand:DI 4 "register_operand" "1"))) 18236 (set (mem:BLK (match_dup 3)) 18237 (mem:BLK (match_dup 4))) 18238 (use (match_dup 5)) 18239 (use (reg:SI DIRFLAG_REG))] 18240 "TARGET_64BIT" 18241 "{rep\;movsl|rep movsd}" 18242 [(set_attr "type" "str") 18243 (set_attr "prefix_rep" "1") 18244 (set_attr "memory" "both") 18245 (set_attr "mode" "SI")]) 18246 18247(define_insn "*rep_movqi" 18248 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0)) 18249 (set (match_operand:SI 0 "register_operand" "=D") 18250 (plus:SI (match_operand:SI 3 "register_operand" "0") 18251 (match_operand:SI 5 "register_operand" "2"))) 18252 (set (match_operand:SI 1 "register_operand" "=S") 18253 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5))) 18254 (set (mem:BLK (match_dup 3)) 18255 (mem:BLK (match_dup 4))) 18256 (use (match_dup 5)) 18257 (use (reg:SI DIRFLAG_REG))] 18258 "!TARGET_64BIT" 18259 "{rep\;movsb|rep movsb}" 18260 [(set_attr "type" "str") 18261 (set_attr "prefix_rep" "1") 18262 (set_attr "memory" "both") 18263 (set_attr "mode" "SI")]) 18264 18265(define_insn "*rep_movqi_rex64" 18266 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) 18267 (set (match_operand:DI 0 "register_operand" "=D") 18268 (plus:DI (match_operand:DI 3 "register_operand" "0") 18269 (match_operand:DI 5 "register_operand" "2"))) 18270 (set (match_operand:DI 1 "register_operand" "=S") 18271 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5))) 18272 (set (mem:BLK (match_dup 3)) 18273 (mem:BLK (match_dup 4))) 18274 (use (match_dup 5)) 18275 (use (reg:SI DIRFLAG_REG))] 18276 "TARGET_64BIT" 18277 "{rep\;movsb|rep movsb}" 18278 [(set_attr "type" "str") 18279 (set_attr "prefix_rep" "1") 18280 (set_attr "memory" "both") 18281 (set_attr "mode" "SI")]) 18282 18283(define_expand "setmemsi" 18284 [(use (match_operand:BLK 0 "memory_operand" "")) 18285 (use (match_operand:SI 1 "nonmemory_operand" "")) 18286 (use (match_operand 2 "const_int_operand" "")) 18287 (use (match_operand 3 "const_int_operand" ""))] 18288 "" 18289{ 18290 /* If value to set is not zero, use the library routine. */ 18291 if (operands[2] != const0_rtx) 18292 FAIL; 18293 18294 if (ix86_expand_clrmem (operands[0], operands[1], operands[3])) 18295 DONE; 18296 else 18297 FAIL; 18298}) 18299 18300(define_expand "setmemdi" 18301 [(use (match_operand:BLK 0 "memory_operand" "")) 18302 (use (match_operand:DI 1 "nonmemory_operand" "")) 18303 (use (match_operand 2 "const_int_operand" "")) 18304 (use (match_operand 3 "const_int_operand" ""))] 18305 "TARGET_64BIT" 18306{ 18307 /* If value to set is not zero, use the library routine. */ 18308 if (operands[2] != const0_rtx) 18309 FAIL; 18310 18311 if (ix86_expand_clrmem (operands[0], operands[1], operands[3])) 18312 DONE; 18313 else 18314 FAIL; 18315}) 18316 18317;; Most CPUs don't like single string operations 18318;; Handle this case here to simplify previous expander. 18319 18320(define_expand "strset" 18321 [(set (match_operand 1 "memory_operand" "") 18322 (match_operand 2 "register_operand" "")) 18323 (parallel [(set (match_operand 0 "register_operand" "") 18324 (match_dup 3)) 18325 (clobber (reg:CC FLAGS_REG))])] 18326 "" 18327{ 18328 if (GET_MODE (operands[1]) != GET_MODE (operands[2])) 18329 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0); 18330 18331 /* If .md ever supports :P for Pmode, this can be directly 18332 in the pattern above. */ 18333 operands[3] = gen_rtx_PLUS (Pmode, operands[0], 18334 GEN_INT (GET_MODE_SIZE (GET_MODE 18335 (operands[2])))); 18336 if (TARGET_SINGLE_STRINGOP || optimize_size) 18337 { 18338 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2], 18339 operands[3])); 18340 DONE; 18341 } 18342}) 18343 18344(define_expand "strset_singleop" 18345 [(parallel [(set (match_operand 1 "memory_operand" "") 18346 (match_operand 2 "register_operand" "")) 18347 (set (match_operand 0 "register_operand" "") 18348 (match_operand 3 "" "")) 18349 (use (reg:SI DIRFLAG_REG))])] 18350 "TARGET_SINGLE_STRINGOP || optimize_size" 18351 "") 18352 18353(define_insn "*strsetdi_rex_1" 18354 [(set (mem:DI (match_operand:DI 1 "register_operand" "0")) 18355 (match_operand:DI 2 "register_operand" "a")) 18356 (set (match_operand:DI 0 "register_operand" "=D") 18357 (plus:DI (match_dup 1) 18358 (const_int 8))) 18359 (use (reg:SI DIRFLAG_REG))] 18360 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18361 "stosq" 18362 [(set_attr "type" "str") 18363 (set_attr "memory" "store") 18364 (set_attr "mode" "DI")]) 18365 18366(define_insn "*strsetsi_1" 18367 [(set (mem:SI (match_operand:SI 1 "register_operand" "0")) 18368 (match_operand:SI 2 "register_operand" "a")) 18369 (set (match_operand:SI 0 "register_operand" "=D") 18370 (plus:SI (match_dup 1) 18371 (const_int 4))) 18372 (use (reg:SI DIRFLAG_REG))] 18373 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18374 "{stosl|stosd}" 18375 [(set_attr "type" "str") 18376 (set_attr "memory" "store") 18377 (set_attr "mode" "SI")]) 18378 18379(define_insn "*strsetsi_rex_1" 18380 [(set (mem:SI (match_operand:DI 1 "register_operand" "0")) 18381 (match_operand:SI 2 "register_operand" "a")) 18382 (set (match_operand:DI 0 "register_operand" "=D") 18383 (plus:DI (match_dup 1) 18384 (const_int 4))) 18385 (use (reg:SI DIRFLAG_REG))] 18386 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18387 "{stosl|stosd}" 18388 [(set_attr "type" "str") 18389 (set_attr "memory" "store") 18390 (set_attr "mode" "SI")]) 18391 18392(define_insn "*strsethi_1" 18393 [(set (mem:HI (match_operand:SI 1 "register_operand" "0")) 18394 (match_operand:HI 2 "register_operand" "a")) 18395 (set (match_operand:SI 0 "register_operand" "=D") 18396 (plus:SI (match_dup 1) 18397 (const_int 2))) 18398 (use (reg:SI DIRFLAG_REG))] 18399 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18400 "stosw" 18401 [(set_attr "type" "str") 18402 (set_attr "memory" "store") 18403 (set_attr "mode" "HI")]) 18404 18405(define_insn "*strsethi_rex_1" 18406 [(set (mem:HI (match_operand:DI 1 "register_operand" "0")) 18407 (match_operand:HI 2 "register_operand" "a")) 18408 (set (match_operand:DI 0 "register_operand" "=D") 18409 (plus:DI (match_dup 1) 18410 (const_int 2))) 18411 (use (reg:SI DIRFLAG_REG))] 18412 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18413 "stosw" 18414 [(set_attr "type" "str") 18415 (set_attr "memory" "store") 18416 (set_attr "mode" "HI")]) 18417 18418(define_insn "*strsetqi_1" 18419 [(set (mem:QI (match_operand:SI 1 "register_operand" "0")) 18420 (match_operand:QI 2 "register_operand" "a")) 18421 (set (match_operand:SI 0 "register_operand" "=D") 18422 (plus:SI (match_dup 1) 18423 (const_int 1))) 18424 (use (reg:SI DIRFLAG_REG))] 18425 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18426 "stosb" 18427 [(set_attr "type" "str") 18428 (set_attr "memory" "store") 18429 (set_attr "mode" "QI")]) 18430 18431(define_insn "*strsetqi_rex_1" 18432 [(set (mem:QI (match_operand:DI 1 "register_operand" "0")) 18433 (match_operand:QI 2 "register_operand" "a")) 18434 (set (match_operand:DI 0 "register_operand" "=D") 18435 (plus:DI (match_dup 1) 18436 (const_int 1))) 18437 (use (reg:SI DIRFLAG_REG))] 18438 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)" 18439 "stosb" 18440 [(set_attr "type" "str") 18441 (set_attr "memory" "store") 18442 (set_attr "mode" "QI")]) 18443 18444(define_expand "rep_stos" 18445 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0)) 18446 (set (match_operand 0 "register_operand" "") 18447 (match_operand 4 "" "")) 18448 (set (match_operand 2 "memory_operand" "") (const_int 0)) 18449 (use (match_operand 3 "register_operand" "")) 18450 (use (match_dup 1)) 18451 (use (reg:SI DIRFLAG_REG))])] 18452 "" 18453 "") 18454 18455(define_insn "*rep_stosdi_rex64" 18456 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) 18457 (set (match_operand:DI 0 "register_operand" "=D") 18458 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1") 18459 (const_int 3)) 18460 (match_operand:DI 3 "register_operand" "0"))) 18461 (set (mem:BLK (match_dup 3)) 18462 (const_int 0)) 18463 (use (match_operand:DI 2 "register_operand" "a")) 18464 (use (match_dup 4)) 18465 (use (reg:SI DIRFLAG_REG))] 18466 "TARGET_64BIT" 18467 "{rep\;stosq|rep stosq}" 18468 [(set_attr "type" "str") 18469 (set_attr "prefix_rep" "1") 18470 (set_attr "memory" "store") 18471 (set_attr "mode" "DI")]) 18472 18473(define_insn "*rep_stossi" 18474 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0)) 18475 (set (match_operand:SI 0 "register_operand" "=D") 18476 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1") 18477 (const_int 2)) 18478 (match_operand:SI 3 "register_operand" "0"))) 18479 (set (mem:BLK (match_dup 3)) 18480 (const_int 0)) 18481 (use (match_operand:SI 2 "register_operand" "a")) 18482 (use (match_dup 4)) 18483 (use (reg:SI DIRFLAG_REG))] 18484 "!TARGET_64BIT" 18485 "{rep\;stosl|rep stosd}" 18486 [(set_attr "type" "str") 18487 (set_attr "prefix_rep" "1") 18488 (set_attr "memory" "store") 18489 (set_attr "mode" "SI")]) 18490 18491(define_insn "*rep_stossi_rex64" 18492 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) 18493 (set (match_operand:DI 0 "register_operand" "=D") 18494 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1") 18495 (const_int 2)) 18496 (match_operand:DI 3 "register_operand" "0"))) 18497 (set (mem:BLK (match_dup 3)) 18498 (const_int 0)) 18499 (use (match_operand:SI 2 "register_operand" "a")) 18500 (use (match_dup 4)) 18501 (use (reg:SI DIRFLAG_REG))] 18502 "TARGET_64BIT" 18503 "{rep\;stosl|rep stosd}" 18504 [(set_attr "type" "str") 18505 (set_attr "prefix_rep" "1") 18506 (set_attr "memory" "store") 18507 (set_attr "mode" "SI")]) 18508 18509(define_insn "*rep_stosqi" 18510 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0)) 18511 (set (match_operand:SI 0 "register_operand" "=D") 18512 (plus:SI (match_operand:SI 3 "register_operand" "0") 18513 (match_operand:SI 4 "register_operand" "1"))) 18514 (set (mem:BLK (match_dup 3)) 18515 (const_int 0)) 18516 (use (match_operand:QI 2 "register_operand" "a")) 18517 (use (match_dup 4)) 18518 (use (reg:SI DIRFLAG_REG))] 18519 "!TARGET_64BIT" 18520 "{rep\;stosb|rep stosb}" 18521 [(set_attr "type" "str") 18522 (set_attr "prefix_rep" "1") 18523 (set_attr "memory" "store") 18524 (set_attr "mode" "QI")]) 18525 18526(define_insn "*rep_stosqi_rex64" 18527 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) 18528 (set (match_operand:DI 0 "register_operand" "=D") 18529 (plus:DI (match_operand:DI 3 "register_operand" "0") 18530 (match_operand:DI 4 "register_operand" "1"))) 18531 (set (mem:BLK (match_dup 3)) 18532 (const_int 0)) 18533 (use (match_operand:QI 2 "register_operand" "a")) 18534 (use (match_dup 4)) 18535 (use (reg:SI DIRFLAG_REG))] 18536 "TARGET_64BIT" 18537 "{rep\;stosb|rep stosb}" 18538 [(set_attr "type" "str") 18539 (set_attr "prefix_rep" "1") 18540 (set_attr "memory" "store") 18541 (set_attr "mode" "QI")]) 18542 18543(define_expand "cmpstrnsi" 18544 [(set (match_operand:SI 0 "register_operand" "") 18545 (compare:SI (match_operand:BLK 1 "general_operand" "") 18546 (match_operand:BLK 2 "general_operand" ""))) 18547 (use (match_operand 3 "general_operand" "")) 18548 (use (match_operand 4 "immediate_operand" ""))] 18549 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS" 18550{ 18551 rtx addr1, addr2, out, outlow, count, countreg, align; 18552 18553 /* Can't use this if the user has appropriated esi or edi. */ 18554 if (global_regs[4] || global_regs[5]) 18555 FAIL; 18556 18557 out = operands[0]; 18558 if (GET_CODE (out) != REG) 18559 out = gen_reg_rtx (SImode); 18560 18561 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); 18562 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0)); 18563 if (addr1 != XEXP (operands[1], 0)) 18564 operands[1] = replace_equiv_address_nv (operands[1], addr1); 18565 if (addr2 != XEXP (operands[2], 0)) 18566 operands[2] = replace_equiv_address_nv (operands[2], addr2); 18567 18568 count = operands[3]; 18569 countreg = ix86_zero_extend_to_Pmode (count); 18570 18571 /* %%% Iff we are testing strict equality, we can use known alignment 18572 to good advantage. This may be possible with combine, particularly 18573 once cc0 is dead. */ 18574 align = operands[4]; 18575 18576 emit_insn (gen_cld ()); 18577 if (GET_CODE (count) == CONST_INT) 18578 { 18579 if (INTVAL (count) == 0) 18580 { 18581 emit_move_insn (operands[0], const0_rtx); 18582 DONE; 18583 } 18584 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align, 18585 operands[1], operands[2])); 18586 } 18587 else 18588 { 18589 if (TARGET_64BIT) 18590 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg)); 18591 else 18592 emit_insn (gen_cmpsi_1 (countreg, countreg)); 18593 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align, 18594 operands[1], operands[2])); 18595 } 18596 18597 outlow = gen_lowpart (QImode, out); 18598 emit_insn (gen_cmpintqi (outlow)); 18599 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow)); 18600 18601 if (operands[0] != out) 18602 emit_move_insn (operands[0], out); 18603 18604 DONE; 18605}) 18606 18607;; Produce a tri-state integer (-1, 0, 1) from condition codes. 18608 18609(define_expand "cmpintqi" 18610 [(set (match_dup 1) 18611 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 18612 (set (match_dup 2) 18613 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 18614 (parallel [(set (match_operand:QI 0 "register_operand" "") 18615 (minus:QI (match_dup 1) 18616 (match_dup 2))) 18617 (clobber (reg:CC FLAGS_REG))])] 18618 "" 18619 "operands[1] = gen_reg_rtx (QImode); 18620 operands[2] = gen_reg_rtx (QImode);") 18621 18622;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is 18623;; zero. Emit extra code to make sure that a zero-length compare is EQ. 18624 18625(define_expand "cmpstrnqi_nz_1" 18626 [(parallel [(set (reg:CC FLAGS_REG) 18627 (compare:CC (match_operand 4 "memory_operand" "") 18628 (match_operand 5 "memory_operand" ""))) 18629 (use (match_operand 2 "register_operand" "")) 18630 (use (match_operand:SI 3 "immediate_operand" "")) 18631 (use (reg:SI DIRFLAG_REG)) 18632 (clobber (match_operand 0 "register_operand" "")) 18633 (clobber (match_operand 1 "register_operand" "")) 18634 (clobber (match_dup 2))])] 18635 "" 18636 "") 18637 18638(define_insn "*cmpstrnqi_nz_1" 18639 [(set (reg:CC FLAGS_REG) 18640 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0")) 18641 (mem:BLK (match_operand:SI 5 "register_operand" "1")))) 18642 (use (match_operand:SI 6 "register_operand" "2")) 18643 (use (match_operand:SI 3 "immediate_operand" "i")) 18644 (use (reg:SI DIRFLAG_REG)) 18645 (clobber (match_operand:SI 0 "register_operand" "=S")) 18646 (clobber (match_operand:SI 1 "register_operand" "=D")) 18647 (clobber (match_operand:SI 2 "register_operand" "=c"))] 18648 "!TARGET_64BIT" 18649 "repz{\;| }cmpsb" 18650 [(set_attr "type" "str") 18651 (set_attr "mode" "QI") 18652 (set_attr "prefix_rep" "1")]) 18653 18654(define_insn "*cmpstrnqi_nz_rex_1" 18655 [(set (reg:CC FLAGS_REG) 18656 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0")) 18657 (mem:BLK (match_operand:DI 5 "register_operand" "1")))) 18658 (use (match_operand:DI 6 "register_operand" "2")) 18659 (use (match_operand:SI 3 "immediate_operand" "i")) 18660 (use (reg:SI DIRFLAG_REG)) 18661 (clobber (match_operand:DI 0 "register_operand" "=S")) 18662 (clobber (match_operand:DI 1 "register_operand" "=D")) 18663 (clobber (match_operand:DI 2 "register_operand" "=c"))] 18664 "TARGET_64BIT" 18665 "repz{\;| }cmpsb" 18666 [(set_attr "type" "str") 18667 (set_attr "mode" "QI") 18668 (set_attr "prefix_rep" "1")]) 18669 18670;; The same, but the count is not known to not be zero. 18671 18672(define_expand "cmpstrnqi_1" 18673 [(parallel [(set (reg:CC FLAGS_REG) 18674 (if_then_else:CC (ne (match_operand 2 "register_operand" "") 18675 (const_int 0)) 18676 (compare:CC (match_operand 4 "memory_operand" "") 18677 (match_operand 5 "memory_operand" "")) 18678 (const_int 0))) 18679 (use (match_operand:SI 3 "immediate_operand" "")) 18680 (use (reg:CC FLAGS_REG)) 18681 (use (reg:SI DIRFLAG_REG)) 18682 (clobber (match_operand 0 "register_operand" "")) 18683 (clobber (match_operand 1 "register_operand" "")) 18684 (clobber (match_dup 2))])] 18685 "" 18686 "") 18687 18688(define_insn "*cmpstrnqi_1" 18689 [(set (reg:CC FLAGS_REG) 18690 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2") 18691 (const_int 0)) 18692 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0")) 18693 (mem:BLK (match_operand:SI 5 "register_operand" "1"))) 18694 (const_int 0))) 18695 (use (match_operand:SI 3 "immediate_operand" "i")) 18696 (use (reg:CC FLAGS_REG)) 18697 (use (reg:SI DIRFLAG_REG)) 18698 (clobber (match_operand:SI 0 "register_operand" "=S")) 18699 (clobber (match_operand:SI 1 "register_operand" "=D")) 18700 (clobber (match_operand:SI 2 "register_operand" "=c"))] 18701 "!TARGET_64BIT" 18702 "repz{\;| }cmpsb" 18703 [(set_attr "type" "str") 18704 (set_attr "mode" "QI") 18705 (set_attr "prefix_rep" "1")]) 18706 18707(define_insn "*cmpstrnqi_rex_1" 18708 [(set (reg:CC FLAGS_REG) 18709 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2") 18710 (const_int 0)) 18711 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0")) 18712 (mem:BLK (match_operand:DI 5 "register_operand" "1"))) 18713 (const_int 0))) 18714 (use (match_operand:SI 3 "immediate_operand" "i")) 18715 (use (reg:CC FLAGS_REG)) 18716 (use (reg:SI DIRFLAG_REG)) 18717 (clobber (match_operand:DI 0 "register_operand" "=S")) 18718 (clobber (match_operand:DI 1 "register_operand" "=D")) 18719 (clobber (match_operand:DI 2 "register_operand" "=c"))] 18720 "TARGET_64BIT" 18721 "repz{\;| }cmpsb" 18722 [(set_attr "type" "str") 18723 (set_attr "mode" "QI") 18724 (set_attr "prefix_rep" "1")]) 18725 18726(define_expand "strlensi" 18727 [(set (match_operand:SI 0 "register_operand" "") 18728 (unspec:SI [(match_operand:BLK 1 "general_operand" "") 18729 (match_operand:QI 2 "immediate_operand" "") 18730 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))] 18731 "" 18732{ 18733 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) 18734 DONE; 18735 else 18736 FAIL; 18737}) 18738 18739(define_expand "strlendi" 18740 [(set (match_operand:DI 0 "register_operand" "") 18741 (unspec:DI [(match_operand:BLK 1 "general_operand" "") 18742 (match_operand:QI 2 "immediate_operand" "") 18743 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))] 18744 "" 18745{ 18746 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) 18747 DONE; 18748 else 18749 FAIL; 18750}) 18751 18752(define_expand "strlenqi_1" 18753 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" "")) 18754 (use (reg:SI DIRFLAG_REG)) 18755 (clobber (match_operand 1 "register_operand" "")) 18756 (clobber (reg:CC FLAGS_REG))])] 18757 "" 18758 "") 18759 18760(define_insn "*strlenqi_1" 18761 [(set (match_operand:SI 0 "register_operand" "=&c") 18762 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1")) 18763 (match_operand:QI 2 "register_operand" "a") 18764 (match_operand:SI 3 "immediate_operand" "i") 18765 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS)) 18766 (use (reg:SI DIRFLAG_REG)) 18767 (clobber (match_operand:SI 1 "register_operand" "=D")) 18768 (clobber (reg:CC FLAGS_REG))] 18769 "!TARGET_64BIT" 18770 "repnz{\;| }scasb" 18771 [(set_attr "type" "str") 18772 (set_attr "mode" "QI") 18773 (set_attr "prefix_rep" "1")]) 18774 18775(define_insn "*strlenqi_rex_1" 18776 [(set (match_operand:DI 0 "register_operand" "=&c") 18777 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1")) 18778 (match_operand:QI 2 "register_operand" "a") 18779 (match_operand:DI 3 "immediate_operand" "i") 18780 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS)) 18781 (use (reg:SI DIRFLAG_REG)) 18782 (clobber (match_operand:DI 1 "register_operand" "=D")) 18783 (clobber (reg:CC FLAGS_REG))] 18784 "TARGET_64BIT" 18785 "repnz{\;| }scasb" 18786 [(set_attr "type" "str") 18787 (set_attr "mode" "QI") 18788 (set_attr "prefix_rep" "1")]) 18789 18790;; Peephole optimizations to clean up after cmpstrn*. This should be 18791;; handled in combine, but it is not currently up to the task. 18792;; When used for their truth value, the cmpstrn* expanders generate 18793;; code like this: 18794;; 18795;; repz cmpsb 18796;; seta %al 18797;; setb %dl 18798;; cmpb %al, %dl 18799;; jcc label 18800;; 18801;; The intermediate three instructions are unnecessary. 18802 18803;; This one handles cmpstrn*_nz_1... 18804(define_peephole2 18805 [(parallel[ 18806 (set (reg:CC FLAGS_REG) 18807 (compare:CC (mem:BLK (match_operand 4 "register_operand" "")) 18808 (mem:BLK (match_operand 5 "register_operand" "")))) 18809 (use (match_operand 6 "register_operand" "")) 18810 (use (match_operand:SI 3 "immediate_operand" "")) 18811 (use (reg:SI DIRFLAG_REG)) 18812 (clobber (match_operand 0 "register_operand" "")) 18813 (clobber (match_operand 1 "register_operand" "")) 18814 (clobber (match_operand 2 "register_operand" ""))]) 18815 (set (match_operand:QI 7 "register_operand" "") 18816 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 18817 (set (match_operand:QI 8 "register_operand" "") 18818 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 18819 (set (reg FLAGS_REG) 18820 (compare (match_dup 7) (match_dup 8))) 18821 ] 18822 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 18823 [(parallel[ 18824 (set (reg:CC FLAGS_REG) 18825 (compare:CC (mem:BLK (match_dup 4)) 18826 (mem:BLK (match_dup 5)))) 18827 (use (match_dup 6)) 18828 (use (match_dup 3)) 18829 (use (reg:SI DIRFLAG_REG)) 18830 (clobber (match_dup 0)) 18831 (clobber (match_dup 1)) 18832 (clobber (match_dup 2))])] 18833 "") 18834 18835;; ...and this one handles cmpstrn*_1. 18836(define_peephole2 18837 [(parallel[ 18838 (set (reg:CC FLAGS_REG) 18839 (if_then_else:CC (ne (match_operand 6 "register_operand" "") 18840 (const_int 0)) 18841 (compare:CC (mem:BLK (match_operand 4 "register_operand" "")) 18842 (mem:BLK (match_operand 5 "register_operand" ""))) 18843 (const_int 0))) 18844 (use (match_operand:SI 3 "immediate_operand" "")) 18845 (use (reg:CC FLAGS_REG)) 18846 (use (reg:SI DIRFLAG_REG)) 18847 (clobber (match_operand 0 "register_operand" "")) 18848 (clobber (match_operand 1 "register_operand" "")) 18849 (clobber (match_operand 2 "register_operand" ""))]) 18850 (set (match_operand:QI 7 "register_operand" "") 18851 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 18852 (set (match_operand:QI 8 "register_operand" "") 18853 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 18854 (set (reg FLAGS_REG) 18855 (compare (match_dup 7) (match_dup 8))) 18856 ] 18857 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 18858 [(parallel[ 18859 (set (reg:CC FLAGS_REG) 18860 (if_then_else:CC (ne (match_dup 6) 18861 (const_int 0)) 18862 (compare:CC (mem:BLK (match_dup 4)) 18863 (mem:BLK (match_dup 5))) 18864 (const_int 0))) 18865 (use (match_dup 3)) 18866 (use (reg:CC FLAGS_REG)) 18867 (use (reg:SI DIRFLAG_REG)) 18868 (clobber (match_dup 0)) 18869 (clobber (match_dup 1)) 18870 (clobber (match_dup 2))])] 18871 "") 18872 18873 18874 18875;; Conditional move instructions. 18876 18877(define_expand "movdicc" 18878 [(set (match_operand:DI 0 "register_operand" "") 18879 (if_then_else:DI (match_operand 1 "comparison_operator" "") 18880 (match_operand:DI 2 "general_operand" "") 18881 (match_operand:DI 3 "general_operand" "")))] 18882 "TARGET_64BIT" 18883 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 18884 18885(define_insn "x86_movdicc_0_m1_rex64" 18886 [(set (match_operand:DI 0 "register_operand" "=r") 18887 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "") 18888 (const_int -1) 18889 (const_int 0))) 18890 (clobber (reg:CC FLAGS_REG))] 18891 "TARGET_64BIT" 18892 "sbb{q}\t%0, %0" 18893 ; Since we don't have the proper number of operands for an alu insn, 18894 ; fill in all the blanks. 18895 [(set_attr "type" "alu") 18896 (set_attr "pent_pair" "pu") 18897 (set_attr "memory" "none") 18898 (set_attr "imm_disp" "false") 18899 (set_attr "mode" "DI") 18900 (set_attr "length_immediate" "0")]) 18901 18902(define_insn "*movdicc_c_rex64" 18903 [(set (match_operand:DI 0 "register_operand" "=r,r") 18904 (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 18905 [(reg FLAGS_REG) (const_int 0)]) 18906 (match_operand:DI 2 "nonimmediate_operand" "rm,0") 18907 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))] 18908 "TARGET_64BIT && TARGET_CMOVE 18909 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 18910 "@ 18911 cmov%O2%C1\t{%2, %0|%0, %2} 18912 cmov%O2%c1\t{%3, %0|%0, %3}" 18913 [(set_attr "type" "icmov") 18914 (set_attr "mode" "DI")]) 18915 18916(define_expand "movsicc" 18917 [(set (match_operand:SI 0 "register_operand" "") 18918 (if_then_else:SI (match_operand 1 "comparison_operator" "") 18919 (match_operand:SI 2 "general_operand" "") 18920 (match_operand:SI 3 "general_operand" "")))] 18921 "" 18922 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 18923 18924;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing 18925;; the register first winds up with `sbbl $0,reg', which is also weird. 18926;; So just document what we're doing explicitly. 18927 18928(define_insn "x86_movsicc_0_m1" 18929 [(set (match_operand:SI 0 "register_operand" "=r") 18930 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "") 18931 (const_int -1) 18932 (const_int 0))) 18933 (clobber (reg:CC FLAGS_REG))] 18934 "" 18935 "sbb{l}\t%0, %0" 18936 ; Since we don't have the proper number of operands for an alu insn, 18937 ; fill in all the blanks. 18938 [(set_attr "type" "alu") 18939 (set_attr "pent_pair" "pu") 18940 (set_attr "memory" "none") 18941 (set_attr "imm_disp" "false") 18942 (set_attr "mode" "SI") 18943 (set_attr "length_immediate" "0")]) 18944 18945(define_insn "*movsicc_noc" 18946 [(set (match_operand:SI 0 "register_operand" "=r,r") 18947 (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 18948 [(reg FLAGS_REG) (const_int 0)]) 18949 (match_operand:SI 2 "nonimmediate_operand" "rm,0") 18950 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))] 18951 "TARGET_CMOVE 18952 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 18953 "@ 18954 cmov%O2%C1\t{%2, %0|%0, %2} 18955 cmov%O2%c1\t{%3, %0|%0, %3}" 18956 [(set_attr "type" "icmov") 18957 (set_attr "mode" "SI")]) 18958 18959(define_expand "movhicc" 18960 [(set (match_operand:HI 0 "register_operand" "") 18961 (if_then_else:HI (match_operand 1 "comparison_operator" "") 18962 (match_operand:HI 2 "general_operand" "") 18963 (match_operand:HI 3 "general_operand" "")))] 18964 "TARGET_HIMODE_MATH" 18965 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 18966 18967(define_insn "*movhicc_noc" 18968 [(set (match_operand:HI 0 "register_operand" "=r,r") 18969 (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 18970 [(reg FLAGS_REG) (const_int 0)]) 18971 (match_operand:HI 2 "nonimmediate_operand" "rm,0") 18972 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))] 18973 "TARGET_CMOVE 18974 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 18975 "@ 18976 cmov%O2%C1\t{%2, %0|%0, %2} 18977 cmov%O2%c1\t{%3, %0|%0, %3}" 18978 [(set_attr "type" "icmov") 18979 (set_attr "mode" "HI")]) 18980 18981(define_expand "movqicc" 18982 [(set (match_operand:QI 0 "register_operand" "") 18983 (if_then_else:QI (match_operand 1 "comparison_operator" "") 18984 (match_operand:QI 2 "general_operand" "") 18985 (match_operand:QI 3 "general_operand" "")))] 18986 "TARGET_QIMODE_MATH" 18987 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;") 18988 18989(define_insn_and_split "*movqicc_noc" 18990 [(set (match_operand:QI 0 "register_operand" "=r,r") 18991 (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 18992 [(match_operand 4 "flags_reg_operand" "") 18993 (const_int 0)]) 18994 (match_operand:QI 2 "register_operand" "r,0") 18995 (match_operand:QI 3 "register_operand" "0,r")))] 18996 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL" 18997 "#" 18998 "&& reload_completed" 18999 [(set (match_dup 0) 19000 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) 19001 (match_dup 2) 19002 (match_dup 3)))] 19003 "operands[0] = gen_lowpart (SImode, operands[0]); 19004 operands[2] = gen_lowpart (SImode, operands[2]); 19005 operands[3] = gen_lowpart (SImode, operands[3]);" 19006 [(set_attr "type" "icmov") 19007 (set_attr "mode" "SI")]) 19008 19009(define_expand "movsfcc" 19010 [(set (match_operand:SF 0 "register_operand" "") 19011 (if_then_else:SF (match_operand 1 "comparison_operator" "") 19012 (match_operand:SF 2 "register_operand" "") 19013 (match_operand:SF 3 "register_operand" "")))] 19014 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH" 19015 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") 19016 19017(define_insn "*movsfcc_1_387" 19018 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r") 19019 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 19020 [(reg FLAGS_REG) (const_int 0)]) 19021 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0") 19022 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))] 19023 "TARGET_80387 && TARGET_CMOVE 19024 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19025 "@ 19026 fcmov%F1\t{%2, %0|%0, %2} 19027 fcmov%f1\t{%3, %0|%0, %3} 19028 cmov%O2%C1\t{%2, %0|%0, %2} 19029 cmov%O2%c1\t{%3, %0|%0, %3}" 19030 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 19031 (set_attr "mode" "SF,SF,SI,SI")]) 19032 19033(define_expand "movdfcc" 19034 [(set (match_operand:DF 0 "register_operand" "") 19035 (if_then_else:DF (match_operand 1 "comparison_operator" "") 19036 (match_operand:DF 2 "register_operand" "") 19037 (match_operand:DF 3 "register_operand" "")))] 19038 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)" 19039 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") 19040 19041(define_insn "*movdfcc_1" 19042 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r") 19043 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 19044 [(reg FLAGS_REG) (const_int 0)]) 19045 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") 19046 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] 19047 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 19048 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19049 "@ 19050 fcmov%F1\t{%2, %0|%0, %2} 19051 fcmov%f1\t{%3, %0|%0, %3} 19052 # 19053 #" 19054 [(set_attr "type" "fcmov,fcmov,multi,multi") 19055 (set_attr "mode" "DF")]) 19056 19057(define_insn "*movdfcc_1_rex64" 19058 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r") 19059 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 19060 [(reg FLAGS_REG) (const_int 0)]) 19061 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") 19062 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] 19063 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 19064 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" 19065 "@ 19066 fcmov%F1\t{%2, %0|%0, %2} 19067 fcmov%f1\t{%3, %0|%0, %3} 19068 cmov%O2%C1\t{%2, %0|%0, %2} 19069 cmov%O2%c1\t{%3, %0|%0, %3}" 19070 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 19071 (set_attr "mode" "DF")]) 19072 19073(define_split 19074 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "") 19075 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 19076 [(match_operand 4 "flags_reg_operand" "") 19077 (const_int 0)]) 19078 (match_operand:DF 2 "nonimmediate_operand" "") 19079 (match_operand:DF 3 "nonimmediate_operand" "")))] 19080 "!TARGET_64BIT && reload_completed" 19081 [(set (match_dup 2) 19082 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) 19083 (match_dup 5) 19084 (match_dup 7))) 19085 (set (match_dup 3) 19086 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)]) 19087 (match_dup 6) 19088 (match_dup 8)))] 19089 "split_di (operands+2, 1, operands+5, operands+6); 19090 split_di (operands+3, 1, operands+7, operands+8); 19091 split_di (operands, 1, operands+2, operands+3);") 19092 19093(define_expand "movxfcc" 19094 [(set (match_operand:XF 0 "register_operand" "") 19095 (if_then_else:XF (match_operand 1 "comparison_operator" "") 19096 (match_operand:XF 2 "register_operand" "") 19097 (match_operand:XF 3 "register_operand" "")))] 19098 "TARGET_80387 && TARGET_CMOVE" 19099 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") 19100 19101(define_insn "*movxfcc_1" 19102 [(set (match_operand:XF 0 "register_operand" "=f,f") 19103 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 19104 [(reg FLAGS_REG) (const_int 0)]) 19105 (match_operand:XF 2 "register_operand" "f,0") 19106 (match_operand:XF 3 "register_operand" "0,f")))] 19107 "TARGET_80387 && TARGET_CMOVE" 19108 "@ 19109 fcmov%F1\t{%2, %0|%0, %2} 19110 fcmov%f1\t{%3, %0|%0, %3}" 19111 [(set_attr "type" "fcmov") 19112 (set_attr "mode" "XF")]) 19113 19114;; These versions of the min/max patterns are intentionally ignorant of 19115;; their behavior wrt -0.0 and NaN (via the commutative operand mark). 19116;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator 19117;; are undefined in this condition, we're certain this is correct. 19118 19119(define_insn "sminsf3" 19120 [(set (match_operand:SF 0 "register_operand" "=x") 19121 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0") 19122 (match_operand:SF 2 "nonimmediate_operand" "xm")))] 19123 "TARGET_SSE_MATH" 19124 "minss\t{%2, %0|%0, %2}" 19125 [(set_attr "type" "sseadd") 19126 (set_attr "mode" "SF")]) 19127 19128(define_insn "smaxsf3" 19129 [(set (match_operand:SF 0 "register_operand" "=x") 19130 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0") 19131 (match_operand:SF 2 "nonimmediate_operand" "xm")))] 19132 "TARGET_SSE_MATH" 19133 "maxss\t{%2, %0|%0, %2}" 19134 [(set_attr "type" "sseadd") 19135 (set_attr "mode" "SF")]) 19136 19137(define_insn "smindf3" 19138 [(set (match_operand:DF 0 "register_operand" "=x") 19139 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0") 19140 (match_operand:DF 2 "nonimmediate_operand" "xm")))] 19141 "TARGET_SSE2 && TARGET_SSE_MATH" 19142 "minsd\t{%2, %0|%0, %2}" 19143 [(set_attr "type" "sseadd") 19144 (set_attr "mode" "DF")]) 19145 19146(define_insn "smaxdf3" 19147 [(set (match_operand:DF 0 "register_operand" "=x") 19148 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0") 19149 (match_operand:DF 2 "nonimmediate_operand" "xm")))] 19150 "TARGET_SSE2 && TARGET_SSE_MATH" 19151 "maxsd\t{%2, %0|%0, %2}" 19152 [(set_attr "type" "sseadd") 19153 (set_attr "mode" "DF")]) 19154 19155;; These versions of the min/max patterns implement exactly the operations 19156;; min = (op1 < op2 ? op1 : op2) 19157;; max = (!(op1 < op2) ? op1 : op2) 19158;; Their operands are not commutative, and thus they may be used in the 19159;; presence of -0.0 and NaN. 19160 19161(define_insn "*ieee_sminsf3" 19162 [(set (match_operand:SF 0 "register_operand" "=x") 19163 (unspec:SF [(match_operand:SF 1 "register_operand" "0") 19164 (match_operand:SF 2 "nonimmediate_operand" "xm")] 19165 UNSPEC_IEEE_MIN))] 19166 "TARGET_SSE_MATH" 19167 "minss\t{%2, %0|%0, %2}" 19168 [(set_attr "type" "sseadd") 19169 (set_attr "mode" "SF")]) 19170 19171(define_insn "*ieee_smaxsf3" 19172 [(set (match_operand:SF 0 "register_operand" "=x") 19173 (unspec:SF [(match_operand:SF 1 "register_operand" "0") 19174 (match_operand:SF 2 "nonimmediate_operand" "xm")] 19175 UNSPEC_IEEE_MAX))] 19176 "TARGET_SSE_MATH" 19177 "maxss\t{%2, %0|%0, %2}" 19178 [(set_attr "type" "sseadd") 19179 (set_attr "mode" "SF")]) 19180 19181(define_insn "*ieee_smindf3" 19182 [(set (match_operand:DF 0 "register_operand" "=x") 19183 (unspec:DF [(match_operand:DF 1 "register_operand" "0") 19184 (match_operand:DF 2 "nonimmediate_operand" "xm")] 19185 UNSPEC_IEEE_MIN))] 19186 "TARGET_SSE2 && TARGET_SSE_MATH" 19187 "minsd\t{%2, %0|%0, %2}" 19188 [(set_attr "type" "sseadd") 19189 (set_attr "mode" "DF")]) 19190 19191(define_insn "*ieee_smaxdf3" 19192 [(set (match_operand:DF 0 "register_operand" "=x") 19193 (unspec:DF [(match_operand:DF 1 "register_operand" "0") 19194 (match_operand:DF 2 "nonimmediate_operand" "xm")] 19195 UNSPEC_IEEE_MAX))] 19196 "TARGET_SSE2 && TARGET_SSE_MATH" 19197 "maxsd\t{%2, %0|%0, %2}" 19198 [(set_attr "type" "sseadd") 19199 (set_attr "mode" "DF")]) 19200 19201;; Make two stack loads independent: 19202;; fld aa fld aa 19203;; fld %st(0) -> fld bb 19204;; fmul bb fmul %st(1), %st 19205;; 19206;; Actually we only match the last two instructions for simplicity. 19207(define_peephole2 19208 [(set (match_operand 0 "fp_register_operand" "") 19209 (match_operand 1 "fp_register_operand" "")) 19210 (set (match_dup 0) 19211 (match_operator 2 "binary_fp_operator" 19212 [(match_dup 0) 19213 (match_operand 3 "memory_operand" "")]))] 19214 "REGNO (operands[0]) != REGNO (operands[1])" 19215 [(set (match_dup 0) (match_dup 3)) 19216 (set (match_dup 0) (match_dup 4))] 19217 19218 ;; The % modifier is not operational anymore in peephole2's, so we have to 19219 ;; swap the operands manually in the case of addition and multiplication. 19220 "if (COMMUTATIVE_ARITH_P (operands[2])) 19221 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), 19222 operands[0], operands[1]); 19223 else 19224 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), 19225 operands[1], operands[0]);") 19226 19227;; Conditional addition patterns 19228(define_expand "addqicc" 19229 [(match_operand:QI 0 "register_operand" "") 19230 (match_operand 1 "comparison_operator" "") 19231 (match_operand:QI 2 "register_operand" "") 19232 (match_operand:QI 3 "const_int_operand" "")] 19233 "" 19234 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 19235 19236(define_expand "addhicc" 19237 [(match_operand:HI 0 "register_operand" "") 19238 (match_operand 1 "comparison_operator" "") 19239 (match_operand:HI 2 "register_operand" "") 19240 (match_operand:HI 3 "const_int_operand" "")] 19241 "" 19242 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 19243 19244(define_expand "addsicc" 19245 [(match_operand:SI 0 "register_operand" "") 19246 (match_operand 1 "comparison_operator" "") 19247 (match_operand:SI 2 "register_operand" "") 19248 (match_operand:SI 3 "const_int_operand" "")] 19249 "" 19250 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 19251 19252(define_expand "adddicc" 19253 [(match_operand:DI 0 "register_operand" "") 19254 (match_operand 1 "comparison_operator" "") 19255 (match_operand:DI 2 "register_operand" "") 19256 (match_operand:DI 3 "const_int_operand" "")] 19257 "TARGET_64BIT" 19258 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;") 19259 19260 19261;; Misc patterns (?) 19262 19263;; This pattern exists to put a dependency on all ebp-based memory accesses. 19264;; Otherwise there will be nothing to keep 19265;; 19266;; [(set (reg ebp) (reg esp))] 19267;; [(set (reg esp) (plus (reg esp) (const_int -160000))) 19268;; (clobber (eflags)] 19269;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))] 19270;; 19271;; in proper program order. 19272(define_insn "pro_epilogue_adjust_stack_1" 19273 [(set (match_operand:SI 0 "register_operand" "=r,r") 19274 (plus:SI (match_operand:SI 1 "register_operand" "0,r") 19275 (match_operand:SI 2 "immediate_operand" "i,i"))) 19276 (clobber (reg:CC FLAGS_REG)) 19277 (clobber (mem:BLK (scratch)))] 19278 "!TARGET_64BIT" 19279{ 19280 switch (get_attr_type (insn)) 19281 { 19282 case TYPE_IMOV: 19283 return "mov{l}\t{%1, %0|%0, %1}"; 19284 19285 case TYPE_ALU: 19286 if (GET_CODE (operands[2]) == CONST_INT 19287 && (INTVAL (operands[2]) == 128 19288 || (INTVAL (operands[2]) < 0 19289 && INTVAL (operands[2]) != -128))) 19290 { 19291 operands[2] = GEN_INT (-INTVAL (operands[2])); 19292 return "sub{l}\t{%2, %0|%0, %2}"; 19293 } 19294 return "add{l}\t{%2, %0|%0, %2}"; 19295 19296 case TYPE_LEA: 19297 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 19298 return "lea{l}\t{%a2, %0|%0, %a2}"; 19299 19300 default: 19301 gcc_unreachable (); 19302 } 19303} 19304 [(set (attr "type") 19305 (cond [(eq_attr "alternative" "0") 19306 (const_string "alu") 19307 (match_operand:SI 2 "const0_operand" "") 19308 (const_string "imov") 19309 ] 19310 (const_string "lea"))) 19311 (set_attr "mode" "SI")]) 19312 19313(define_insn "pro_epilogue_adjust_stack_rex64" 19314 [(set (match_operand:DI 0 "register_operand" "=r,r") 19315 (plus:DI (match_operand:DI 1 "register_operand" "0,r") 19316 (match_operand:DI 2 "x86_64_immediate_operand" "e,e"))) 19317 (clobber (reg:CC FLAGS_REG)) 19318 (clobber (mem:BLK (scratch)))] 19319 "TARGET_64BIT" 19320{ 19321 switch (get_attr_type (insn)) 19322 { 19323 case TYPE_IMOV: 19324 return "mov{q}\t{%1, %0|%0, %1}"; 19325 19326 case TYPE_ALU: 19327 if (GET_CODE (operands[2]) == CONST_INT 19328 /* Avoid overflows. */ 19329 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))) 19330 && (INTVAL (operands[2]) == 128 19331 || (INTVAL (operands[2]) < 0 19332 && INTVAL (operands[2]) != -128))) 19333 { 19334 operands[2] = GEN_INT (-INTVAL (operands[2])); 19335 return "sub{q}\t{%2, %0|%0, %2}"; 19336 } 19337 return "add{q}\t{%2, %0|%0, %2}"; 19338 19339 case TYPE_LEA: 19340 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 19341 return "lea{q}\t{%a2, %0|%0, %a2}"; 19342 19343 default: 19344 gcc_unreachable (); 19345 } 19346} 19347 [(set (attr "type") 19348 (cond [(eq_attr "alternative" "0") 19349 (const_string "alu") 19350 (match_operand:DI 2 "const0_operand" "") 19351 (const_string "imov") 19352 ] 19353 (const_string "lea"))) 19354 (set_attr "mode" "DI")]) 19355 19356(define_insn "pro_epilogue_adjust_stack_rex64_2" 19357 [(set (match_operand:DI 0 "register_operand" "=r,r") 19358 (plus:DI (match_operand:DI 1 "register_operand" "0,r") 19359 (match_operand:DI 3 "immediate_operand" "i,i"))) 19360 (use (match_operand:DI 2 "register_operand" "r,r")) 19361 (clobber (reg:CC FLAGS_REG)) 19362 (clobber (mem:BLK (scratch)))] 19363 "TARGET_64BIT" 19364{ 19365 switch (get_attr_type (insn)) 19366 { 19367 case TYPE_ALU: 19368 return "add{q}\t{%2, %0|%0, %2}"; 19369 19370 case TYPE_LEA: 19371 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]); 19372 return "lea{q}\t{%a2, %0|%0, %a2}"; 19373 19374 default: 19375 gcc_unreachable (); 19376 } 19377} 19378 [(set_attr "type" "alu,lea") 19379 (set_attr "mode" "DI")]) 19380 19381(define_expand "allocate_stack_worker" 19382 [(match_operand:SI 0 "register_operand" "")] 19383 "TARGET_STACK_PROBE" 19384{ 19385 if (reload_completed) 19386 { 19387 if (TARGET_64BIT) 19388 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0])); 19389 else 19390 emit_insn (gen_allocate_stack_worker_postreload (operands[0])); 19391 } 19392 else 19393 { 19394 if (TARGET_64BIT) 19395 emit_insn (gen_allocate_stack_worker_rex64 (operands[0])); 19396 else 19397 emit_insn (gen_allocate_stack_worker_1 (operands[0])); 19398 } 19399 DONE; 19400}) 19401 19402(define_insn "allocate_stack_worker_1" 19403 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")] 19404 UNSPECV_STACK_PROBE) 19405 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0))) 19406 (clobber (match_scratch:SI 1 "=0")) 19407 (clobber (reg:CC FLAGS_REG))] 19408 "!TARGET_64BIT && TARGET_STACK_PROBE" 19409 "call\t__alloca" 19410 [(set_attr "type" "multi") 19411 (set_attr "length" "5")]) 19412 19413(define_expand "allocate_stack_worker_postreload" 19414 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")] 19415 UNSPECV_STACK_PROBE) 19416 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0))) 19417 (clobber (match_dup 0)) 19418 (clobber (reg:CC FLAGS_REG))])] 19419 "" 19420 "") 19421 19422(define_insn "allocate_stack_worker_rex64" 19423 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")] 19424 UNSPECV_STACK_PROBE) 19425 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0))) 19426 (clobber (match_scratch:DI 1 "=0")) 19427 (clobber (reg:CC FLAGS_REG))] 19428 "TARGET_64BIT && TARGET_STACK_PROBE" 19429 "call\t__alloca" 19430 [(set_attr "type" "multi") 19431 (set_attr "length" "5")]) 19432 19433(define_expand "allocate_stack_worker_rex64_postreload" 19434 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")] 19435 UNSPECV_STACK_PROBE) 19436 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0))) 19437 (clobber (match_dup 0)) 19438 (clobber (reg:CC FLAGS_REG))])] 19439 "" 19440 "") 19441 19442(define_expand "allocate_stack" 19443 [(parallel [(set (match_operand:SI 0 "register_operand" "=r") 19444 (minus:SI (reg:SI SP_REG) 19445 (match_operand:SI 1 "general_operand" ""))) 19446 (clobber (reg:CC FLAGS_REG))]) 19447 (parallel [(set (reg:SI SP_REG) 19448 (minus:SI (reg:SI SP_REG) (match_dup 1))) 19449 (clobber (reg:CC FLAGS_REG))])] 19450 "TARGET_STACK_PROBE" 19451{ 19452#ifdef CHECK_STACK_LIMIT 19453 if (GET_CODE (operands[1]) == CONST_INT 19454 && INTVAL (operands[1]) < CHECK_STACK_LIMIT) 19455 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, 19456 operands[1])); 19457 else 19458#endif 19459 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode, 19460 operands[1]))); 19461 19462 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 19463 DONE; 19464}) 19465 19466(define_expand "builtin_setjmp_receiver" 19467 [(label_ref (match_operand 0 "" ""))] 19468 "!TARGET_64BIT && flag_pic" 19469{ 19470 if (TARGET_MACHO) 19471 { 19472 rtx xops[3]; 19473 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM); 19474 rtx label_rtx = gen_label_rtx (); 19475 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx)); 19476 xops[0] = xops[1] = picreg; 19477 xops[2] = gen_rtx_CONST (SImode, 19478 gen_rtx_MINUS (SImode, 19479 gen_rtx_LABEL_REF (SImode, label_rtx), 19480 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME))); 19481 ix86_expand_binary_operator (MINUS, SImode, xops); 19482 } 19483 else 19484 emit_insn (gen_set_got (pic_offset_table_rtx)); 19485 DONE; 19486}) 19487 19488;; Avoid redundant prefixes by splitting HImode arithmetic to SImode. 19489 19490(define_split 19491 [(set (match_operand 0 "register_operand" "") 19492 (match_operator 3 "promotable_binary_operator" 19493 [(match_operand 1 "register_operand" "") 19494 (match_operand 2 "aligned_operand" "")])) 19495 (clobber (reg:CC FLAGS_REG))] 19496 "! TARGET_PARTIAL_REG_STALL && reload_completed 19497 && ((GET_MODE (operands[0]) == HImode 19498 && ((!optimize_size && !TARGET_FAST_PREFIX) 19499 /* ??? next two lines just !satisfies_constraint_K (...) */ 19500 || GET_CODE (operands[2]) != CONST_INT 19501 || satisfies_constraint_K (operands[2]))) 19502 || (GET_MODE (operands[0]) == QImode 19503 && (TARGET_PROMOTE_QImode || optimize_size)))" 19504 [(parallel [(set (match_dup 0) 19505 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 19506 (clobber (reg:CC FLAGS_REG))])] 19507 "operands[0] = gen_lowpart (SImode, operands[0]); 19508 operands[1] = gen_lowpart (SImode, operands[1]); 19509 if (GET_CODE (operands[3]) != ASHIFT) 19510 operands[2] = gen_lowpart (SImode, operands[2]); 19511 PUT_MODE (operands[3], SImode);") 19512 19513; Promote the QImode tests, as i386 has encoding of the AND 19514; instruction with 32-bit sign-extended immediate and thus the 19515; instruction size is unchanged, except in the %eax case for 19516; which it is increased by one byte, hence the ! optimize_size. 19517(define_split 19518 [(set (match_operand 0 "flags_reg_operand" "") 19519 (match_operator 2 "compare_operator" 19520 [(and (match_operand 3 "aligned_operand" "") 19521 (match_operand 4 "const_int_operand" "")) 19522 (const_int 0)])) 19523 (set (match_operand 1 "register_operand" "") 19524 (and (match_dup 3) (match_dup 4)))] 19525 "! TARGET_PARTIAL_REG_STALL && reload_completed 19526 /* Ensure that the operand will remain sign-extended immediate. */ 19527 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode) 19528 && ! optimize_size 19529 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX) 19530 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))" 19531 [(parallel [(set (match_dup 0) 19532 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4)) 19533 (const_int 0)])) 19534 (set (match_dup 1) 19535 (and:SI (match_dup 3) (match_dup 4)))])] 19536{ 19537 operands[4] 19538 = gen_int_mode (INTVAL (operands[4]) 19539 & GET_MODE_MASK (GET_MODE (operands[1])), SImode); 19540 operands[1] = gen_lowpart (SImode, operands[1]); 19541 operands[3] = gen_lowpart (SImode, operands[3]); 19542}) 19543 19544; Don't promote the QImode tests, as i386 doesn't have encoding of 19545; the TEST instruction with 32-bit sign-extended immediate and thus 19546; the instruction size would at least double, which is not what we 19547; want even with ! optimize_size. 19548(define_split 19549 [(set (match_operand 0 "flags_reg_operand" "") 19550 (match_operator 1 "compare_operator" 19551 [(and (match_operand:HI 2 "aligned_operand" "") 19552 (match_operand:HI 3 "const_int_operand" "")) 19553 (const_int 0)]))] 19554 "! TARGET_PARTIAL_REG_STALL && reload_completed 19555 /* Ensure that the operand will remain sign-extended immediate. */ 19556 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode) 19557 && ! TARGET_FAST_PREFIX 19558 && ! optimize_size" 19559 [(set (match_dup 0) 19560 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 19561 (const_int 0)]))] 19562{ 19563 operands[3] 19564 = gen_int_mode (INTVAL (operands[3]) 19565 & GET_MODE_MASK (GET_MODE (operands[2])), SImode); 19566 operands[2] = gen_lowpart (SImode, operands[2]); 19567}) 19568 19569(define_split 19570 [(set (match_operand 0 "register_operand" "") 19571 (neg (match_operand 1 "register_operand" ""))) 19572 (clobber (reg:CC FLAGS_REG))] 19573 "! TARGET_PARTIAL_REG_STALL && reload_completed 19574 && (GET_MODE (operands[0]) == HImode 19575 || (GET_MODE (operands[0]) == QImode 19576 && (TARGET_PROMOTE_QImode || optimize_size)))" 19577 [(parallel [(set (match_dup 0) 19578 (neg:SI (match_dup 1))) 19579 (clobber (reg:CC FLAGS_REG))])] 19580 "operands[0] = gen_lowpart (SImode, operands[0]); 19581 operands[1] = gen_lowpart (SImode, operands[1]);") 19582 19583(define_split 19584 [(set (match_operand 0 "register_operand" "") 19585 (not (match_operand 1 "register_operand" "")))] 19586 "! TARGET_PARTIAL_REG_STALL && reload_completed 19587 && (GET_MODE (operands[0]) == HImode 19588 || (GET_MODE (operands[0]) == QImode 19589 && (TARGET_PROMOTE_QImode || optimize_size)))" 19590 [(set (match_dup 0) 19591 (not:SI (match_dup 1)))] 19592 "operands[0] = gen_lowpart (SImode, operands[0]); 19593 operands[1] = gen_lowpart (SImode, operands[1]);") 19594 19595(define_split 19596 [(set (match_operand 0 "register_operand" "") 19597 (if_then_else (match_operator 1 "comparison_operator" 19598 [(reg FLAGS_REG) (const_int 0)]) 19599 (match_operand 2 "register_operand" "") 19600 (match_operand 3 "register_operand" "")))] 19601 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE 19602 && (GET_MODE (operands[0]) == HImode 19603 || (GET_MODE (operands[0]) == QImode 19604 && (TARGET_PROMOTE_QImode || optimize_size)))" 19605 [(set (match_dup 0) 19606 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))] 19607 "operands[0] = gen_lowpart (SImode, operands[0]); 19608 operands[2] = gen_lowpart (SImode, operands[2]); 19609 operands[3] = gen_lowpart (SImode, operands[3]);") 19610 19611 19612;; RTL Peephole optimizations, run before sched2. These primarily look to 19613;; transform a complex memory operation into two memory to register operations. 19614 19615;; Don't push memory operands 19616(define_peephole2 19617 [(set (match_operand:SI 0 "push_operand" "") 19618 (match_operand:SI 1 "memory_operand" "")) 19619 (match_scratch:SI 2 "r")] 19620 "!optimize_size && !TARGET_PUSH_MEMORY 19621 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19622 [(set (match_dup 2) (match_dup 1)) 19623 (set (match_dup 0) (match_dup 2))] 19624 "") 19625 19626(define_peephole2 19627 [(set (match_operand:DI 0 "push_operand" "") 19628 (match_operand:DI 1 "memory_operand" "")) 19629 (match_scratch:DI 2 "r")] 19630 "!optimize_size && !TARGET_PUSH_MEMORY 19631 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19632 [(set (match_dup 2) (match_dup 1)) 19633 (set (match_dup 0) (match_dup 2))] 19634 "") 19635 19636;; We need to handle SFmode only, because DFmode and XFmode is split to 19637;; SImode pushes. 19638(define_peephole2 19639 [(set (match_operand:SF 0 "push_operand" "") 19640 (match_operand:SF 1 "memory_operand" "")) 19641 (match_scratch:SF 2 "r")] 19642 "!optimize_size && !TARGET_PUSH_MEMORY 19643 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19644 [(set (match_dup 2) (match_dup 1)) 19645 (set (match_dup 0) (match_dup 2))] 19646 "") 19647 19648(define_peephole2 19649 [(set (match_operand:HI 0 "push_operand" "") 19650 (match_operand:HI 1 "memory_operand" "")) 19651 (match_scratch:HI 2 "r")] 19652 "!optimize_size && !TARGET_PUSH_MEMORY 19653 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19654 [(set (match_dup 2) (match_dup 1)) 19655 (set (match_dup 0) (match_dup 2))] 19656 "") 19657 19658(define_peephole2 19659 [(set (match_operand:QI 0 "push_operand" "") 19660 (match_operand:QI 1 "memory_operand" "")) 19661 (match_scratch:QI 2 "q")] 19662 "!optimize_size && !TARGET_PUSH_MEMORY 19663 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 19664 [(set (match_dup 2) (match_dup 1)) 19665 (set (match_dup 0) (match_dup 2))] 19666 "") 19667 19668;; Don't move an immediate directly to memory when the instruction 19669;; gets too big. 19670(define_peephole2 19671 [(match_scratch:SI 1 "r") 19672 (set (match_operand:SI 0 "memory_operand" "") 19673 (const_int 0))] 19674 "! optimize_size 19675 && ! TARGET_USE_MOV0 19676 && TARGET_SPLIT_LONG_MOVES 19677 && get_attr_length (insn) >= ix86_cost->large_insn 19678 && peep2_regno_dead_p (0, FLAGS_REG)" 19679 [(parallel [(set (match_dup 1) (const_int 0)) 19680 (clobber (reg:CC FLAGS_REG))]) 19681 (set (match_dup 0) (match_dup 1))] 19682 "") 19683 19684(define_peephole2 19685 [(match_scratch:HI 1 "r") 19686 (set (match_operand:HI 0 "memory_operand" "") 19687 (const_int 0))] 19688 "! optimize_size 19689 && ! TARGET_USE_MOV0 19690 && TARGET_SPLIT_LONG_MOVES 19691 && get_attr_length (insn) >= ix86_cost->large_insn 19692 && peep2_regno_dead_p (0, FLAGS_REG)" 19693 [(parallel [(set (match_dup 2) (const_int 0)) 19694 (clobber (reg:CC FLAGS_REG))]) 19695 (set (match_dup 0) (match_dup 1))] 19696 "operands[2] = gen_lowpart (SImode, operands[1]);") 19697 19698(define_peephole2 19699 [(match_scratch:QI 1 "q") 19700 (set (match_operand:QI 0 "memory_operand" "") 19701 (const_int 0))] 19702 "! optimize_size 19703 && ! TARGET_USE_MOV0 19704 && TARGET_SPLIT_LONG_MOVES 19705 && get_attr_length (insn) >= ix86_cost->large_insn 19706 && peep2_regno_dead_p (0, FLAGS_REG)" 19707 [(parallel [(set (match_dup 2) (const_int 0)) 19708 (clobber (reg:CC FLAGS_REG))]) 19709 (set (match_dup 0) (match_dup 1))] 19710 "operands[2] = gen_lowpart (SImode, operands[1]);") 19711 19712(define_peephole2 19713 [(match_scratch:SI 2 "r") 19714 (set (match_operand:SI 0 "memory_operand" "") 19715 (match_operand:SI 1 "immediate_operand" ""))] 19716 "! optimize_size 19717 && get_attr_length (insn) >= ix86_cost->large_insn 19718 && TARGET_SPLIT_LONG_MOVES" 19719 [(set (match_dup 2) (match_dup 1)) 19720 (set (match_dup 0) (match_dup 2))] 19721 "") 19722 19723(define_peephole2 19724 [(match_scratch:HI 2 "r") 19725 (set (match_operand:HI 0 "memory_operand" "") 19726 (match_operand:HI 1 "immediate_operand" ""))] 19727 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn 19728 && TARGET_SPLIT_LONG_MOVES" 19729 [(set (match_dup 2) (match_dup 1)) 19730 (set (match_dup 0) (match_dup 2))] 19731 "") 19732 19733(define_peephole2 19734 [(match_scratch:QI 2 "q") 19735 (set (match_operand:QI 0 "memory_operand" "") 19736 (match_operand:QI 1 "immediate_operand" ""))] 19737 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn 19738 && TARGET_SPLIT_LONG_MOVES" 19739 [(set (match_dup 2) (match_dup 1)) 19740 (set (match_dup 0) (match_dup 2))] 19741 "") 19742 19743;; Don't compare memory with zero, load and use a test instead. 19744(define_peephole2 19745 [(set (match_operand 0 "flags_reg_operand" "") 19746 (match_operator 1 "compare_operator" 19747 [(match_operand:SI 2 "memory_operand" "") 19748 (const_int 0)])) 19749 (match_scratch:SI 3 "r")] 19750 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size" 19751 [(set (match_dup 3) (match_dup 2)) 19752 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))] 19753 "") 19754 19755;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 19756;; Don't split NOTs with a displacement operand, because resulting XOR 19757;; will not be pairable anyway. 19758;; 19759;; On AMD K6, NOT is vector decoded with memory operand that cannot be 19760;; represented using a modRM byte. The XOR replacement is long decoded, 19761;; so this split helps here as well. 19762;; 19763;; Note: Can't do this as a regular split because we can't get proper 19764;; lifetime information then. 19765 19766(define_peephole2 19767 [(set (match_operand:SI 0 "nonimmediate_operand" "") 19768 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))] 19769 "!optimize_size 19770 && peep2_regno_dead_p (0, FLAGS_REG) 19771 && ((TARGET_PENTIUM 19772 && (GET_CODE (operands[0]) != MEM 19773 || !memory_displacement_operand (operands[0], SImode))) 19774 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))" 19775 [(parallel [(set (match_dup 0) 19776 (xor:SI (match_dup 1) (const_int -1))) 19777 (clobber (reg:CC FLAGS_REG))])] 19778 "") 19779 19780(define_peephole2 19781 [(set (match_operand:HI 0 "nonimmediate_operand" "") 19782 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))] 19783 "!optimize_size 19784 && peep2_regno_dead_p (0, FLAGS_REG) 19785 && ((TARGET_PENTIUM 19786 && (GET_CODE (operands[0]) != MEM 19787 || !memory_displacement_operand (operands[0], HImode))) 19788 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))" 19789 [(parallel [(set (match_dup 0) 19790 (xor:HI (match_dup 1) (const_int -1))) 19791 (clobber (reg:CC FLAGS_REG))])] 19792 "") 19793 19794(define_peephole2 19795 [(set (match_operand:QI 0 "nonimmediate_operand" "") 19796 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))] 19797 "!optimize_size 19798 && peep2_regno_dead_p (0, FLAGS_REG) 19799 && ((TARGET_PENTIUM 19800 && (GET_CODE (operands[0]) != MEM 19801 || !memory_displacement_operand (operands[0], QImode))) 19802 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))" 19803 [(parallel [(set (match_dup 0) 19804 (xor:QI (match_dup 1) (const_int -1))) 19805 (clobber (reg:CC FLAGS_REG))])] 19806 "") 19807 19808;; Non pairable "test imm, reg" instructions can be translated to 19809;; "and imm, reg" if reg dies. The "and" form is also shorter (one 19810;; byte opcode instead of two, have a short form for byte operands), 19811;; so do it for other CPUs as well. Given that the value was dead, 19812;; this should not create any new dependencies. Pass on the sub-word 19813;; versions if we're concerned about partial register stalls. 19814 19815(define_peephole2 19816 [(set (match_operand 0 "flags_reg_operand" "") 19817 (match_operator 1 "compare_operator" 19818 [(and:SI (match_operand:SI 2 "register_operand" "") 19819 (match_operand:SI 3 "immediate_operand" "")) 19820 (const_int 0)]))] 19821 "ix86_match_ccmode (insn, CCNOmode) 19822 && (true_regnum (operands[2]) != 0 19823 || satisfies_constraint_K (operands[3])) 19824 && peep2_reg_dead_p (1, operands[2])" 19825 [(parallel 19826 [(set (match_dup 0) 19827 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 19828 (const_int 0)])) 19829 (set (match_dup 2) 19830 (and:SI (match_dup 2) (match_dup 3)))])] 19831 "") 19832 19833;; We don't need to handle HImode case, because it will be promoted to SImode 19834;; on ! TARGET_PARTIAL_REG_STALL 19835 19836(define_peephole2 19837 [(set (match_operand 0 "flags_reg_operand" "") 19838 (match_operator 1 "compare_operator" 19839 [(and:QI (match_operand:QI 2 "register_operand" "") 19840 (match_operand:QI 3 "immediate_operand" "")) 19841 (const_int 0)]))] 19842 "! TARGET_PARTIAL_REG_STALL 19843 && ix86_match_ccmode (insn, CCNOmode) 19844 && true_regnum (operands[2]) != 0 19845 && peep2_reg_dead_p (1, operands[2])" 19846 [(parallel 19847 [(set (match_dup 0) 19848 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 19849 (const_int 0)])) 19850 (set (match_dup 2) 19851 (and:QI (match_dup 2) (match_dup 3)))])] 19852 "") 19853 19854(define_peephole2 19855 [(set (match_operand 0 "flags_reg_operand" "") 19856 (match_operator 1 "compare_operator" 19857 [(and:SI 19858 (zero_extract:SI 19859 (match_operand 2 "ext_register_operand" "") 19860 (const_int 8) 19861 (const_int 8)) 19862 (match_operand 3 "const_int_operand" "")) 19863 (const_int 0)]))] 19864 "! TARGET_PARTIAL_REG_STALL 19865 && ix86_match_ccmode (insn, CCNOmode) 19866 && true_regnum (operands[2]) != 0 19867 && peep2_reg_dead_p (1, operands[2])" 19868 [(parallel [(set (match_dup 0) 19869 (match_op_dup 1 19870 [(and:SI 19871 (zero_extract:SI 19872 (match_dup 2) 19873 (const_int 8) 19874 (const_int 8)) 19875 (match_dup 3)) 19876 (const_int 0)])) 19877 (set (zero_extract:SI (match_dup 2) 19878 (const_int 8) 19879 (const_int 8)) 19880 (and:SI 19881 (zero_extract:SI 19882 (match_dup 2) 19883 (const_int 8) 19884 (const_int 8)) 19885 (match_dup 3)))])] 19886 "") 19887 19888;; Don't do logical operations with memory inputs. 19889(define_peephole2 19890 [(match_scratch:SI 2 "r") 19891 (parallel [(set (match_operand:SI 0 "register_operand" "") 19892 (match_operator:SI 3 "arith_or_logical_operator" 19893 [(match_dup 0) 19894 (match_operand:SI 1 "memory_operand" "")])) 19895 (clobber (reg:CC FLAGS_REG))])] 19896 "! optimize_size && ! TARGET_READ_MODIFY" 19897 [(set (match_dup 2) (match_dup 1)) 19898 (parallel [(set (match_dup 0) 19899 (match_op_dup 3 [(match_dup 0) (match_dup 2)])) 19900 (clobber (reg:CC FLAGS_REG))])] 19901 "") 19902 19903(define_peephole2 19904 [(match_scratch:SI 2 "r") 19905 (parallel [(set (match_operand:SI 0 "register_operand" "") 19906 (match_operator:SI 3 "arith_or_logical_operator" 19907 [(match_operand:SI 1 "memory_operand" "") 19908 (match_dup 0)])) 19909 (clobber (reg:CC FLAGS_REG))])] 19910 "! optimize_size && ! TARGET_READ_MODIFY" 19911 [(set (match_dup 2) (match_dup 1)) 19912 (parallel [(set (match_dup 0) 19913 (match_op_dup 3 [(match_dup 2) (match_dup 0)])) 19914 (clobber (reg:CC FLAGS_REG))])] 19915 "") 19916 19917; Don't do logical operations with memory outputs 19918; 19919; These two don't make sense for PPro/PII -- we're expanding a 4-uop 19920; instruction into two 1-uop insns plus a 2-uop insn. That last has 19921; the same decoder scheduling characteristics as the original. 19922 19923(define_peephole2 19924 [(match_scratch:SI 2 "r") 19925 (parallel [(set (match_operand:SI 0 "memory_operand" "") 19926 (match_operator:SI 3 "arith_or_logical_operator" 19927 [(match_dup 0) 19928 (match_operand:SI 1 "nonmemory_operand" "")])) 19929 (clobber (reg:CC FLAGS_REG))])] 19930 "! optimize_size && ! TARGET_READ_MODIFY_WRITE" 19931 [(set (match_dup 2) (match_dup 0)) 19932 (parallel [(set (match_dup 2) 19933 (match_op_dup 3 [(match_dup 2) (match_dup 1)])) 19934 (clobber (reg:CC FLAGS_REG))]) 19935 (set (match_dup 0) (match_dup 2))] 19936 "") 19937 19938(define_peephole2 19939 [(match_scratch:SI 2 "r") 19940 (parallel [(set (match_operand:SI 0 "memory_operand" "") 19941 (match_operator:SI 3 "arith_or_logical_operator" 19942 [(match_operand:SI 1 "nonmemory_operand" "") 19943 (match_dup 0)])) 19944 (clobber (reg:CC FLAGS_REG))])] 19945 "! optimize_size && ! TARGET_READ_MODIFY_WRITE" 19946 [(set (match_dup 2) (match_dup 0)) 19947 (parallel [(set (match_dup 2) 19948 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 19949 (clobber (reg:CC FLAGS_REG))]) 19950 (set (match_dup 0) (match_dup 2))] 19951 "") 19952 19953;; Attempt to always use XOR for zeroing registers. 19954(define_peephole2 19955 [(set (match_operand 0 "register_operand" "") 19956 (match_operand 1 "const0_operand" ""))] 19957 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD 19958 && (! TARGET_USE_MOV0 || optimize_size) 19959 && GENERAL_REG_P (operands[0]) 19960 && peep2_regno_dead_p (0, FLAGS_REG)" 19961 [(parallel [(set (match_dup 0) (const_int 0)) 19962 (clobber (reg:CC FLAGS_REG))])] 19963{ 19964 operands[0] = gen_lowpart (word_mode, operands[0]); 19965}) 19966 19967(define_peephole2 19968 [(set (strict_low_part (match_operand 0 "register_operand" "")) 19969 (const_int 0))] 19970 "(GET_MODE (operands[0]) == QImode 19971 || GET_MODE (operands[0]) == HImode) 19972 && (! TARGET_USE_MOV0 || optimize_size) 19973 && peep2_regno_dead_p (0, FLAGS_REG)" 19974 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0)) 19975 (clobber (reg:CC FLAGS_REG))])]) 19976 19977;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg. 19978(define_peephole2 19979 [(set (match_operand 0 "register_operand" "") 19980 (const_int -1))] 19981 "(GET_MODE (operands[0]) == HImode 19982 || GET_MODE (operands[0]) == SImode 19983 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT)) 19984 && (optimize_size || TARGET_PENTIUM) 19985 && peep2_regno_dead_p (0, FLAGS_REG)" 19986 [(parallel [(set (match_dup 0) (const_int -1)) 19987 (clobber (reg:CC FLAGS_REG))])] 19988 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode, 19989 operands[0]);") 19990 19991;; Attempt to convert simple leas to adds. These can be created by 19992;; move expanders. 19993(define_peephole2 19994 [(set (match_operand:SI 0 "register_operand" "") 19995 (plus:SI (match_dup 0) 19996 (match_operand:SI 1 "nonmemory_operand" "")))] 19997 "peep2_regno_dead_p (0, FLAGS_REG)" 19998 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) 19999 (clobber (reg:CC FLAGS_REG))])] 20000 "") 20001 20002(define_peephole2 20003 [(set (match_operand:SI 0 "register_operand" "") 20004 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "") 20005 (match_operand:DI 2 "nonmemory_operand" "")) 0))] 20006 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])" 20007 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2))) 20008 (clobber (reg:CC FLAGS_REG))])] 20009 "operands[2] = gen_lowpart (SImode, operands[2]);") 20010 20011(define_peephole2 20012 [(set (match_operand:DI 0 "register_operand" "") 20013 (plus:DI (match_dup 0) 20014 (match_operand:DI 1 "x86_64_general_operand" "")))] 20015 "peep2_regno_dead_p (0, FLAGS_REG)" 20016 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1))) 20017 (clobber (reg:CC FLAGS_REG))])] 20018 "") 20019 20020(define_peephole2 20021 [(set (match_operand:SI 0 "register_operand" "") 20022 (mult:SI (match_dup 0) 20023 (match_operand:SI 1 "const_int_operand" "")))] 20024 "exact_log2 (INTVAL (operands[1])) >= 0 20025 && peep2_regno_dead_p (0, FLAGS_REG)" 20026 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) 20027 (clobber (reg:CC FLAGS_REG))])] 20028 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));") 20029 20030(define_peephole2 20031 [(set (match_operand:DI 0 "register_operand" "") 20032 (mult:DI (match_dup 0) 20033 (match_operand:DI 1 "const_int_operand" "")))] 20034 "exact_log2 (INTVAL (operands[1])) >= 0 20035 && peep2_regno_dead_p (0, FLAGS_REG)" 20036 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2))) 20037 (clobber (reg:CC FLAGS_REG))])] 20038 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));") 20039 20040(define_peephole2 20041 [(set (match_operand:SI 0 "register_operand" "") 20042 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "") 20043 (match_operand:DI 2 "const_int_operand" "")) 0))] 20044 "exact_log2 (INTVAL (operands[2])) >= 0 20045 && REGNO (operands[0]) == REGNO (operands[1]) 20046 && peep2_regno_dead_p (0, FLAGS_REG)" 20047 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2))) 20048 (clobber (reg:CC FLAGS_REG))])] 20049 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));") 20050 20051;; The ESP adjustments can be done by the push and pop instructions. Resulting 20052;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On 20053;; many CPUs it is also faster, since special hardware to avoid esp 20054;; dependencies is present. 20055 20056;; While some of these conversions may be done using splitters, we use peepholes 20057;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL. 20058 20059;; Convert prologue esp subtractions to push. 20060;; We need register to push. In order to keep verify_flow_info happy we have 20061;; two choices 20062;; - use scratch and clobber it in order to avoid dependencies 20063;; - use already live register 20064;; We can't use the second way right now, since there is no reliable way how to 20065;; verify that given register is live. First choice will also most likely in 20066;; fewer dependencies. On the place of esp adjustments it is very likely that 20067;; call clobbered registers are dead. We may want to use base pointer as an 20068;; alternative when no register is available later. 20069 20070(define_peephole2 20071 [(match_scratch:SI 0 "r") 20072 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) 20073 (clobber (reg:CC FLAGS_REG)) 20074 (clobber (mem:BLK (scratch)))])] 20075 "optimize_size || !TARGET_SUB_ESP_4" 20076 [(clobber (match_dup 0)) 20077 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 20078 (clobber (mem:BLK (scratch)))])]) 20079 20080(define_peephole2 20081 [(match_scratch:SI 0 "r") 20082 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 20083 (clobber (reg:CC FLAGS_REG)) 20084 (clobber (mem:BLK (scratch)))])] 20085 "optimize_size || !TARGET_SUB_ESP_8" 20086 [(clobber (match_dup 0)) 20087 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 20088 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 20089 (clobber (mem:BLK (scratch)))])]) 20090 20091;; Convert esp subtractions to push. 20092(define_peephole2 20093 [(match_scratch:SI 0 "r") 20094 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) 20095 (clobber (reg:CC FLAGS_REG))])] 20096 "optimize_size || !TARGET_SUB_ESP_4" 20097 [(clobber (match_dup 0)) 20098 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))]) 20099 20100(define_peephole2 20101 [(match_scratch:SI 0 "r") 20102 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) 20103 (clobber (reg:CC FLAGS_REG))])] 20104 "optimize_size || !TARGET_SUB_ESP_8" 20105 [(clobber (match_dup 0)) 20106 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0)) 20107 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))]) 20108 20109;; Convert epilogue deallocator to pop. 20110(define_peephole2 20111 [(match_scratch:SI 0 "r") 20112 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20113 (clobber (reg:CC FLAGS_REG)) 20114 (clobber (mem:BLK (scratch)))])] 20115 "optimize_size || !TARGET_ADD_ESP_4" 20116 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20117 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20118 (clobber (mem:BLK (scratch)))])] 20119 "") 20120 20121;; Two pops case is tricky, since pop causes dependency on destination register. 20122;; We use two registers if available. 20123(define_peephole2 20124 [(match_scratch:SI 0 "r") 20125 (match_scratch:SI 1 "r") 20126 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 20127 (clobber (reg:CC FLAGS_REG)) 20128 (clobber (mem:BLK (scratch)))])] 20129 "optimize_size || !TARGET_ADD_ESP_8" 20130 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20131 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20132 (clobber (mem:BLK (scratch)))]) 20133 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG))) 20134 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20135 "") 20136 20137(define_peephole2 20138 [(match_scratch:SI 0 "r") 20139 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 20140 (clobber (reg:CC FLAGS_REG)) 20141 (clobber (mem:BLK (scratch)))])] 20142 "optimize_size" 20143 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20144 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20145 (clobber (mem:BLK (scratch)))]) 20146 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20147 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20148 "") 20149 20150;; Convert esp additions to pop. 20151(define_peephole2 20152 [(match_scratch:SI 0 "r") 20153 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4))) 20154 (clobber (reg:CC FLAGS_REG))])] 20155 "" 20156 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20157 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20158 "") 20159 20160;; Two pops case is tricky, since pop causes dependency on destination register. 20161;; We use two registers if available. 20162(define_peephole2 20163 [(match_scratch:SI 0 "r") 20164 (match_scratch:SI 1 "r") 20165 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 20166 (clobber (reg:CC FLAGS_REG))])] 20167 "" 20168 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20169 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))]) 20170 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG))) 20171 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20172 "") 20173 20174(define_peephole2 20175 [(match_scratch:SI 0 "r") 20176 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) 20177 (clobber (reg:CC FLAGS_REG))])] 20178 "optimize_size" 20179 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20180 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))]) 20181 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG))) 20182 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])] 20183 "") 20184 20185;; Convert compares with 1 to shorter inc/dec operations when CF is not 20186;; required and register dies. Similarly for 128 to plus -128. 20187(define_peephole2 20188 [(set (match_operand 0 "flags_reg_operand" "") 20189 (match_operator 1 "compare_operator" 20190 [(match_operand 2 "register_operand" "") 20191 (match_operand 3 "const_int_operand" "")]))] 20192 "(INTVAL (operands[3]) == -1 20193 || INTVAL (operands[3]) == 1 20194 || INTVAL (operands[3]) == 128) 20195 && ix86_match_ccmode (insn, CCGCmode) 20196 && peep2_reg_dead_p (1, operands[2])" 20197 [(parallel [(set (match_dup 0) 20198 (match_op_dup 1 [(match_dup 2) (match_dup 3)])) 20199 (clobber (match_dup 2))])] 20200 "") 20201 20202(define_peephole2 20203 [(match_scratch:DI 0 "r") 20204 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 20205 (clobber (reg:CC FLAGS_REG)) 20206 (clobber (mem:BLK (scratch)))])] 20207 "optimize_size || !TARGET_SUB_ESP_4" 20208 [(clobber (match_dup 0)) 20209 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 20210 (clobber (mem:BLK (scratch)))])]) 20211 20212(define_peephole2 20213 [(match_scratch:DI 0 "r") 20214 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16))) 20215 (clobber (reg:CC FLAGS_REG)) 20216 (clobber (mem:BLK (scratch)))])] 20217 "optimize_size || !TARGET_SUB_ESP_8" 20218 [(clobber (match_dup 0)) 20219 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 20220 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 20221 (clobber (mem:BLK (scratch)))])]) 20222 20223;; Convert esp subtractions to push. 20224(define_peephole2 20225 [(match_scratch:DI 0 "r") 20226 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8))) 20227 (clobber (reg:CC FLAGS_REG))])] 20228 "optimize_size || !TARGET_SUB_ESP_4" 20229 [(clobber (match_dup 0)) 20230 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))]) 20231 20232(define_peephole2 20233 [(match_scratch:DI 0 "r") 20234 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16))) 20235 (clobber (reg:CC FLAGS_REG))])] 20236 "optimize_size || !TARGET_SUB_ESP_8" 20237 [(clobber (match_dup 0)) 20238 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0)) 20239 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))]) 20240 20241;; Convert epilogue deallocator to pop. 20242(define_peephole2 20243 [(match_scratch:DI 0 "r") 20244 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20245 (clobber (reg:CC FLAGS_REG)) 20246 (clobber (mem:BLK (scratch)))])] 20247 "optimize_size || !TARGET_ADD_ESP_4" 20248 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20249 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20250 (clobber (mem:BLK (scratch)))])] 20251 "") 20252 20253;; Two pops case is tricky, since pop causes dependency on destination register. 20254;; We use two registers if available. 20255(define_peephole2 20256 [(match_scratch:DI 0 "r") 20257 (match_scratch:DI 1 "r") 20258 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20259 (clobber (reg:CC FLAGS_REG)) 20260 (clobber (mem:BLK (scratch)))])] 20261 "optimize_size || !TARGET_ADD_ESP_8" 20262 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20263 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20264 (clobber (mem:BLK (scratch)))]) 20265 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG))) 20266 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20267 "") 20268 20269(define_peephole2 20270 [(match_scratch:DI 0 "r") 20271 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20272 (clobber (reg:CC FLAGS_REG)) 20273 (clobber (mem:BLK (scratch)))])] 20274 "optimize_size" 20275 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20276 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20277 (clobber (mem:BLK (scratch)))]) 20278 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20279 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20280 "") 20281 20282;; Convert esp additions to pop. 20283(define_peephole2 20284 [(match_scratch:DI 0 "r") 20285 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8))) 20286 (clobber (reg:CC FLAGS_REG))])] 20287 "" 20288 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20289 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20290 "") 20291 20292;; Two pops case is tricky, since pop causes dependency on destination register. 20293;; We use two registers if available. 20294(define_peephole2 20295 [(match_scratch:DI 0 "r") 20296 (match_scratch:DI 1 "r") 20297 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20298 (clobber (reg:CC FLAGS_REG))])] 20299 "" 20300 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20301 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))]) 20302 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG))) 20303 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20304 "") 20305 20306(define_peephole2 20307 [(match_scratch:DI 0 "r") 20308 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16))) 20309 (clobber (reg:CC FLAGS_REG))])] 20310 "optimize_size" 20311 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20312 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))]) 20313 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG))) 20314 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])] 20315 "") 20316 20317;; Convert imul by three, five and nine into lea 20318(define_peephole2 20319 [(parallel 20320 [(set (match_operand:SI 0 "register_operand" "") 20321 (mult:SI (match_operand:SI 1 "register_operand" "") 20322 (match_operand:SI 2 "const_int_operand" ""))) 20323 (clobber (reg:CC FLAGS_REG))])] 20324 "INTVAL (operands[2]) == 3 20325 || INTVAL (operands[2]) == 5 20326 || INTVAL (operands[2]) == 9" 20327 [(set (match_dup 0) 20328 (plus:SI (mult:SI (match_dup 1) (match_dup 2)) 20329 (match_dup 1)))] 20330 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20331 20332(define_peephole2 20333 [(parallel 20334 [(set (match_operand:SI 0 "register_operand" "") 20335 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "") 20336 (match_operand:SI 2 "const_int_operand" ""))) 20337 (clobber (reg:CC FLAGS_REG))])] 20338 "!optimize_size 20339 && (INTVAL (operands[2]) == 3 20340 || INTVAL (operands[2]) == 5 20341 || INTVAL (operands[2]) == 9)" 20342 [(set (match_dup 0) (match_dup 1)) 20343 (set (match_dup 0) 20344 (plus:SI (mult:SI (match_dup 0) (match_dup 2)) 20345 (match_dup 0)))] 20346 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20347 20348(define_peephole2 20349 [(parallel 20350 [(set (match_operand:DI 0 "register_operand" "") 20351 (mult:DI (match_operand:DI 1 "register_operand" "") 20352 (match_operand:DI 2 "const_int_operand" ""))) 20353 (clobber (reg:CC FLAGS_REG))])] 20354 "TARGET_64BIT 20355 && (INTVAL (operands[2]) == 3 20356 || INTVAL (operands[2]) == 5 20357 || INTVAL (operands[2]) == 9)" 20358 [(set (match_dup 0) 20359 (plus:DI (mult:DI (match_dup 1) (match_dup 2)) 20360 (match_dup 1)))] 20361 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20362 20363(define_peephole2 20364 [(parallel 20365 [(set (match_operand:DI 0 "register_operand" "") 20366 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "") 20367 (match_operand:DI 2 "const_int_operand" ""))) 20368 (clobber (reg:CC FLAGS_REG))])] 20369 "TARGET_64BIT 20370 && !optimize_size 20371 && (INTVAL (operands[2]) == 3 20372 || INTVAL (operands[2]) == 5 20373 || INTVAL (operands[2]) == 9)" 20374 [(set (match_dup 0) (match_dup 1)) 20375 (set (match_dup 0) 20376 (plus:DI (mult:DI (match_dup 0) (match_dup 2)) 20377 (match_dup 0)))] 20378 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); }) 20379 20380;; Imul $32bit_imm, mem, reg is vector decoded, while 20381;; imul $32bit_imm, reg, reg is direct decoded. 20382(define_peephole2 20383 [(match_scratch:DI 3 "r") 20384 (parallel [(set (match_operand:DI 0 "register_operand" "") 20385 (mult:DI (match_operand:DI 1 "memory_operand" "") 20386 (match_operand:DI 2 "immediate_operand" ""))) 20387 (clobber (reg:CC FLAGS_REG))])] 20388 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size 20389 && !satisfies_constraint_K (operands[2])" 20390 [(set (match_dup 3) (match_dup 1)) 20391 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2))) 20392 (clobber (reg:CC FLAGS_REG))])] 20393"") 20394 20395(define_peephole2 20396 [(match_scratch:SI 3 "r") 20397 (parallel [(set (match_operand:SI 0 "register_operand" "") 20398 (mult:SI (match_operand:SI 1 "memory_operand" "") 20399 (match_operand:SI 2 "immediate_operand" ""))) 20400 (clobber (reg:CC FLAGS_REG))])] 20401 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size 20402 && !satisfies_constraint_K (operands[2])" 20403 [(set (match_dup 3) (match_dup 1)) 20404 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2))) 20405 (clobber (reg:CC FLAGS_REG))])] 20406"") 20407 20408(define_peephole2 20409 [(match_scratch:SI 3 "r") 20410 (parallel [(set (match_operand:DI 0 "register_operand" "") 20411 (zero_extend:DI 20412 (mult:SI (match_operand:SI 1 "memory_operand" "") 20413 (match_operand:SI 2 "immediate_operand" "")))) 20414 (clobber (reg:CC FLAGS_REG))])] 20415 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size 20416 && !satisfies_constraint_K (operands[2])" 20417 [(set (match_dup 3) (match_dup 1)) 20418 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2)))) 20419 (clobber (reg:CC FLAGS_REG))])] 20420"") 20421 20422;; imul $8/16bit_imm, regmem, reg is vector decoded. 20423;; Convert it into imul reg, reg 20424;; It would be better to force assembler to encode instruction using long 20425;; immediate, but there is apparently no way to do so. 20426(define_peephole2 20427 [(parallel [(set (match_operand:DI 0 "register_operand" "") 20428 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "") 20429 (match_operand:DI 2 "const_int_operand" ""))) 20430 (clobber (reg:CC FLAGS_REG))]) 20431 (match_scratch:DI 3 "r")] 20432 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size 20433 && satisfies_constraint_K (operands[2])" 20434 [(set (match_dup 3) (match_dup 2)) 20435 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3))) 20436 (clobber (reg:CC FLAGS_REG))])] 20437{ 20438 if (!rtx_equal_p (operands[0], operands[1])) 20439 emit_move_insn (operands[0], operands[1]); 20440}) 20441 20442(define_peephole2 20443 [(parallel [(set (match_operand:SI 0 "register_operand" "") 20444 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "") 20445 (match_operand:SI 2 "const_int_operand" ""))) 20446 (clobber (reg:CC FLAGS_REG))]) 20447 (match_scratch:SI 3 "r")] 20448 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size 20449 && satisfies_constraint_K (operands[2])" 20450 [(set (match_dup 3) (match_dup 2)) 20451 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3))) 20452 (clobber (reg:CC FLAGS_REG))])] 20453{ 20454 if (!rtx_equal_p (operands[0], operands[1])) 20455 emit_move_insn (operands[0], operands[1]); 20456}) 20457 20458(define_peephole2 20459 [(parallel [(set (match_operand:HI 0 "register_operand" "") 20460 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "") 20461 (match_operand:HI 2 "immediate_operand" ""))) 20462 (clobber (reg:CC FLAGS_REG))]) 20463 (match_scratch:HI 3 "r")] 20464 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size" 20465 [(set (match_dup 3) (match_dup 2)) 20466 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3))) 20467 (clobber (reg:CC FLAGS_REG))])] 20468{ 20469 if (!rtx_equal_p (operands[0], operands[1])) 20470 emit_move_insn (operands[0], operands[1]); 20471}) 20472 20473;; After splitting up read-modify operations, array accesses with memory 20474;; operands might end up in form: 20475;; sall $2, %eax 20476;; movl 4(%esp), %edx 20477;; addl %edx, %eax 20478;; instead of pre-splitting: 20479;; sall $2, %eax 20480;; addl 4(%esp), %eax 20481;; Turn it into: 20482;; movl 4(%esp), %edx 20483;; leal (%edx,%eax,4), %eax 20484 20485(define_peephole2 20486 [(parallel [(set (match_operand 0 "register_operand" "") 20487 (ashift (match_operand 1 "register_operand" "") 20488 (match_operand 2 "const_int_operand" ""))) 20489 (clobber (reg:CC FLAGS_REG))]) 20490 (set (match_operand 3 "register_operand") 20491 (match_operand 4 "x86_64_general_operand" "")) 20492 (parallel [(set (match_operand 5 "register_operand" "") 20493 (plus (match_operand 6 "register_operand" "") 20494 (match_operand 7 "register_operand" ""))) 20495 (clobber (reg:CC FLAGS_REG))])] 20496 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3 20497 /* Validate MODE for lea. */ 20498 && ((!TARGET_PARTIAL_REG_STALL 20499 && (GET_MODE (operands[0]) == QImode 20500 || GET_MODE (operands[0]) == HImode)) 20501 || GET_MODE (operands[0]) == SImode 20502 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) 20503 /* We reorder load and the shift. */ 20504 && !rtx_equal_p (operands[1], operands[3]) 20505 && !reg_overlap_mentioned_p (operands[0], operands[4]) 20506 /* Last PLUS must consist of operand 0 and 3. */ 20507 && !rtx_equal_p (operands[0], operands[3]) 20508 && (rtx_equal_p (operands[3], operands[6]) 20509 || rtx_equal_p (operands[3], operands[7])) 20510 && (rtx_equal_p (operands[0], operands[6]) 20511 || rtx_equal_p (operands[0], operands[7])) 20512 /* The intermediate operand 0 must die or be same as output. */ 20513 && (rtx_equal_p (operands[0], operands[5]) 20514 || peep2_reg_dead_p (3, operands[0]))" 20515 [(set (match_dup 3) (match_dup 4)) 20516 (set (match_dup 0) (match_dup 1))] 20517{ 20518 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode; 20519 int scale = 1 << INTVAL (operands[2]); 20520 rtx index = gen_lowpart (Pmode, operands[1]); 20521 rtx base = gen_lowpart (Pmode, operands[3]); 20522 rtx dest = gen_lowpart (mode, operands[5]); 20523 20524 operands[1] = gen_rtx_PLUS (Pmode, base, 20525 gen_rtx_MULT (Pmode, index, GEN_INT (scale))); 20526 if (mode != Pmode) 20527 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); 20528 operands[0] = dest; 20529}) 20530 20531;; Call-value patterns last so that the wildcard operand does not 20532;; disrupt insn-recog's switch tables. 20533 20534(define_insn "*call_value_pop_0" 20535 [(set (match_operand 0 "" "") 20536 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) 20537 (match_operand:SI 2 "" ""))) 20538 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 20539 (match_operand:SI 3 "immediate_operand" "")))] 20540 "!TARGET_64BIT" 20541{ 20542 if (SIBLING_CALL_P (insn)) 20543 return "jmp\t%P1"; 20544 else 20545 return "call\t%P1"; 20546} 20547 [(set_attr "type" "callv")]) 20548 20549(define_insn "*call_value_pop_1" 20550 [(set (match_operand 0 "" "") 20551 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm")) 20552 (match_operand:SI 2 "" ""))) 20553 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) 20554 (match_operand:SI 3 "immediate_operand" "i")))] 20555 "!TARGET_64BIT" 20556{ 20557 if (constant_call_address_operand (operands[1], Pmode)) 20558 { 20559 if (SIBLING_CALL_P (insn)) 20560 return "jmp\t%P1"; 20561 else 20562 return "call\t%P1"; 20563 } 20564 if (SIBLING_CALL_P (insn)) 20565 return "jmp\t%A1"; 20566 else 20567 return "call\t%A1"; 20568} 20569 [(set_attr "type" "callv")]) 20570 20571(define_insn "*call_value_0" 20572 [(set (match_operand 0 "" "") 20573 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" "")) 20574 (match_operand:SI 2 "" "")))] 20575 "!TARGET_64BIT" 20576{ 20577 if (SIBLING_CALL_P (insn)) 20578 return "jmp\t%P1"; 20579 else 20580 return "call\t%P1"; 20581} 20582 [(set_attr "type" "callv")]) 20583 20584(define_insn "*call_value_0_rex64" 20585 [(set (match_operand 0 "" "") 20586 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) 20587 (match_operand:DI 2 "const_int_operand" "")))] 20588 "TARGET_64BIT" 20589{ 20590 if (SIBLING_CALL_P (insn)) 20591 return "jmp\t%P1"; 20592 else 20593 return "call\t%P1"; 20594} 20595 [(set_attr "type" "callv")]) 20596 20597(define_insn "*call_value_1" 20598 [(set (match_operand 0 "" "") 20599 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm")) 20600 (match_operand:SI 2 "" "")))] 20601 "!SIBLING_CALL_P (insn) && !TARGET_64BIT" 20602{ 20603 if (constant_call_address_operand (operands[1], Pmode)) 20604 return "call\t%P1"; 20605 return "call\t%A1"; 20606} 20607 [(set_attr "type" "callv")]) 20608 20609(define_insn "*sibcall_value_1" 20610 [(set (match_operand 0 "" "") 20611 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a")) 20612 (match_operand:SI 2 "" "")))] 20613 "SIBLING_CALL_P (insn) && !TARGET_64BIT" 20614{ 20615 if (constant_call_address_operand (operands[1], Pmode)) 20616 return "jmp\t%P1"; 20617 return "jmp\t%A1"; 20618} 20619 [(set_attr "type" "callv")]) 20620 20621(define_insn "*call_value_1_rex64" 20622 [(set (match_operand 0 "" "") 20623 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm")) 20624 (match_operand:DI 2 "" "")))] 20625 "!SIBLING_CALL_P (insn) && TARGET_64BIT" 20626{ 20627 if (constant_call_address_operand (operands[1], Pmode)) 20628 return "call\t%P1"; 20629 return "call\t%A1"; 20630} 20631 [(set_attr "type" "callv")]) 20632 20633(define_insn "*sibcall_value_1_rex64" 20634 [(set (match_operand 0 "" "") 20635 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" "")) 20636 (match_operand:DI 2 "" "")))] 20637 "SIBLING_CALL_P (insn) && TARGET_64BIT" 20638 "jmp\t%P1" 20639 [(set_attr "type" "callv")]) 20640 20641(define_insn "*sibcall_value_1_rex64_v" 20642 [(set (match_operand 0 "" "") 20643 (call (mem:QI (reg:DI 40)) 20644 (match_operand:DI 1 "" "")))] 20645 "SIBLING_CALL_P (insn) && TARGET_64BIT" 20646 "jmp\t*%%r11" 20647 [(set_attr "type" "callv")]) 20648 20649;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5. 20650;; That, however, is usually mapped by the OS to SIGSEGV, which is often 20651;; caught for use by garbage collectors and the like. Using an insn that 20652;; maps to SIGILL makes it more likely the program will rightfully die. 20653;; Keeping with tradition, "6" is in honor of #UD. 20654(define_insn "trap" 20655 [(trap_if (const_int 1) (const_int 6))] 20656 "" 20657 { return ASM_SHORT "0x0b0f"; } 20658 [(set_attr "length" "2")]) 20659 20660(define_expand "sse_prologue_save" 20661 [(parallel [(set (match_operand:BLK 0 "" "") 20662 (unspec:BLK [(reg:DI 21) 20663 (reg:DI 22) 20664 (reg:DI 23) 20665 (reg:DI 24) 20666 (reg:DI 25) 20667 (reg:DI 26) 20668 (reg:DI 27) 20669 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE)) 20670 (use (match_operand:DI 1 "register_operand" "")) 20671 (use (match_operand:DI 2 "immediate_operand" "")) 20672 (use (label_ref:DI (match_operand 3 "" "")))])] 20673 "TARGET_64BIT" 20674 "") 20675 20676(define_insn "*sse_prologue_save_insn" 20677 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R") 20678 (match_operand:DI 4 "const_int_operand" "n"))) 20679 (unspec:BLK [(reg:DI 21) 20680 (reg:DI 22) 20681 (reg:DI 23) 20682 (reg:DI 24) 20683 (reg:DI 25) 20684 (reg:DI 26) 20685 (reg:DI 27) 20686 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE)) 20687 (use (match_operand:DI 1 "register_operand" "r")) 20688 (use (match_operand:DI 2 "const_int_operand" "i")) 20689 (use (label_ref:DI (match_operand 3 "" "X")))] 20690 "TARGET_64BIT 20691 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128 20692 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128" 20693 "* 20694{ 20695 int i; 20696 operands[0] = gen_rtx_MEM (Pmode, 20697 gen_rtx_PLUS (Pmode, operands[0], operands[4])); 20698 output_asm_insn (\"jmp\\t%A1\", operands); 20699 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--) 20700 { 20701 operands[4] = adjust_address (operands[0], DImode, i*16); 20702 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i)); 20703 PUT_MODE (operands[4], TImode); 20704 if (GET_CODE (XEXP (operands[0], 0)) != PLUS) 20705 output_asm_insn (\"rex\", operands); 20706 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands); 20707 } 20708 (*targetm.asm_out.internal_label) (asm_out_file, \"L\", 20709 CODE_LABEL_NUMBER (operands[3])); 20710 RET; 20711} 20712 " 20713 [(set_attr "type" "other") 20714 (set_attr "length_immediate" "0") 20715 (set_attr "length_address" "0") 20716 (set_attr "length" "135") 20717 (set_attr "memory" "store") 20718 (set_attr "modrm" "0") 20719 (set_attr "mode" "DI")]) 20720 20721(define_expand "prefetch" 20722 [(prefetch (match_operand 0 "address_operand" "") 20723 (match_operand:SI 1 "const_int_operand" "") 20724 (match_operand:SI 2 "const_int_operand" ""))] 20725 "TARGET_PREFETCH_SSE || TARGET_3DNOW" 20726{ 20727 int rw = INTVAL (operands[1]); 20728 int locality = INTVAL (operands[2]); 20729 20730 gcc_assert (rw == 0 || rw == 1); 20731 gcc_assert (locality >= 0 && locality <= 3); 20732 gcc_assert (GET_MODE (operands[0]) == Pmode 20733 || GET_MODE (operands[0]) == VOIDmode); 20734 20735 /* Use 3dNOW prefetch in case we are asking for write prefetch not 20736 supported by SSE counterpart or the SSE prefetch is not available 20737 (K6 machines). Otherwise use SSE prefetch as it allows specifying 20738 of locality. */ 20739 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw)) 20740 operands[2] = GEN_INT (3); 20741 else 20742 operands[1] = const0_rtx; 20743}) 20744 20745(define_insn "*prefetch_sse" 20746 [(prefetch (match_operand:SI 0 "address_operand" "p") 20747 (const_int 0) 20748 (match_operand:SI 1 "const_int_operand" ""))] 20749 "TARGET_PREFETCH_SSE && !TARGET_64BIT" 20750{ 20751 static const char * const patterns[4] = { 20752 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" 20753 }; 20754 20755 int locality = INTVAL (operands[1]); 20756 gcc_assert (locality >= 0 && locality <= 3); 20757 20758 return patterns[locality]; 20759} 20760 [(set_attr "type" "sse") 20761 (set_attr "memory" "none")]) 20762 20763(define_insn "*prefetch_sse_rex" 20764 [(prefetch (match_operand:DI 0 "address_operand" "p") 20765 (const_int 0) 20766 (match_operand:SI 1 "const_int_operand" ""))] 20767 "TARGET_PREFETCH_SSE && TARGET_64BIT" 20768{ 20769 static const char * const patterns[4] = { 20770 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" 20771 }; 20772 20773 int locality = INTVAL (operands[1]); 20774 gcc_assert (locality >= 0 && locality <= 3); 20775 20776 return patterns[locality]; 20777} 20778 [(set_attr "type" "sse") 20779 (set_attr "memory" "none")]) 20780 20781(define_insn "*prefetch_3dnow" 20782 [(prefetch (match_operand:SI 0 "address_operand" "p") 20783 (match_operand:SI 1 "const_int_operand" "n") 20784 (const_int 3))] 20785 "TARGET_3DNOW && !TARGET_64BIT" 20786{ 20787 if (INTVAL (operands[1]) == 0) 20788 return "prefetch\t%a0"; 20789 else 20790 return "prefetchw\t%a0"; 20791} 20792 [(set_attr "type" "mmx") 20793 (set_attr "memory" "none")]) 20794 20795(define_insn "*prefetch_3dnow_rex" 20796 [(prefetch (match_operand:DI 0 "address_operand" "p") 20797 (match_operand:SI 1 "const_int_operand" "n") 20798 (const_int 3))] 20799 "TARGET_3DNOW && TARGET_64BIT" 20800{ 20801 if (INTVAL (operands[1]) == 0) 20802 return "prefetch\t%a0"; 20803 else 20804 return "prefetchw\t%a0"; 20805} 20806 [(set_attr "type" "mmx") 20807 (set_attr "memory" "none")]) 20808 20809(define_expand "stack_protect_set" 20810 [(match_operand 0 "memory_operand" "") 20811 (match_operand 1 "memory_operand" "")] 20812 "" 20813{ 20814#ifdef TARGET_THREAD_SSP_OFFSET 20815 if (TARGET_64BIT) 20816 emit_insn (gen_stack_tls_protect_set_di (operands[0], 20817 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 20818 else 20819 emit_insn (gen_stack_tls_protect_set_si (operands[0], 20820 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 20821#else 20822 if (TARGET_64BIT) 20823 emit_insn (gen_stack_protect_set_di (operands[0], operands[1])); 20824 else 20825 emit_insn (gen_stack_protect_set_si (operands[0], operands[1])); 20826#endif 20827 DONE; 20828}) 20829 20830(define_insn "stack_protect_set_si" 20831 [(set (match_operand:SI 0 "memory_operand" "=m") 20832 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 20833 (set (match_scratch:SI 2 "=&r") (const_int 0)) 20834 (clobber (reg:CC FLAGS_REG))] 20835 "" 20836 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2" 20837 [(set_attr "type" "multi")]) 20838 20839(define_insn "stack_protect_set_di" 20840 [(set (match_operand:DI 0 "memory_operand" "=m") 20841 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 20842 (set (match_scratch:DI 2 "=&r") (const_int 0)) 20843 (clobber (reg:CC FLAGS_REG))] 20844 "TARGET_64BIT" 20845 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" 20846 [(set_attr "type" "multi")]) 20847 20848(define_insn "stack_tls_protect_set_si" 20849 [(set (match_operand:SI 0 "memory_operand" "=m") 20850 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET)) 20851 (set (match_scratch:SI 2 "=&r") (const_int 0)) 20852 (clobber (reg:CC FLAGS_REG))] 20853 "" 20854 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2" 20855 [(set_attr "type" "multi")]) 20856 20857(define_insn "stack_tls_protect_set_di" 20858 [(set (match_operand:DI 0 "memory_operand" "=m") 20859 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET)) 20860 (set (match_scratch:DI 2 "=&r") (const_int 0)) 20861 (clobber (reg:CC FLAGS_REG))] 20862 "TARGET_64BIT" 20863 { 20864 /* The kernel uses a different segment register for performance reasons; a 20865 system call would not have to trash the userspace segment register, 20866 which would be expensive */ 20867 if (ix86_cmodel != CM_KERNEL) 20868 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"; 20869 else 20870 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"; 20871 } 20872 [(set_attr "type" "multi")]) 20873 20874(define_expand "stack_protect_test" 20875 [(match_operand 0 "memory_operand" "") 20876 (match_operand 1 "memory_operand" "") 20877 (match_operand 2 "" "")] 20878 "" 20879{ 20880 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG); 20881 ix86_compare_op0 = operands[0]; 20882 ix86_compare_op1 = operands[1]; 20883 ix86_compare_emitted = flags; 20884 20885#ifdef TARGET_THREAD_SSP_OFFSET 20886 if (TARGET_64BIT) 20887 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0], 20888 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 20889 else 20890 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0], 20891 GEN_INT (TARGET_THREAD_SSP_OFFSET))); 20892#else 20893 if (TARGET_64BIT) 20894 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1])); 20895 else 20896 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1])); 20897#endif 20898 emit_jump_insn (gen_beq (operands[2])); 20899 DONE; 20900}) 20901 20902(define_insn "stack_protect_test_si" 20903 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 20904 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m") 20905 (match_operand:SI 2 "memory_operand" "m")] 20906 UNSPEC_SP_TEST)) 20907 (clobber (match_scratch:SI 3 "=&r"))] 20908 "" 20909 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}" 20910 [(set_attr "type" "multi")]) 20911 20912(define_insn "stack_protect_test_di" 20913 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 20914 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m") 20915 (match_operand:DI 2 "memory_operand" "m")] 20916 UNSPEC_SP_TEST)) 20917 (clobber (match_scratch:DI 3 "=&r"))] 20918 "TARGET_64BIT" 20919 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}" 20920 [(set_attr "type" "multi")]) 20921 20922(define_insn "stack_tls_protect_test_si" 20923 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 20924 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m") 20925 (match_operand:SI 2 "const_int_operand" "i")] 20926 UNSPEC_SP_TLS_TEST)) 20927 (clobber (match_scratch:SI 3 "=r"))] 20928 "" 20929 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}" 20930 [(set_attr "type" "multi")]) 20931 20932(define_insn "stack_tls_protect_test_di" 20933 [(set (match_operand:CCZ 0 "flags_reg_operand" "") 20934 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m") 20935 (match_operand:DI 2 "const_int_operand" "i")] 20936 UNSPEC_SP_TLS_TEST)) 20937 (clobber (match_scratch:DI 3 "=r"))] 20938 "TARGET_64BIT" 20939 { 20940 /* The kernel uses a different segment register for performance reasons; a 20941 system call would not have to trash the userspace segment register, 20942 which would be expensive */ 20943 if (ix86_cmodel != CM_KERNEL) 20944 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}"; 20945 else 20946 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}"; 20947 } 20948 [(set_attr "type" "multi")]) 20949 20950(include "sse.md") 20951(include "mmx.md") 20952(include "sync.md") 20953