i386.md revision 53176
1185573Srwatson; GCC machine description for Intel X86. 2155131Srwatson;; Copyright (C) 1988, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. 3168777Srwatson;; Mostly by William Schelter. 4155131Srwatson 5155131Srwatson;; This file is part of GNU CC. 6155131Srwatson 7155131Srwatson;; GNU CC is free software; you can redistribute it and/or modify 8168777Srwatson;; it under the terms of the GNU General Public License as published by 9155131Srwatson;; the Free Software Foundation; either version 2, or (at your option) 10155131Srwatson;; any later version. 11168777Srwatson 12185573Srwatson;; GNU CC is distributed in the hope that it will be useful, 13155131Srwatson;; but WITHOUT ANY WARRANTY; without even the implied warranty of 14168777Srwatson;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15168777Srwatson;; GNU General Public License for more details. 16155131Srwatson 17155131Srwatson;; You should have received a copy of the GNU General Public License 18155131Srwatson;; along with GNU CC; see the file COPYING. If not, write to 19155131Srwatson;; the Free Software Foundation, 59 Temple Place - Suite 330, 20155131Srwatson;; Boston, MA 02111-1307, USA. */ 21155131Srwatson 22155131Srwatson;; The original PO technology requires these to be ordered by speed, 23155131Srwatson;; so that assigner will pick the fastest. 24155131Srwatson 25155131Srwatson;; See file "rtl.def" for documentation on define_insn, match_*, et. al. 26155131Srwatson 27155131Srwatson;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code 28243750Srwatson;; updates for most instructions. 29155131Srwatson 30155364Srwatson;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register 31155131Srwatson;; constraint letters. 32155131Srwatson 33155131Srwatson;; the special asm out single letter directives following a '%' are: 34155131Srwatson;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of 35155131Srwatson;; operands[1]. 36155131Srwatson;; 'L' Print the opcode suffix for a 32-bit integer opcode. 37168777Srwatson;; 'W' Print the opcode suffix for a 16-bit integer opcode. 38155131Srwatson;; 'B' Print the opcode suffix for an 8-bit integer opcode. 39168777Srwatson;; 'Q' Print the opcode suffix for a 64-bit float opcode. 40168777Srwatson;; 'S' Print the opcode suffix for a 32-bit float opcode. 41155131Srwatson;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode. 42155131Srwatson;; 'J' Print the appropriate jump operand. 43155131Srwatson 44155131Srwatson;; 'b' Print the QImode name of the register for the indicated operand. 45155131Srwatson;; %b0 would print %al if operands[0] is reg 0. 46168777Srwatson;; 'w' Likewise, print the HImode name of the register. 47168777Srwatson;; 'k' Likewise, print the SImode name of the register. 48168777Srwatson;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh. 49155131Srwatson;; 'y' Print "st(0)" instead of "st" as a register. 50155131Srwatson 51185573Srwatson;; UNSPEC usage: 52168777Srwatson;; 0 This is a `scas' operation. The mode of the UNSPEC is always SImode. 53155131Srwatson;; operand 0 is the memory address to scan. 54155131Srwatson;; operand 1 is a register containing the value to scan for. The mode 55168777Srwatson;; of the scas opcode will be the same as the mode of this operand. 56155131Srwatson;; operand 2 is the known alignment of operand 0. 57155131Srwatson;; 1 This is a `sin' operation. The mode of the UNSPEC is MODE_FLOAT. 58155131Srwatson;; operand 0 is the argument for `sin'. 59155131Srwatson;; 2 This is a `cos' operation. The mode of the UNSPEC is MODE_FLOAT. 60168777Srwatson;; operand 0 is the argument for `cos'. 61168777Srwatson;; 3 This is part of a `stack probe' operation. The mode of the UNSPEC is 62168777Srwatson;; always SImode. operand 0 is the size of the stack allocation. 63155131Srwatson;; 4 This is the source of a fake SET of the frame pointer which is used to 64168777Srwatson;; prevent insns referencing it being scheduled across the initial 65168777Srwatson;; decrement of the stack pointer. 66155131Srwatson;; 5 This is a `bsf' operation. 67155131Srwatson;; 6 This is the @GOT offset of a PIC address. 68155131Srwatson;; 7 This is the @GOTOFF offset of a PIC address. 69168777Srwatson;; 8 This is a reference to a symbol's @PLT address. 70155131Srwatson 71155131Srwatson;; This shadows the processor_type enumeration, so changes must be made 72168777Srwatson;; to i386.h at the same time. 73155131Srwatson 74168777Srwatson;; $FreeBSD: head/contrib/gcc/config/i386/i386.md 53176 1999-11-15 04:28:55Z obrien $ 75155131Srwatson 76155131Srwatson(define_attr "type" 77155131Srwatson "integer,binary,memory,test,compare,fcompare,idiv,imul,lea,fld,fpop,fpdiv,fpmul" 78155131Srwatson (const_string "integer")) 79155131Srwatson 80155131Srwatson(define_attr "memory" "none,load,store" 81155131Srwatson (cond [(eq_attr "type" "idiv,lea") 82155131Srwatson (const_string "none") 83155131Srwatson 84155131Srwatson (eq_attr "type" "fld") 85155131Srwatson (const_string "load") 86155131Srwatson 87155290Srwatson (eq_attr "type" "test") 88155131Srwatson (if_then_else (match_operand 0 "memory_operand" "") 89168777Srwatson (const_string "load") 90155131Srwatson (const_string "none")) 91168777Srwatson 92155131Srwatson (eq_attr "type" "compare,fcompare") 93168777Srwatson (if_then_else (ior (match_operand 0 "memory_operand" "") 94155131Srwatson (match_operand 1 "memory_operand" "")) 95243750Srwatson (const_string "load") 96155131Srwatson (const_string "none")) 97185573Srwatson 98185573Srwatson (and (eq_attr "type" "integer,memory,fpop") 99155131Srwatson (match_operand 0 "memory_operand" "")) 100155131Srwatson (const_string "store") 101155131Srwatson 102168777Srwatson (and (eq_attr "type" "integer,memory,fpop") 103168777Srwatson (match_operand 1 "memory_operand" "")) 104168777Srwatson (const_string "load") 105162621Srwatson 106162621Srwatson (and (eq_attr "type" "binary,imul,fpmul,fpdiv") 107162621Srwatson (ior (match_operand 1 "memory_operand" "") 108168777Srwatson (match_operand 2 "memory_operand" ""))) 109168777Srwatson (const_string "load")] 110168777Srwatson 111162621Srwatson (const_string "none"))) 112162621Srwatson 113162621Srwatson;; Functional units 114162621Srwatson 115168777Srwatson; (define_function_unit NAME MULTIPLICITY SIMULTANEITY 116168777Srwatson; TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST]) 117168777Srwatson 118162621Srwatson; pentiumpro has a reservation station with 5 ports 119168777Srwatson; port 0 has integer, float add, integer divide, float divide, float 120168777Srwatson; multiply, and shifter units. 121168777Srwatson; port 1 has integer, and jump units. 122168777Srwatson; port 2 has the load address generation unit 123168777Srwatson; ports 3 and 4 have the store address generation units 124168777Srwatson 125168777Srwatson; pentium has two integer pipelines, the main u pipe and the secondary v pipe. 126168777Srwatson; and a float pipeline 127155131Srwatson 128168777Srwatson;; Floating point 129168777Srwatson 130168777Srwatson(define_function_unit "fp" 1 0 131168777Srwatson (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "i386,i486")) 132185573Srwatson 5 5) 133185573Srwatson 134155131Srwatson(define_function_unit "fp" 1 0 135168777Srwatson (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "pentium,pentiumpro")) 136155131Srwatson 3 0) 137155364Srwatson 138155364Srwatson(define_function_unit "fp" 1 0 139168777Srwatson (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentium")) 140168777Srwatson 7 0) 141168777Srwatson 142168777Srwatson(define_function_unit "fp" 1 0 143155131Srwatson (and (eq_attr "type" "fpmul") (eq_attr "cpu" "pentiumpro")) 144155131Srwatson 5 0) 145155131Srwatson 146155131Srwatson(define_function_unit "fp" 1 0 147168777Srwatson (and (eq_attr "type" "idiv") (eq_attr "cpu" "pentiumpro")) 148168777Srwatson 10 10) 149168777Srwatson 150168777Srwatson(define_function_unit "fp" 1 0 151155131Srwatson (and (eq_attr "type" "imul") (eq_attr "cpu" "pentiumpro")) 152162621Srwatson 6 0) 153162621Srwatson 154162621Srwatson(define_function_unit "fp" 1 0 155162621Srwatson (eq_attr "type" "fpdiv") 156162621Srwatson 10 10) 157162621Srwatson 158168777Srwatson(define_function_unit "fp" 1 0 159168777Srwatson (and (eq_attr "type" "fld") (eq_attr "cpu" "!pentiumpro,k6")) 160168777Srwatson 1 0) 161168777Srwatson 162168777Srwatson;; K6 FPU is not pipelined. 163162621Srwatson(define_function_unit "fp" 1 0 164162621Srwatson (and (eq_attr "type" "fpop,fpmul,fcompare") (eq_attr "cpu" "k6")) 165162621Srwatson 2 2) 166168777Srwatson 167168777Srwatson;; i386 and i486 have one integer unit, which need not be modeled 168168777Srwatson 169168777Srwatson(define_function_unit "integer" 2 0 170162621Srwatson (and (eq_attr "type" "integer,binary,test,compare,lea") (eq_attr "cpu" "pentium,pentiumpro")) 171162621Srwatson 1 0) 172162621Srwatson 173168777Srwatson(define_function_unit "integer" 2 0 174168777Srwatson (and (eq_attr "cpu" "k6") 175168777Srwatson (and (eq_attr "type" "integer,binary,test,compare") 176168777Srwatson (eq_attr "memory" "!load"))) 177168777Srwatson 1 0) 178155131Srwatson 179155364Srwatson;; Internally, K6 converts REG OP MEM instructions into a load (2 cycles) 180155131Srwatson;; and a register operation (1 cycle). 181155364Srwatson(define_function_unit "integer" 2 0 182168777Srwatson (and (eq_attr "cpu" "k6") 183168777Srwatson (and (eq_attr "type" "integer,binary,test,compare") 184168777Srwatson (eq_attr "memory" "load"))) 185168777Srwatson 3 0) 186168777Srwatson 187155131Srwatson;; Multiplies use one of the integer units 188168777Srwatson(define_function_unit "integer" 2 0 189155131Srwatson (and (eq_attr "cpu" "pentium") (eq_attr "type" "imul")) 190155131Srwatson 11 11) 191168777Srwatson 192168777Srwatson(define_function_unit "integer" 2 0 193168777Srwatson (and (eq_attr "cpu" "k6") (eq_attr "type" "imul")) 194168777Srwatson 2 2) 195155131Srwatson 196155131Srwatson(define_function_unit "integer" 2 0 197155131Srwatson (and (eq_attr "cpu" "pentium") (eq_attr "type" "idiv")) 198 25 25) 199 200(define_function_unit "integer" 2 0 201 (and (eq_attr "cpu" "k6") (eq_attr "type" "idiv")) 202 17 17) 203 204;; Pentium Pro and K6 have a separate load unit. 205(define_function_unit "load" 1 0 206 (and (eq_attr "cpu" "pentiumpro") (eq_attr "memory" "load")) 207 3 0) 208 209(define_function_unit "load" 1 0 210 (and (eq_attr "cpu" "k6") (eq_attr "memory" "load")) 211 2 0) 212 213;; Pentium Pro and K6 have a separate store unit. 214(define_function_unit "store" 1 0 215 (and (eq_attr "cpu" "pentiumpro,k6") (eq_attr "memory" "store")) 216 1 0) 217 218;; lea executes in the K6 store unit with 1 cycle latency 219(define_function_unit "store" 1 0 220 (and (eq_attr "cpu" "k6") (eq_attr "type" "lea")) 221 1 0) 222 223 224;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM". 225;; But restricting MEM here would mean that gcc could not remove a redundant 226;; test in cases like "incl MEM / je TARGET". 227;; 228;; We don't want to allow a constant operand for test insns because 229;; (set (cc0) (const_int foo)) has no mode information. Such insns will 230;; be folded while optimizing anyway. 231 232;; All test insns have expanders that save the operands away without 233;; actually generating RTL. The bCOND or sCOND (emitted immediately 234;; after the tstM or cmp) will actually emit the tstM or cmpM. 235 236;; Processor type -- this attribute must exactly match the processor_type 237;; enumeration in i386.h. 238 239(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6" 240 (const (symbol_ref "ix86_cpu"))) 241 242(define_insn "tstsi_1" 243 [(set (cc0) 244 (match_operand:SI 0 "nonimmediate_operand" "rm"))] 245 "" 246 "* 247{ 248 if (REG_P (operands[0])) 249 return AS2 (test%L0,%0,%0); 250 251 operands[1] = const0_rtx; 252 return AS2 (cmp%L0,%1,%0); 253}" 254 [(set_attr "type" "test")]) 255 256(define_expand "tstsi" 257 [(set (cc0) 258 (match_operand:SI 0 "nonimmediate_operand" ""))] 259 "" 260 " 261{ 262 i386_compare_gen = gen_tstsi_1; 263 i386_compare_op0 = operands[0]; 264 i386_compare_op1 = const0_rtx; 265 DONE; 266}") 267 268(define_insn "tsthi_1" 269 [(set (cc0) 270 (match_operand:HI 0 "nonimmediate_operand" "rm"))] 271 "" 272 "* 273{ 274 if (REG_P (operands[0])) 275 return AS2 (test%W0,%0,%0); 276 277 operands[1] = const0_rtx; 278 return AS2 (cmp%W0,%1,%0); 279}" 280 [(set_attr "type" "test")]) 281 282(define_expand "tsthi" 283 [(set (cc0) 284 (match_operand:HI 0 "nonimmediate_operand" ""))] 285 "" 286 " 287{ 288 i386_compare_gen = gen_tsthi_1; 289 i386_compare_op0 = operands[0]; 290 i386_compare_op1 = const0_rtx; 291 DONE; 292}") 293 294(define_insn "tstqi_1" 295 [(set (cc0) 296 (match_operand:QI 0 "nonimmediate_operand" "qm"))] 297 "" 298 "* 299{ 300 if (REG_P (operands[0])) 301 return AS2 (test%B0,%0,%0); 302 303 operands[1] = const0_rtx; 304 return AS2 (cmp%B0,%1,%0); 305}" 306 [(set_attr "type" "test")]) 307 308(define_expand "tstqi" 309 [(set (cc0) 310 (match_operand:QI 0 "nonimmediate_operand" ""))] 311 "" 312 " 313{ 314 i386_compare_gen = gen_tstqi_1; 315 i386_compare_op0 = operands[0]; 316 i386_compare_op1 = const0_rtx; 317 DONE; 318}") 319 320(define_insn "tstsf_cc" 321 [(set (cc0) 322 (match_operand:SF 0 "register_operand" "f")) 323 (clobber (match_scratch:HI 1 "=a"))] 324 "TARGET_80387 && ! TARGET_IEEE_FP" 325 "* 326{ 327 if (! STACK_TOP_P (operands[0])) 328 abort (); 329 330 output_asm_insn (\"ftst\", operands); 331 332 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) 333 output_asm_insn (AS1 (fstp,%y0), operands); 334 335 return output_fp_cc0_set (insn); 336}" 337 [(set_attr "type" "test")]) 338 339;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode 340;; isn't IEEE compliant. 341 342(define_expand "tstsf" 343 [(parallel [(set (cc0) 344 (match_operand:SF 0 "register_operand" "")) 345 (clobber (match_scratch:HI 1 ""))])] 346 "TARGET_80387 && ! TARGET_IEEE_FP" 347 " 348{ 349 i386_compare_gen = gen_tstsf_cc; 350 i386_compare_op0 = operands[0]; 351 i386_compare_op1 = const0_rtx; 352 DONE; 353}") 354 355(define_insn "tstdf_cc" 356 [(set (cc0) 357 (match_operand:DF 0 "register_operand" "f")) 358 (clobber (match_scratch:HI 1 "=a"))] 359 "TARGET_80387 && ! TARGET_IEEE_FP" 360 "* 361{ 362 if (! STACK_TOP_P (operands[0])) 363 abort (); 364 365 output_asm_insn (\"ftst\", operands); 366 367 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) 368 output_asm_insn (AS1 (fstp,%y0), operands); 369 370 return output_fp_cc0_set (insn); 371}" 372 [(set_attr "type" "test")]) 373 374;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode 375;; isn't IEEE compliant. 376 377(define_expand "tstdf" 378 [(parallel [(set (cc0) 379 (match_operand:DF 0 "register_operand" "")) 380 (clobber (match_scratch:HI 1 ""))])] 381 "TARGET_80387 && ! TARGET_IEEE_FP" 382 " 383{ 384 i386_compare_gen = gen_tstdf_cc; 385 i386_compare_op0 = operands[0]; 386 i386_compare_op1 = const0_rtx; 387 DONE; 388}") 389 390(define_insn "tstxf_cc" 391 [(set (cc0) 392 (match_operand:XF 0 "register_operand" "f")) 393 (clobber (match_scratch:HI 1 "=a"))] 394 "TARGET_80387 && ! TARGET_IEEE_FP" 395 "* 396{ 397 if (! STACK_TOP_P (operands[0])) 398 abort (); 399 400 output_asm_insn (\"ftst\", operands); 401 402 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) 403 output_asm_insn (AS1 (fstp,%y0), operands); 404 405 return output_fp_cc0_set (insn); 406}" 407 [(set_attr "type" "test")]) 408 409;; Don't generate tstxf if generating IEEE code, since the `ftst' opcode 410;; isn't IEEE compliant. 411 412(define_expand "tstxf" 413 [(parallel [(set (cc0) 414 (match_operand:XF 0 "register_operand" "")) 415 (clobber (match_scratch:HI 1 ""))])] 416 "TARGET_80387 && ! TARGET_IEEE_FP" 417 " 418{ 419 i386_compare_gen = gen_tstxf_cc; 420 i386_compare_op0 = operands[0]; 421 i386_compare_op1 = const0_rtx; 422 DONE; 423}") 424 425;;- compare instructions. See comments above tstM patterns about 426;; expansion of these insns. 427 428(define_insn "cmpsi_1" 429 [(set (cc0) 430 (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r") 431 (match_operand:SI 1 "general_operand" "ri,mr")))] 432 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 433 "* return AS2 (cmp%L0,%1,%0);" 434 [(set_attr "type" "compare")]) 435 436(define_expand "cmpsi" 437 [(set (cc0) 438 (compare (match_operand:SI 0 "nonimmediate_operand" "") 439 (match_operand:SI 1 "general_operand" "")))] 440 "" 441 " 442{ 443 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 444 operands[0] = force_reg (SImode, operands[0]); 445 446 i386_compare_gen = gen_cmpsi_1; 447 i386_compare_op0 = operands[0]; 448 i386_compare_op1 = operands[1]; 449 DONE; 450}") 451 452(define_insn "cmphi_1" 453 [(set (cc0) 454 (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r") 455 (match_operand:HI 1 "general_operand" "ri,mr")))] 456 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 457 "* return AS2 (cmp%W0,%1,%0);" 458 [(set_attr "type" "compare")]) 459 460(define_expand "cmphi" 461 [(set (cc0) 462 (compare (match_operand:HI 0 "nonimmediate_operand" "") 463 (match_operand:HI 1 "general_operand" "")))] 464 "" 465 " 466{ 467 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 468 operands[0] = force_reg (HImode, operands[0]); 469 470 i386_compare_gen = gen_cmphi_1; 471 i386_compare_op0 = operands[0]; 472 i386_compare_op1 = operands[1]; 473 DONE; 474}") 475 476(define_insn "cmpqi_1" 477 [(set (cc0) 478 (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq") 479 (match_operand:QI 1 "general_operand" "qm,nq")))] 480 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" 481 "* return AS2 (cmp%B0,%1,%0);" 482 [(set_attr "type" "compare")]) 483 484(define_expand "cmpqi" 485 [(set (cc0) 486 (compare (match_operand:QI 0 "nonimmediate_operand" "") 487 (match_operand:QI 1 "general_operand" "")))] 488 "" 489 " 490{ 491 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 492 operands[0] = force_reg (QImode, operands[0]); 493 494 i386_compare_gen = gen_cmpqi_1; 495 i386_compare_op0 = operands[0]; 496 i386_compare_op1 = operands[1]; 497 DONE; 498}") 499 500;; These implement float point compares. For each of DFmode and 501;; SFmode, there is the normal insn, and an insn where the second operand 502;; is converted to the desired mode. 503 504(define_insn "" 505 [(set (cc0) 506 (match_operator 2 "VOIDmode_compare_op" 507 [(match_operand:XF 0 "register_operand" "f") 508 (match_operand:XF 1 "register_operand" "f")])) 509 (clobber (match_scratch:HI 3 "=a"))] 510 "TARGET_80387" 511 "* return output_float_compare (insn, operands);" 512 [(set_attr "type" "fcompare")]) 513 514(define_insn "" 515 [(set (cc0) 516 (match_operator 2 "VOIDmode_compare_op" 517 [(match_operand:XF 0 "register_operand" "f") 518 (float_extend:XF 519 (match_operand:DF 1 "nonimmediate_operand" "fm"))])) 520 (clobber (match_scratch:HI 3 "=a"))] 521 "TARGET_80387" 522 "* return output_float_compare (insn, operands);" 523 [(set_attr "type" "fcompare")]) 524 525(define_insn "" 526 [(set (cc0) 527 (match_operator 2 "VOIDmode_compare_op" 528 [(float_extend:XF 529 (match_operand:DF 0 "nonimmediate_operand" "fm")) 530 (match_operand:XF 1 "register_operand" "f")])) 531 (clobber (match_scratch:HI 3 "=a"))] 532 "TARGET_80387" 533 "* return output_float_compare (insn, operands);" 534 [(set_attr "type" "fcompare")]) 535 536(define_insn "" 537 [(set (cc0) 538 (match_operator 2 "VOIDmode_compare_op" 539 [(match_operand:XF 0 "register_operand" "f") 540 (float_extend:XF 541 (match_operand:SF 1 "nonimmediate_operand" "fm"))])) 542 (clobber (match_scratch:HI 3 "=a"))] 543 "TARGET_80387" 544 "* return output_float_compare (insn, operands);" 545 [(set_attr "type" "fcompare")]) 546 547(define_insn "" 548 [(set (cc0) 549 (match_operator 2 "VOIDmode_compare_op" 550 [(float_extend:XF 551 (match_operand:SF 0 "nonimmediate_operand" "fm")) 552 (match_operand:XF 1 "register_operand" "f")])) 553 (clobber (match_scratch:HI 3 "=a"))] 554 "TARGET_80387" 555 "* return output_float_compare (insn, operands);" 556 [(set_attr "type" "fcompare")]) 557 558(define_insn "" 559 [(set (cc0) 560 (compare:CCFPEQ (match_operand:XF 0 "register_operand" "f") 561 (match_operand:XF 1 "register_operand" "f"))) 562 (clobber (match_scratch:HI 2 "=a"))] 563 "TARGET_80387" 564 "* return output_float_compare (insn, operands);" 565 [(set_attr "type" "fcompare")]) 566 567(define_insn "" 568 [(set (cc0) 569 (match_operator 2 "VOIDmode_compare_op" 570 [(match_operand:DF 0 "nonimmediate_operand" "f,fm") 571 (match_operand:DF 1 "nonimmediate_operand" "fm,f")])) 572 (clobber (match_scratch:HI 3 "=a,a"))] 573 "TARGET_80387 574 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 575 "* return output_float_compare (insn, operands);" 576 [(set_attr "type" "fcompare")]) 577 578(define_insn "" 579 [(set (cc0) 580 (match_operator 2 "VOIDmode_compare_op" 581 [(match_operand:DF 0 "register_operand" "f") 582 (float_extend:DF 583 (match_operand:SF 1 "nonimmediate_operand" "fm"))])) 584 (clobber (match_scratch:HI 3 "=a"))] 585 "TARGET_80387" 586 "* return output_float_compare (insn, operands);" 587 [(set_attr "type" "fcompare")]) 588 589(define_insn "" 590 [(set (cc0) 591 (match_operator 2 "VOIDmode_compare_op" 592 [(float_extend:DF 593 (match_operand:SF 0 "nonimmediate_operand" "fm")) 594 (match_operand:DF 1 "register_operand" "f")])) 595 (clobber (match_scratch:HI 3 "=a"))] 596 "TARGET_80387" 597 "* return output_float_compare (insn, operands);" 598 [(set_attr "type" "fcompare")]) 599 600(define_insn "" 601 [(set (cc0) 602 (match_operator 2 "VOIDmode_compare_op" 603 [(float_extend:DF 604 (match_operand:SF 0 "register_operand" "f")) 605 (match_operand:DF 1 "nonimmediate_operand" "fm")])) 606 (clobber (match_scratch:HI 3 "=a"))] 607 "TARGET_80387" 608 "* return output_float_compare (insn, operands);" 609 [(set_attr "type" "fcompare")]) 610 611(define_insn "" 612 [(set (cc0) 613 (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f") 614 (match_operand:DF 1 "register_operand" "f"))) 615 (clobber (match_scratch:HI 2 "=a"))] 616 "TARGET_80387" 617 "* return output_float_compare (insn, operands);" 618 [(set_attr "type" "fcompare")]) 619 620;; These two insns will never be generated by combine due to the mode of 621;; the COMPARE. 622;(define_insn "" 623; [(set (cc0) 624; (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f") 625; (float_extend:DF 626; (match_operand:SF 1 "register_operand" "f")))) 627; (clobber (match_scratch:HI 2 "=a"))] 628; "TARGET_80387" 629; "* return output_float_compare (insn, operands);") 630; 631;(define_insn "" 632; [(set (cc0) 633; (compare:CCFPEQ (float_extend:DF 634; (match_operand:SF 0 "register_operand" "f")) 635; (match_operand:DF 1 "register_operand" "f"))) 636; (clobber (match_scratch:HI 2 "=a"))] 637; "TARGET_80387" 638; "* return output_float_compare (insn, operands);") 639 640(define_insn "*cmpsf_cc_1" 641 [(set (cc0) 642 (match_operator 2 "VOIDmode_compare_op" 643 [(match_operand:SF 0 "nonimmediate_operand" "f,fm") 644 (match_operand:SF 1 "nonimmediate_operand" "fm,f")])) 645 (clobber (match_scratch:HI 3 "=a,a"))] 646 "TARGET_80387 647 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 648 "* return output_float_compare (insn, operands);" 649 [(set_attr "type" "fcompare")]) 650 651(define_insn "" 652 [(set (cc0) 653 (compare:CCFPEQ (match_operand:SF 0 "register_operand" "f") 654 (match_operand:SF 1 "register_operand" "f"))) 655 (clobber (match_scratch:HI 2 "=a"))] 656 "TARGET_80387" 657 "* return output_float_compare (insn, operands);" 658 [(set_attr "type" "fcompare")]) 659 660(define_expand "cmpxf" 661 [(set (cc0) 662 (compare (match_operand:XF 0 "register_operand" "") 663 (match_operand:XF 1 "register_operand" "")))] 664 "TARGET_80387" 665 " 666{ 667 i386_compare_gen = gen_cmpxf_cc; 668 i386_compare_gen_eq = gen_cmpxf_ccfpeq; 669 i386_compare_op0 = operands[0]; 670 i386_compare_op1 = operands[1]; 671 DONE; 672}") 673 674(define_expand "cmpdf" 675 [(set (cc0) 676 (compare (match_operand:DF 0 "register_operand" "") 677 (match_operand:DF 1 "general_operand" "")))] 678 "TARGET_80387" 679 " 680{ 681 i386_compare_gen = gen_cmpdf_cc; 682 i386_compare_gen_eq = gen_cmpdf_ccfpeq; 683 i386_compare_op0 = operands[0]; 684 i386_compare_op1 = (immediate_operand (operands[1], DFmode)) 685 ? copy_to_mode_reg (DFmode, operands[1]) : operands[1]; 686 DONE; 687}") 688 689(define_expand "cmpsf" 690 [(set (cc0) 691 (compare (match_operand:SF 0 "register_operand" "") 692 (match_operand:SF 1 "general_operand" "")))] 693 "TARGET_80387" 694 " 695{ 696 i386_compare_gen = gen_cmpsf_cc; 697 i386_compare_gen_eq = gen_cmpsf_ccfpeq; 698 i386_compare_op0 = operands[0]; 699 i386_compare_op1 = (immediate_operand (operands[1], SFmode)) 700 ? copy_to_mode_reg (SFmode, operands[1]) : operands[1]; 701 DONE; 702}") 703 704(define_expand "cmpxf_cc" 705 [(parallel [(set (cc0) 706 (compare (match_operand:XF 0 "register_operand" "") 707 (match_operand:XF 1 "register_operand" ""))) 708 (clobber (match_scratch:HI 2 ""))])] 709 "TARGET_80387" 710 "") 711 712(define_expand "cmpxf_ccfpeq" 713 [(parallel [(set (cc0) 714 (compare:CCFPEQ (match_operand:XF 0 "register_operand" "") 715 (match_operand:XF 1 "register_operand" ""))) 716 (clobber (match_scratch:HI 2 ""))])] 717 "TARGET_80387" 718 "") 719 720(define_expand "cmpdf_cc" 721 [(parallel [(set (cc0) 722 (compare (match_operand:DF 0 "register_operand" "") 723 (match_operand:DF 1 "register_operand" ""))) 724 (clobber (match_scratch:HI 2 ""))])] 725 "TARGET_80387" 726 "") 727 728(define_expand "cmpdf_ccfpeq" 729 [(parallel [(set (cc0) 730 (compare:CCFPEQ (match_operand:DF 0 "register_operand" "") 731 (match_operand:DF 1 "register_operand" ""))) 732 (clobber (match_scratch:HI 2 ""))])] 733 "TARGET_80387" 734 " 735{ 736 if (! register_operand (operands[1], DFmode)) 737 operands[1] = copy_to_mode_reg (DFmode, operands[1]); 738}") 739 740(define_expand "cmpsf_cc" 741 [(parallel [(set (cc0) 742 (compare (match_operand:SF 0 "register_operand" "") 743 (match_operand:SF 1 "register_operand" ""))) 744 (clobber (match_scratch:HI 2 ""))])] 745 "TARGET_80387" 746 "") 747 748(define_expand "cmpsf_ccfpeq" 749 [(parallel [(set (cc0) 750 (compare:CCFPEQ (match_operand:SF 0 "register_operand" "") 751 (match_operand:SF 1 "register_operand" ""))) 752 (clobber (match_scratch:HI 2 ""))])] 753 "TARGET_80387" 754 " 755{ 756 if (! register_operand (operands[1], SFmode)) 757 operands[1] = copy_to_mode_reg (SFmode, operands[1]); 758}") 759 760;; logical compare 761 762(define_insn "" 763 [(set (cc0) 764 (and:SI (match_operand:SI 0 "general_operand" "%ro") 765 (match_operand:SI 1 "nonmemory_operand" "ri")))] 766 "" 767 "* 768{ 769 /* For small integers, we may actually use testb. */ 770 if (GET_CODE (operands[1]) == CONST_INT 771 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) 772 && (! REG_P (operands[0]) || QI_REG_P (operands[0])) 773 /* A Pentium test is pairable only with eax. Not with ah or al. */ 774 && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM 775 || optimize_size)) 776 { 777 /* We may set the sign bit spuriously. */ 778 779 if ((INTVAL (operands[1]) & ~0xff) == 0) 780 { 781 cc_status.flags |= CC_NOT_NEGATIVE; 782 return AS2 (test%B0,%1,%b0); 783 } 784 785 if ((INTVAL (operands[1]) & ~0xff00) == 0) 786 { 787 cc_status.flags |= CC_NOT_NEGATIVE; 788 operands[1] = GEN_INT (INTVAL (operands[1]) >> 8); 789 790 if (QI_REG_P (operands[0])) 791 return AS2 (test%B0,%1,%h0); 792 else 793 { 794 operands[0] = adj_offsettable_operand (operands[0], 1); 795 return AS2 (test%B0,%1,%b0); 796 } 797 } 798 799 if (GET_CODE (operands[0]) == MEM 800 && (INTVAL (operands[1]) & ~0xff0000) == 0) 801 { 802 cc_status.flags |= CC_NOT_NEGATIVE; 803 operands[1] = GEN_INT (INTVAL (operands[1]) >> 16); 804 operands[0] = adj_offsettable_operand (operands[0], 2); 805 return AS2 (test%B0,%1,%b0); 806 } 807 808 if (GET_CODE (operands[0]) == MEM 809 && (INTVAL (operands[1]) & ~0xff000000) == 0) 810 { 811 operands[1] = GEN_INT ((INTVAL (operands[1]) >> 24) & 0xff); 812 operands[0] = adj_offsettable_operand (operands[0], 3); 813 return AS2 (test%B0,%1,%b0); 814 } 815 } 816 817 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM) 818 return AS2 (test%L0,%1,%0); 819 820 return AS2 (test%L1,%0,%1); 821}" 822 [(set_attr "type" "compare")]) 823 824(define_insn "" 825 [(set (cc0) 826 (and:HI (match_operand:HI 0 "general_operand" "%ro") 827 (match_operand:HI 1 "nonmemory_operand" "ri")))] 828 "" 829 "* 830{ 831 if (GET_CODE (operands[1]) == CONST_INT 832 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) 833 && (! REG_P (operands[0]) || QI_REG_P (operands[0]))) 834 { 835 if ((INTVAL (operands[1]) & 0xff00) == 0) 836 { 837 /* ??? This might not be necessary. */ 838 if (INTVAL (operands[1]) & 0xffff0000) 839 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); 840 841 /* We may set the sign bit spuriously. */ 842 cc_status.flags |= CC_NOT_NEGATIVE; 843 return AS2 (test%B0,%1,%b0); 844 } 845 846 if ((INTVAL (operands[1]) & 0xff) == 0) 847 { 848 operands[1] = GEN_INT ((INTVAL (operands[1]) >> 8) & 0xff); 849 850 if (QI_REG_P (operands[0])) 851 return AS2 (test%B0,%1,%h0); 852 else 853 { 854 operands[0] = adj_offsettable_operand (operands[0], 1); 855 return AS2 (test%B0,%1,%b0); 856 } 857 } 858 } 859 860 /* use 32-bit test instruction if there are no sign issues */ 861 if (GET_CODE (operands[1]) == CONST_INT 862 && !(INTVAL (operands[1]) & ~0x7fff) 863 && i386_aligned_p (operands[0])) 864 return AS2 (test%L0,%1,%k0); 865 866 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM) 867 return AS2 (test%W0,%1,%0); 868 869 return AS2 (test%W1,%0,%1); 870}" 871 [(set_attr "type" "compare")]) 872 873(define_insn "" 874 [(set (cc0) 875 (and:QI (match_operand:QI 0 "nonimmediate_operand" "%qm") 876 (match_operand:QI 1 "nonmemory_operand" "qi")))] 877 "" 878 "* 879{ 880 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM) 881 return AS2 (test%B0,%1,%0); 882 883 return AS2 (test%B1,%0,%1); 884}" 885 [(set_attr "type" "compare")]) 886 887;; move instructions. 888;; There is one for each machine mode, 889;; and each is preceded by a corresponding push-insn pattern 890;; (since pushes are not general_operands on the 386). 891 892(define_insn "" 893 [(set (match_operand:SI 0 "push_operand" "=<") 894 (match_operand:SI 1 "nonmemory_operand" "rn"))] 895 "flag_pic" 896 "* return AS1 (push%L0,%1);" 897 [(set_attr "memory" "store")]) 898 899(define_insn "" 900 [(set (match_operand:SI 0 "push_operand" "=<") 901 (match_operand:SI 1 "nonmemory_operand" "ri"))] 902 "!flag_pic" 903 "* return AS1 (push%L0,%1);" 904 [(set_attr "memory" "store")]) 905 906;; On a 386, it is faster to push MEM directly. 907 908(define_insn "" 909 [(set (match_operand:SI 0 "push_operand" "=<") 910 (match_operand:SI 1 "memory_operand" "m"))] 911 "TARGET_PUSH_MEMORY" 912 "* return AS1 (push%L0,%1);" 913 [(set_attr "type" "memory") 914 (set_attr "memory" "load")]) 915 916;; General case of fullword move. 917 918;; If generating PIC code and operands[1] is a symbolic CONST, emit a 919;; move to get the address of the symbolic object from the GOT. 920 921(define_expand "movsi" 922 [(set (match_operand:SI 0 "general_operand" "") 923 (match_operand:SI 1 "general_operand" ""))] 924 "" 925 " 926{ 927 extern int flag_pic; 928 929 if (flag_pic && SYMBOLIC_CONST (operands[1])) 930 emit_pic_move (operands, SImode); 931 932 /* Don't generate memory->memory moves, go through a register */ 933 else if (TARGET_MOVE 934 && no_new_pseudos == 0 935 && GET_CODE (operands[0]) == MEM 936 && GET_CODE (operands[1]) == MEM) 937 { 938 operands[1] = force_reg (SImode, operands[1]); 939 } 940}") 941 942;; On i486, incl reg is faster than movl $1,reg. 943 944(define_insn "" 945 [(set (match_operand:SI 0 "general_operand" "=g,r,r") 946 (match_operand:SI 1 "general_operand" "rn,i,m"))] 947 "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM) 948 || (GET_CODE (operands[1]) != MEM)) 949 && flag_pic" 950 "* 951{ 952 rtx link; 953 954 /* K6: mov reg,0 is slightly faster than xor reg,reg but is 3 bytes 955 longer. */ 956 if ((ix86_cpu != PROCESSOR_K6 || optimize_size) 957 && operands[1] == const0_rtx && REG_P (operands[0])) 958 return AS2 (xor%L0,%0,%0); 959 960 if (operands[1] == const1_rtx 961 /* PPRO and K6 prefer mov to inc to reduce dependencies. */ 962 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO) 963 && (link = find_reg_note (insn, REG_WAS_0, 0)) 964 /* Make sure the insn that stored the 0 is still present. */ 965 && ! INSN_DELETED_P (XEXP (link, 0)) 966 && GET_CODE (XEXP (link, 0)) != NOTE 967 /* Make sure cross jumping didn't happen here. */ 968 && no_labels_between_p (XEXP (link, 0), insn) 969 /* Make sure the reg hasn't been clobbered. */ 970 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) 971 /* Fastest way to change a 0 to a 1. */ 972 return AS1 (inc%L0,%0); 973 974 if (SYMBOLIC_CONST (operands[1])) 975 return AS2 (lea%L0,%a1,%0); 976 977 return AS2 (mov%L0,%1,%0); 978}" 979 [(set_attr "type" "integer,integer,memory") 980 (set_attr "memory" "*,*,load")]) 981 982(define_insn "" 983 [(set (match_operand:SI 0 "general_operand" "=g,r") 984 (match_operand:SI 1 "general_operand" "ri,m"))] 985 "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM) 986 || (GET_CODE (operands[1]) != MEM)) 987 && !flag_pic" 988 "* 989{ 990 rtx link; 991 992 /* Use of xor was disabled for AMD K6 as recommended by the Optimization 993 Manual. My test shows, that this generally hurts the performance, because 994 mov is longer and takes longer to decode and decoding is the main 995 bottleneck of K6 when executing GCC code. */ 996 997 if (operands[1] == const0_rtx && REG_P (operands[0])) 998 return AS2 (xor%L0,%0,%0); 999 1000 if (operands[1] == const1_rtx 1001 /* PPRO and K6 prefer mov to inc to reduce dependencies. */ 1002 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO) 1003 && (link = find_reg_note (insn, REG_WAS_0, 0)) 1004 /* Make sure the insn that stored the 0 is still present. */ 1005 && ! INSN_DELETED_P (XEXP (link, 0)) 1006 && GET_CODE (XEXP (link, 0)) != NOTE 1007 /* Make sure cross jumping didn't happen here. */ 1008 && no_labels_between_p (XEXP (link, 0), insn) 1009 /* Make sure the reg hasn't been clobbered. */ 1010 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) 1011 /* Fastest way to change a 0 to a 1. */ 1012 return AS1 (inc%L0,%0); 1013 1014 return AS2 (mov%L0,%1,%0); 1015}" 1016 [(set_attr "type" "integer,memory") 1017 (set_attr "memory" "*,load")]) 1018 1019(define_insn "" 1020 [(set (match_operand:HI 0 "push_operand" "=<") 1021 (match_operand:HI 1 "nonmemory_operand" "ri"))] 1022 "" 1023 "* return AS1 (push%W0,%1);" 1024 [(set_attr "type" "memory") 1025 (set_attr "memory" "store")]) 1026 1027(define_insn "" 1028 [(set (match_operand:HI 0 "push_operand" "=<") 1029 (match_operand:HI 1 "memory_operand" "m"))] 1030 "TARGET_PUSH_MEMORY" 1031 "* return AS1 (push%W0,%1);" 1032 [(set_attr "type" "memory") 1033 (set_attr "memory" "load")]) 1034 1035;; On i486, an incl and movl are both faster than incw and movw. 1036 1037(define_expand "movhi" 1038 [(set (match_operand:HI 0 "general_operand" "") 1039 (match_operand:HI 1 "general_operand" ""))] 1040 "" 1041 " 1042{ 1043 /* Don't generate memory->memory moves, go through a register */ 1044 if (TARGET_MOVE 1045 && no_new_pseudos == 0 1046 && GET_CODE (operands[0]) == MEM 1047 && GET_CODE (operands[1]) == MEM) 1048 { 1049 operands[1] = force_reg (HImode, operands[1]); 1050 } 1051}") 1052 1053(define_insn "" 1054 [(set (match_operand:HI 0 "general_operand" "=g,r") 1055 (match_operand:HI 1 "general_operand" "ri,m"))] 1056 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" 1057 "* 1058{ 1059 rtx link; 1060 if (REG_P (operands[0]) && operands[1] == const0_rtx) 1061 return AS2 (xor%L0,%k0,%k0); 1062 1063 if (REG_P (operands[0]) && operands[1] == const1_rtx 1064 /* PPRO and K6 prefer mov to inc to reduce dependencies. */ 1065 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO) 1066 && (link = find_reg_note (insn, REG_WAS_0, 0)) 1067 /* Make sure the insn that stored the 0 is still present. */ 1068 && ! INSN_DELETED_P (XEXP (link, 0)) 1069 && GET_CODE (XEXP (link, 0)) != NOTE 1070 /* Make sure cross jumping didn't happen here. */ 1071 && no_labels_between_p (XEXP (link, 0), insn) 1072 /* Make sure the reg hasn't been clobbered. */ 1073 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) 1074 /* Fastest way to change a 0 to a 1. */ 1075 return AS1 (inc%L0,%k0); 1076 1077 if (REG_P (operands[0])) 1078 { 1079 if (i386_aligned_p (operands[1])) 1080 { 1081 operands[1] = i386_sext16_if_const (operands[1]); 1082 return AS2 (mov%L0,%k1,%k0); 1083 } 1084 if (! TARGET_ZERO_EXTEND_WITH_AND) 1085 { 1086 /* movzwl is faster than movw on the Pentium Pro, 1087 * although not as fast as an aligned movl. */ 1088#ifdef INTEL_SYNTAX 1089 return AS2 (movzx,%1,%k0); 1090#else 1091 return AS2 (movz%W0%L0,%1,%k0); 1092#endif 1093 } 1094 } 1095 1096 return AS2 (mov%W0,%1,%0); 1097}" 1098 [(set_attr "type" "integer,memory") 1099 (set_attr "memory" "*,load")]) 1100 1101(define_expand "movstricthi" 1102 [(set (strict_low_part (match_operand:HI 0 "general_operand" "")) 1103 (match_operand:HI 1 "general_operand" ""))] 1104 "" 1105 " 1106{ 1107 /* Don't generate memory->memory moves, go through a register */ 1108 if (TARGET_MOVE 1109 && no_new_pseudos == 0 1110 && GET_CODE (operands[0]) == MEM 1111 && GET_CODE (operands[1]) == MEM) 1112 { 1113 operands[1] = force_reg (HImode, operands[1]); 1114 } 1115}") 1116 1117(define_insn "" 1118 [(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r")) 1119 (match_operand:HI 1 "general_operand" "ri,m"))] 1120 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" 1121 "* 1122{ 1123 rtx link; 1124 1125 /* Use of xor was disabled for AMD K6 as recommended by the Optimization 1126 Manual. My test shows, that this generally hurts the performance, because 1127 mov is longer and takes longer to decode and decoding is the main 1128 bottleneck of K6 when executing GCC code. */ 1129 1130 if (operands[1] == const0_rtx && REG_P (operands[0])) 1131 return AS2 (xor%W0,%0,%0); 1132 1133 if (operands[1] == const1_rtx 1134 /* PPRO and K6 prefer mov to inc to reduce dependencies. */ 1135 && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO) 1136 && (link = find_reg_note (insn, REG_WAS_0, 0)) 1137 /* Make sure the insn that stored the 0 is still present. */ 1138 && ! INSN_DELETED_P (XEXP (link, 0)) 1139 && GET_CODE (XEXP (link, 0)) != NOTE 1140 /* Make sure cross jumping didn't happen here. */ 1141 && no_labels_between_p (XEXP (link, 0), insn) 1142 /* Make sure the reg hasn't been clobbered. */ 1143 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) 1144 /* Fastest way to change a 0 to a 1. */ 1145 return AS1 (inc%W0,%0); 1146 1147 return AS2 (mov%W0,%1,%0); 1148}" 1149 [(set_attr "type" "integer,memory")]) 1150 1151;; emit_push_insn when it calls move_by_pieces 1152;; requires an insn to "push a byte". 1153;; But actually we use pushw, which has the effect of rounding 1154;; the amount pushed up to a halfword. 1155(define_insn "" 1156 [(set (match_operand:QI 0 "push_operand" "=<") 1157 (match_operand:QI 1 "const_int_operand" "n"))] 1158 "" 1159 "* return AS1(push%W0,%1);") 1160 1161(define_insn "" 1162 [(set (match_operand:QI 0 "push_operand" "=<") 1163 (match_operand:QI 1 "register_operand" "q"))] 1164 "" 1165 "* 1166{ 1167 operands[1] = gen_rtx_REG (HImode, REGNO (operands[1])); 1168 return AS1 (push%W0,%1); 1169}") 1170 1171;; On i486, incb reg is faster than movb $1,reg. 1172 1173;; ??? Do a recognizer for zero_extract that looks just like this, but reads 1174;; or writes %ah, %bh, %ch, %dh. 1175 1176(define_expand "movqi" 1177 [(set (match_operand:QI 0 "general_operand" "") 1178 (match_operand:QI 1 "general_operand" ""))] 1179 "" 1180 " 1181{ 1182 /* Don't generate memory->memory moves, go through a register */ 1183 if (TARGET_MOVE 1184 && no_new_pseudos == 0 1185 && GET_CODE (operands[0]) == MEM 1186 && GET_CODE (operands[1]) == MEM) 1187 { 1188 operands[1] = force_reg (QImode, operands[1]); 1189 } 1190}") 1191 1192(define_insn "" 1193 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,*r,qm") 1194 (match_operand:QI 1 "general_operand" "*g,*rn,qn"))] 1195 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" 1196 "* 1197{ 1198 rtx link; 1199 1200 /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8. 1201 It is at least as fast as xor on any processor except a Pentium. */ 1202 1203 if (operands[1] == const1_rtx 1204 && TARGET_PENTIUM 1205 && (link = find_reg_note (insn, REG_WAS_0, 0)) 1206 /* Make sure the insn that stored the 0 is still present. */ 1207 && ! INSN_DELETED_P (XEXP (link, 0)) 1208 && GET_CODE (XEXP (link, 0)) != NOTE 1209 /* Make sure cross jumping didn't happen here. */ 1210 && no_labels_between_p (XEXP (link, 0), insn) 1211 /* Make sure the reg hasn't been clobbered. */ 1212 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) 1213 { 1214 /* Fastest way to change a 0 to a 1. 1215 If inc%B0 isn't allowed, use inc%L0. */ 1216 if (NON_QI_REG_P (operands[0])) 1217 return AS1 (inc%L0,%k0); 1218 else 1219 return AS1 (inc%B0,%0); 1220 } 1221 1222 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */ 1223 if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1])) 1224 return (AS2 (mov%L0,%k1,%k0)); 1225 1226 return (AS2 (mov%B0,%1,%0)); 1227}") 1228 1229;; If it becomes necessary to support movstrictqi into %esi or %edi, 1230;; use the insn sequence: 1231;; 1232;; shrdl $8,srcreg,dstreg 1233;; rorl $24,dstreg 1234;; 1235;; If operands[1] is a constant, then an andl/orl sequence would be 1236;; faster. 1237 1238(define_expand "movstrictqi" 1239 [(set (strict_low_part (match_operand:QI 0 "general_operand" "")) 1240 (match_operand:QI 1 "general_operand" ""))] 1241 "" 1242 " 1243{ 1244 /* Don't generate memory->memory moves, go through a register */ 1245 if (TARGET_MOVE 1246 && no_new_pseudos == 0 1247 && GET_CODE (operands[0]) == MEM 1248 && GET_CODE (operands[1]) == MEM) 1249 { 1250 operands[1] = force_reg (QImode, operands[1]); 1251 } 1252}") 1253 1254(define_insn "" 1255 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 1256 (match_operand:QI 1 "general_operand" "*qn,m"))] 1257 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" 1258 "* 1259{ 1260 rtx link; 1261 1262 /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8. */ 1263 1264 if (operands[1] == const1_rtx 1265 && TARGET_PENTIUM 1266 && ! NON_QI_REG_P (operands[0]) 1267 && (link = find_reg_note (insn, REG_WAS_0, 0)) 1268 /* Make sure the insn that stored the 0 is still present. */ 1269 && ! INSN_DELETED_P (XEXP (link, 0)) 1270 && GET_CODE (XEXP (link, 0)) != NOTE 1271 /* Make sure cross jumping didn't happen here. */ 1272 && no_labels_between_p (XEXP (link, 0), insn) 1273 /* Make sure the reg hasn't been clobbered. */ 1274 && ! reg_set_between_p (operands[0], XEXP (link, 0), insn)) 1275 /* Fastest way to change a 0 to a 1. */ 1276 return AS1 (inc%B0,%0); 1277 1278 /* If mov%B0 isn't allowed for one of these regs, use mov%L0. */ 1279 if (NON_QI_REG_P (operands[0]) || NON_QI_REG_P (operands[1])) 1280 { 1281 abort (); 1282 return (AS2 (mov%L0,%k1,%k0)); 1283 } 1284 1285 return AS2 (mov%B0,%1,%0); 1286}") 1287 1288(define_insn "movsf_push" 1289 [(set (match_operand:SF 0 "push_operand" "=<,<") 1290 (match_operand:SF 1 "general_operand" "*rfF,m"))] 1291 "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM 1292 || reload_in_progress || reload_completed" 1293 "* 1294{ 1295 if (STACK_REG_P (operands[1])) 1296 { 1297 rtx xops[3]; 1298 1299 if (! STACK_TOP_P (operands[1])) 1300 abort (); 1301 1302 xops[0] = AT_SP (SFmode); 1303 xops[1] = GEN_INT (4); 1304 xops[2] = stack_pointer_rtx; 1305 1306 output_asm_insn (AS2 (sub%L2,%1,%2), xops); 1307 1308 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) 1309 output_asm_insn (AS1 (fstp%S0,%0), xops); 1310 else 1311 output_asm_insn (AS1 (fst%S0,%0), xops); 1312 1313 RET; 1314 } 1315 1316 return AS1 (push%L0,%1); 1317}") 1318 1319(define_split 1320 [(set (match_operand:SF 0 "push_operand" "") 1321 (match_operand:SF 1 "general_operand" ""))] 1322 "reload_completed && STACK_REG_P (operands[1])" 1323 [(set (reg:SI 7) 1324 (minus:SI (reg:SI 7) (const_int 4))) 1325 (set (mem:SF (reg:SI 7)) 1326 (match_dup 1))] 1327 "") 1328 1329(define_expand "movsf" 1330 [(set (match_operand:SF 0 "general_operand" "") 1331 (match_operand:SF 1 "general_operand" ""))] 1332 "" 1333 " 1334{ 1335 /* Don't generate memory->memory moves, go through a register */ 1336 if (TARGET_MOVE 1337 && no_new_pseudos == 0 1338 && GET_CODE (operands[0]) == MEM 1339 && GET_CODE (operands[1]) == MEM) 1340 { 1341 operands[1] = force_reg (SFmode, operands[1]); 1342 } 1343 1344 /* If we are loading a floating point constant that isn't 0 or 1 1345 into a register, force the value to memory now, since we'll 1346 get better code out the back end. */ 1347 else if ((reload_in_progress | reload_completed) == 0 1348 && GET_CODE (operands[0]) != MEM 1349 && GET_CODE (operands[1]) == CONST_DOUBLE 1350 && !standard_80387_constant_p (operands[1])) 1351 { 1352 operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 1353 } 1354}") 1355 1356;; For the purposes of regclass, prefer FLOAT_REGS. 1357(define_insn "" 1358 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r,!m") 1359 (match_operand:SF 1 "general_operand" "fmG,f,*rmF,*rF"))] 1360 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" 1361 "* 1362{ 1363 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 1364 1365 /* First handle a `pop' insn or a `fld %st(0)' */ 1366 1367 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1])) 1368 { 1369 if (stack_top_dies) 1370 return AS1 (fstp,%y0); 1371 else 1372 return AS1 (fld,%y0); 1373 } 1374 1375 /* Handle other kinds of writes from the 387 */ 1376 1377 if (STACK_TOP_P (operands[1])) 1378 { 1379 if (stack_top_dies) 1380 return AS1 (fstp%z0,%y0); 1381 else 1382 return AS1 (fst%z0,%y0); 1383 } 1384 1385 /* Handle other kinds of reads to the 387 */ 1386 1387 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE) 1388 return output_move_const_single (operands); 1389 1390 if (STACK_TOP_P (operands[0])) 1391 return AS1 (fld%z1,%y1); 1392 1393 /* Handle all SFmode moves not involving the 387 */ 1394 1395 return singlemove_string (operands); 1396}" 1397 [(set_attr "type" "fld")]) 1398 1399 1400(define_insn "swapsf" 1401 [(set (match_operand:SF 0 "register_operand" "f") 1402 (match_operand:SF 1 "register_operand" "f")) 1403 (set (match_dup 1) 1404 (match_dup 0))] 1405 "" 1406 "* 1407{ 1408 if (STACK_TOP_P (operands[0])) 1409 return AS1 (fxch,%1); 1410 else 1411 return AS1 (fxch,%0); 1412}") 1413 1414 1415(define_insn "movdf_push" 1416 [(set (match_operand:DF 0 "push_operand" "=<,<") 1417 (match_operand:DF 1 "general_operand" "*rfF,o"))] 1418 "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM 1419 || reload_in_progress || reload_completed" 1420 "* 1421{ 1422 if (STACK_REG_P (operands[1])) 1423 { 1424 rtx xops[3]; 1425 1426 xops[0] = AT_SP (DFmode); 1427 xops[1] = GEN_INT (8); 1428 xops[2] = stack_pointer_rtx; 1429 1430 output_asm_insn (AS2 (sub%L2,%1,%2), xops); 1431 1432 if (find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) 1433 output_asm_insn (AS1 (fstp%Q0,%0), xops); 1434 else 1435 output_asm_insn (AS1 (fst%Q0,%0), xops); 1436 1437 RET; 1438 } 1439 1440 if (which_alternative == 1) 1441 return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode), 0, 0); 1442 1443 return output_move_double (operands); 1444}") 1445 1446(define_split 1447 [(set (match_operand:DF 0 "push_operand" "") 1448 (match_operand:DF 1 "register_operand" ""))] 1449 "reload_completed && STACK_REG_P (operands[1])" 1450 [(set (reg:SI 7) 1451 (minus:SI (reg:SI 7) (const_int 8))) 1452 (set (mem:DF (reg:SI 7)) 1453 (match_dup 1))] 1454 "") 1455 1456(define_expand "movdf" 1457 [(set (match_operand:DF 0 "general_operand" "") 1458 (match_operand:DF 1 "general_operand" ""))] 1459 "" 1460 " 1461{ 1462 /* Don't generate memory->memory moves, go through a register */ 1463 if (TARGET_MOVE 1464 && no_new_pseudos == 0 1465 && GET_CODE (operands[0]) == MEM 1466 && GET_CODE (operands[1]) == MEM) 1467 { 1468 operands[1] = force_reg (DFmode, operands[1]); 1469 } 1470 1471 /* If we are loading a floating point constant that isn't 0 or 1 into a 1472 register, indicate we need the pic register loaded. This could be 1473 optimized into stores of constants if the target eventually moves to 1474 memory, but better safe than sorry. */ 1475 else if ((reload_in_progress | reload_completed) == 0 1476 && GET_CODE (operands[0]) != MEM 1477 && GET_CODE (operands[1]) == CONST_DOUBLE 1478 && !standard_80387_constant_p (operands[1])) 1479 { 1480 operands[1] = validize_mem (force_const_mem (DFmode, operands[1])); 1481 } 1482}") 1483 1484;; For the purposes of regclass, prefer FLOAT_REGS. 1485(define_insn "" 1486 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r,!o") 1487 (match_operand:DF 1 "general_operand" "fmG,f,*roF,*rF"))] 1488 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) 1489 || (GET_CODE (operands[1]) != MEM)" 1490 "* 1491{ 1492 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 1493 1494 /* First handle a `pop' insn or a `fld %st(0)' */ 1495 1496 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1])) 1497 { 1498 if (stack_top_dies) 1499 return AS1 (fstp,%y0); 1500 else 1501 return AS1 (fld,%y0); 1502 } 1503 1504 /* Handle other kinds of writes from the 387 */ 1505 1506 if (STACK_TOP_P (operands[1])) 1507 { 1508 if (stack_top_dies) 1509 return AS1 (fstp%z0,%y0); 1510 else 1511 return AS1 (fst%z0,%y0); 1512 } 1513 1514 /* Handle other kinds of reads to the 387 */ 1515 1516 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE) 1517 return output_move_const_single (operands); 1518 1519 if (STACK_TOP_P (operands[0])) 1520 return AS1 (fld%z1,%y1); 1521 1522 /* Handle all DFmode moves not involving the 387 */ 1523 1524 return output_move_double (operands); 1525}" 1526 [(set_attr "type" "fld")]) 1527 1528 1529 1530(define_insn "swapdf" 1531 [(set (match_operand:DF 0 "register_operand" "f") 1532 (match_operand:DF 1 "register_operand" "f")) 1533 (set (match_dup 1) 1534 (match_dup 0))] 1535 "" 1536 "* 1537{ 1538 if (STACK_TOP_P (operands[0])) 1539 return AS1 (fxch,%1); 1540 else 1541 return AS1 (fxch,%0); 1542}") 1543 1544(define_insn "movxf_push" 1545 [(set (match_operand:XF 0 "push_operand" "=<,<") 1546 (match_operand:XF 1 "general_operand" "*rfF,o"))] 1547 "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM 1548 || reload_in_progress || reload_completed" 1549 "* 1550{ 1551 if (STACK_REG_P (operands[1])) 1552 { 1553 rtx xops[3]; 1554 1555 xops[0] = AT_SP (XFmode); 1556 xops[1] = GEN_INT (12); 1557 xops[2] = stack_pointer_rtx; 1558 1559 output_asm_insn (AS2 (sub%L2,%1,%2), xops); 1560 1561 output_asm_insn (AS1 (fstp%T0,%0), xops); 1562 if (! find_regno_note (insn, REG_DEAD, FIRST_STACK_REG)) 1563 output_asm_insn (AS1 (fld%T0,%0), xops); 1564 1565 RET; 1566 } 1567 1568 if (which_alternative == 1) 1569 return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode), 0, 0); 1570 1571 return output_move_double (operands); 1572 }") 1573 1574(define_split 1575 [(set (match_operand:XF 0 "push_operand" "") 1576 (match_operand:XF 1 "register_operand" ""))] 1577 "reload_completed && STACK_REG_P (operands[1])" 1578 [(set (reg:SI 7) 1579 (minus:SI (reg:SI 7) (const_int 12))) 1580 (set (mem:XF (reg:SI 7)) 1581 (match_dup 1))] 1582 "") 1583 1584(define_expand "movxf" 1585 [(set (match_operand:XF 0 "general_operand" "") 1586 (match_operand:XF 1 "general_operand" ""))] 1587 "" 1588 " 1589{ 1590 /* Don't generate memory->memory moves, go through a register */ 1591 if (TARGET_MOVE 1592 && no_new_pseudos == 0 1593 && GET_CODE (operands[0]) == MEM 1594 && GET_CODE (operands[1]) == MEM) 1595 { 1596 operands[1] = force_reg (XFmode, operands[1]); 1597 } 1598 1599 /* If we are loading a floating point constant that isn't 0 or 1 1600 into a register, indicate we need the pic register loaded. This could 1601 be optimized into stores of constants if the target eventually moves 1602 to memory, but better safe than sorry. */ 1603 else if ((reload_in_progress | reload_completed) == 0 1604 && GET_CODE (operands[0]) != MEM 1605 && GET_CODE (operands[1]) == CONST_DOUBLE 1606 && !standard_80387_constant_p (operands[1])) 1607 { 1608 operands[1] = validize_mem (force_const_mem (XFmode, operands[1])); 1609 } 1610}") 1611 1612 1613(define_insn "" 1614 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!*r,!o") 1615 (match_operand:XF 1 "general_operand" "fmG,f,*roF,*rF"))] 1616 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) 1617 || (GET_CODE (operands[1]) != MEM)" 1618 "* 1619{ 1620 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 1621 1622 /* First handle a `pop' insn or a `fld %st(0)' */ 1623 1624 if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1])) 1625 { 1626 if (stack_top_dies) 1627 return AS1 (fstp,%y0); 1628 else 1629 return AS1 (fld,%y0); 1630 } 1631 1632 /* Handle other kinds of writes from the 387 */ 1633 1634 if (STACK_TOP_P (operands[1])) 1635 { 1636 output_asm_insn (AS1 (fstp%z0,%y0), operands); 1637 if (! stack_top_dies) 1638 return AS1 (fld%z0,%y0); 1639 1640 RET; 1641 } 1642 1643 /* Handle other kinds of reads to the 387 */ 1644 1645 if (STACK_TOP_P (operands[0]) && GET_CODE (operands[1]) == CONST_DOUBLE) 1646 return output_move_const_single (operands); 1647 1648 if (STACK_TOP_P (operands[0])) 1649 return AS1 (fld%z1,%y1); 1650 1651 /* Handle all XFmode moves not involving the 387 */ 1652 1653 return output_move_double (operands); 1654}") 1655 1656(define_insn "swapxf" 1657 [(set (match_operand:XF 0 "register_operand" "f") 1658 (match_operand:XF 1 "register_operand" "f")) 1659 (set (match_dup 1) 1660 (match_dup 0))] 1661 "" 1662 "* 1663{ 1664 if (STACK_TOP_P (operands[0])) 1665 return AS1 (fxch,%1); 1666 else 1667 return AS1 (fxch,%0); 1668}") 1669 1670(define_insn "" 1671 [(set (match_operand:DI 0 "push_operand" "=<") 1672 (match_operand:DI 1 "general_operand" "riF"))] 1673 "" 1674 "* return output_move_double (operands);") 1675 1676(define_insn "" 1677 [(set (match_operand:DI 0 "push_operand" "=<") 1678 (match_operand:DI 1 "memory_operand" "o"))] 1679 "TARGET_PUSH_MEMORY" 1680 "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DImode),0,0);") 1681 1682(define_expand "movdi" 1683 [(set (match_operand:DI 0 "general_operand" "") 1684 (match_operand:DI 1 "general_operand" ""))] 1685 "" 1686 " 1687{ 1688 /* Don't generate memory->memory moves, go through a register */ 1689 if (TARGET_MOVE 1690 && no_new_pseudos == 0 1691 && GET_CODE (operands[0]) == MEM 1692 && GET_CODE (operands[1]) == MEM) 1693 { 1694 operands[1] = force_reg (DImode, operands[1]); 1695 } 1696}") 1697 1698(define_insn "" 1699 [(set (match_operand:DI 0 "general_operand" "=g,r") 1700 (match_operand:DI 1 "general_operand" "riF,m"))] 1701 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) 1702 || (GET_CODE (operands[1]) != MEM)" 1703 "* return output_move_double (operands);" 1704 [(set_attr "type" "integer,memory") 1705 (set_attr "memory" "*,load")]) 1706 1707(define_split 1708 [(set (match_operand:DI 0 "nonimmediate_operand" "") 1709 (match_operand:DI 1 "general_operand" ""))] 1710 "reload_completed 1711 && (offsettable_memref_p (operands[0]) 1712 || nonmemory_operand (operands[0], DImode)) 1713 && (offsettable_memref_p (operands[1]) 1714 || nonmemory_operand (operands[1], DImode)) 1715 && (! reg_overlap_mentioned_p (gen_lowpart (SImode, operands[0]), 1716 operands[1]) 1717 || ! reg_overlap_mentioned_p (gen_highpart (SImode, operands[0]), 1718 operands[1]))" 1719 [(set (match_dup 2) 1720 (match_dup 4)) 1721 (set (match_dup 3) 1722 (match_dup 5))] 1723 " 1724{ 1725 split_di (&operands[0], 1, &operands[2], &operands[3]); 1726 split_di (&operands[1], 1, &operands[4], &operands[5]); 1727 1728 if (reg_overlap_mentioned_p (operands[2], operands[1])) 1729 { 1730 rtx tmp; 1731 1732 tmp = operands[2]; 1733 operands[2] = operands[3]; 1734 operands[3] = tmp; 1735 1736 tmp = operands[4]; 1737 operands[4] = operands[5]; 1738 operands[5] = tmp; 1739 } 1740}") 1741 1742;;- conversion instructions 1743;;- NONE 1744 1745;;- zero extension instructions 1746;; See comments by `andsi' for when andl is faster than movzx. 1747 1748(define_expand "zero_extendhisi2" 1749 [(set (match_operand:SI 0 "register_operand" "") 1750 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 1751 "" 1752 "") 1753 1754;; When optimizing for the PPro/PII or code size, always use movzwl. 1755;; We want to use a different pattern so we can use different constraints 1756;; than the generic pattern. 1757(define_insn "" 1758 [(set (match_operand:SI 0 "register_operand" "=r") 1759 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 1760 "(optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)" 1761 "* return AS2 (movz%W0%L0,%1,%0);") 1762 1763(define_insn "" 1764 [(set (match_operand:SI 0 "register_operand" "=r,&r,?r") 1765 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))] 1766 "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)" 1767 "* 1768 { 1769 rtx xops[2]; 1770 1771 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0) 1772 && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])) 1773 { 1774 xops[0] = operands[0]; 1775 xops[1] = GEN_INT (0xffff); 1776 output_asm_insn (AS2 (and%L0,%1,%k0), xops); 1777 RET; 1778 } 1779 if (TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])) 1780 { 1781 output_asm_insn (AS2 (xor%L0,%0,%0),operands); 1782 output_asm_insn (AS2 (mov%W0,%1,%w0),operands); 1783 RET; 1784 } 1785 1786 if (TARGET_ZERO_EXTEND_WITH_AND) 1787 { 1788 xops[0] = operands[0]; 1789 xops[1] = GEN_INT (0xffff); 1790 if (i386_aligned_p (operands[1])) 1791 output_asm_insn (AS2 (mov%L0,%k1,%k0),operands); 1792 else 1793 output_asm_insn (AS2 (mov%W0,%1,%w0),operands); 1794 output_asm_insn (AS2 (and%L0,%1,%k0), xops); 1795 RET; 1796 } 1797 1798#ifdef INTEL_SYNTAX 1799 return AS2 (movzx,%1,%0); 1800#else 1801 return AS2 (movz%W0%L0,%1,%0); 1802#endif 1803}") 1804 1805(define_split 1806 [(set (match_operand:SI 0 "register_operand" "") 1807 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 1808 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])" 1809 [(set (match_dup 0) 1810 (const_int 0)) 1811 (set (strict_low_part (match_dup 2)) 1812 (match_dup 1))] 1813 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));") 1814 1815 1816(define_split 1817 [(set (match_operand:SI 0 "register_operand" "") 1818 (zero_extend:SI (match_operand:HI 1 "memory_operand" "")))] 1819 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && reg_overlap_mentioned_p (operands[0], operands[1])" 1820 [(set (strict_low_part (match_dup 2)) 1821 (match_dup 1)) 1822 (set (match_dup 0) 1823 (and:SI (match_dup 0) 1824 (const_int 65535)))] 1825 "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));") 1826 1827(define_expand "zero_extendqihi2" 1828 [(set (match_operand:HI 0 "register_operand" "") 1829 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] 1830 "" 1831 "") 1832 1833(define_insn "" 1834 [(set (match_operand:HI 0 "register_operand" "=r") 1835 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 1836 "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO" 1837 1838 "* return AS2 (movz%B0%W0,%1,%0);") 1839 1840(define_insn "" 1841 [(set (match_operand:HI 0 "register_operand" "=q,&q,?r") 1842 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))] 1843 "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)" 1844 "* 1845 { 1846 rtx xops[2]; 1847 1848 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0) 1849 && REG_P (operands[1]) 1850 && REGNO (operands[0]) == REGNO (operands[1])) 1851 { 1852 xops[0] = operands[0]; 1853 xops[1] = GEN_INT (0xff); 1854 output_asm_insn (AS2 (and%L0,%1,%k0), xops); 1855 RET; 1856 } 1857 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0])) 1858 { 1859 if(!reg_overlap_mentioned_p(operands[0],operands[1])) 1860 { 1861 output_asm_insn (AS2 (xor%L0,%k0,%k0), operands); 1862 output_asm_insn (AS2 (mov%B0,%1,%b0), operands); 1863 } 1864 else 1865 { 1866 xops[0] = operands[0]; 1867 xops[1] = GEN_INT (0xff); 1868 output_asm_insn (AS2 (mov%B0,%1,%b0),operands); 1869 output_asm_insn (AS2 (and%L0,%1,%k0), xops); 1870 } 1871 RET; 1872 } 1873 1874#ifdef INTEL_SYNTAX 1875 return AS2 (movzx,%1,%0); 1876#else 1877 return AS2 (movz%B0%W0,%1,%0); 1878#endif 1879}") 1880 1881(define_split 1882 [(set (match_operand:HI 0 "register_operand" "") 1883 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] 1884 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND 1885 && !reg_overlap_mentioned_p (operands[0], operands[1])" 1886 [(set (match_dup 0) 1887 (const_int 0)) 1888 (set (strict_low_part (match_dup 2)) 1889 (match_dup 1))] 1890 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));") 1891 1892 1893(define_split 1894 [(set (match_operand:HI 0 "register_operand" "") 1895 (zero_extend:HI (match_operand:QI 1 "memory_operand" "")))] 1896 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND 1897 && reg_overlap_mentioned_p (operands[0], operands[1])" 1898 [(set (strict_low_part (match_dup 2)) 1899 (match_dup 1)) 1900 (set (match_dup 0) 1901 (and:HI (match_dup 0) 1902 (const_int 255)))] 1903 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));") 1904 1905(define_split 1906 [(set (match_operand:HI 0 "register_operand" "") 1907 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))] 1908 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND" 1909 [(set (match_dup 0) 1910 (match_dup 2)) 1911 (set (match_dup 0) 1912 (and:HI (match_dup 0) 1913 (const_int 255)))] 1914 "if (GET_CODE (operands[1]) == SUBREG && SUBREG_WORD (operands[1]) == 0) 1915 operands[1] = SUBREG_REG (operands[1]); 1916 if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG 1917 || REGNO (operands[0]) == REGNO (operands[1])) 1918 FAIL; 1919 operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));") 1920 1921(define_expand "zero_extendqisi2" 1922 [(set (match_operand:SI 0 "register_operand" "") 1923 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] 1924 "" 1925 "") 1926 1927(define_insn "" 1928 [(set (match_operand:SI 0 "register_operand" "=r") 1929 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 1930 "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO" 1931 "* return AS2 (movz%B0%L0,%1,%0);") 1932 1933(define_insn "" 1934 [(set (match_operand:SI 0 "register_operand" "=q,&q,?r") 1935 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))] 1936 "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)" 1937 "* 1938 { 1939 rtx xops[2]; 1940 1941 if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0) 1942 && REG_P (operands[1]) 1943 && REGNO (operands[0]) == REGNO (operands[1])) 1944 { 1945 xops[0] = operands[0]; 1946 xops[1] = GEN_INT (0xff); 1947 output_asm_insn (AS2 (and%L0,%1,%k0), xops); 1948 RET; 1949 } 1950 if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0])) 1951 { 1952 if(!reg_overlap_mentioned_p (operands[0], operands[1])) 1953 { 1954 output_asm_insn (AS2 (xor%L0,%0,%0),operands); 1955 output_asm_insn (AS2 (mov%B0,%1,%b0),operands); 1956 } 1957 else 1958 { 1959 xops[0] = operands[0]; 1960 xops[1] = GEN_INT (0xff); 1961 output_asm_insn (AS2 (mov%B0,%1,%b0), operands); 1962 output_asm_insn (AS2 (and%L0,%1,%k0), xops); 1963 } 1964 RET; 1965 } 1966 1967 if (TARGET_ZERO_EXTEND_WITH_AND && GET_CODE (operands[1]) == REG) 1968 { 1969 xops[0] = operands[0]; 1970 xops[1] = GEN_INT (0xff); 1971 operands[1] = gen_rtx_REG (SImode, REGNO (operands[1])); 1972 output_asm_insn (AS2 (mov%L0,%1,%0), operands); 1973 output_asm_insn (AS2 (and%L0,%1,%k0), xops); 1974 RET; 1975 } 1976 1977#ifdef INTEL_SYNTAX 1978 return AS2 (movzx,%1,%0); 1979#else 1980 return AS2 (movz%B0%L0,%1,%0); 1981#endif 1982}") 1983 1984(define_split 1985 [(set (match_operand:SI 0 "register_operand" "") 1986 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] 1987 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND 1988 && !reg_overlap_mentioned_p (operands[0], operands[1])" 1989 [(set (match_dup 0) 1990 (const_int 0)) 1991 (set (strict_low_part (match_dup 2)) 1992 (match_dup 1))] 1993 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));") 1994 1995 1996(define_split 1997 [(set (match_operand:SI 0 "register_operand" "") 1998 (zero_extend:SI (match_operand:QI 1 "memory_operand" "")))] 1999 "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND 2000 && reg_overlap_mentioned_p (operands[0], operands[1])" 2001 [(set (strict_low_part (match_dup 2)) 2002 (match_dup 1)) 2003 (set (match_dup 0) 2004 (and:SI (match_dup 0) 2005 (const_int 255)))] 2006 "operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));") 2007 2008(define_split 2009 [(set (match_operand:SI 0 "register_operand" "") 2010 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))] 2011 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND 2012 && ! reg_overlap_mentioned_p (operands[0], operands[1])" 2013 [(set (match_dup 0) 2014 (match_dup 2)) 2015 (set (match_dup 0) 2016 (and:SI (match_dup 0) 2017 (const_int 255)))] 2018 "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));") 2019 2020(define_insn "zero_extendsidi2" 2021 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o") 2022 (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))] 2023 "" 2024 "#") 2025 2026(define_split 2027 [(set (match_operand:DI 0 "register_operand" "") 2028 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))] 2029 "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])" 2030 [(set (match_dup 4) (const_int 0))] 2031 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 2032 2033(define_split 2034 [(set (match_operand:DI 0 "nonimmediate_operand" "") 2035 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))] 2036 "reload_completed" 2037 [(set (match_dup 3) (match_dup 1)) 2038 (set (match_dup 4) (const_int 0))] 2039 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 2040 2041;;- sign extension instructions 2042 2043(define_insn "extendsidi2" 2044 [(set (match_operand:DI 0 "nonimmediate_operand" "=A,?r,?Ar,*o") 2045 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,*r"))) 2046 (clobber (match_scratch:SI 2 "=X,X,X,&r"))] 2047 "" 2048 "#") 2049 2050;; Extend to memory case when source register does die. 2051(define_split 2052 [(set (match_operand:DI 0 "memory_operand" "") 2053 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 2054 (clobber (match_operand:SI 2 "register_operand" ""))] 2055 "(flow2_completed 2056 && dead_or_set_p (insn, operands[1]) 2057 && !reg_mentioned_p (operands[1], operands[0]))" 2058 [(set (match_dup 3) (match_dup 1)) 2059 (set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) 2060 (set (match_dup 4) (match_dup 1))] 2061 "split_di (&operands[0], 1, &operands[3], &operands[4]);") 2062 2063;; Extend to memory case when source register does not die. 2064(define_split 2065 [(set (match_operand:DI 0 "memory_operand" "") 2066 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 2067 (clobber (match_operand:SI 2 "register_operand" ""))] 2068 "flow2_completed" 2069 [(const_int 0)] 2070 " 2071{ 2072 split_di (&operands[0], 1, &operands[3], &operands[4]); 2073 2074 emit_move_insn (operands[3], operands[1]); 2075 2076 /* Generate a cltd if possible and doing so it profitable. */ 2077 if (true_regnum (operands[1]) == 0 2078 && true_regnum (operands[2]) == 1 2079 && (optimize_size || !TARGET_PENTIUM)) 2080 { 2081 emit_insn (gen_ashrsi3_31 (operands[2], operands[1])); 2082 } 2083 else 2084 { 2085 emit_move_insn (operands[2], operands[1]); 2086 emit_insn (gen_ashrsi3_31 (operands[2], operands[2])); 2087 } 2088 emit_move_insn (operands[4], operands[2]); 2089 DONE; 2090}") 2091 2092;; Extend to register case. Optimize case where source and destination 2093;; registers match and cases where we can use cltd. 2094(define_split 2095 [(set (match_operand:DI 0 "register_operand" "") 2096 (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) 2097 (clobber (match_scratch:SI 2 ""))] 2098 "reload_completed" 2099 [(const_int 0)] 2100 " 2101{ 2102 split_di (&operands[0], 1, &operands[3], &operands[4]); 2103 2104 if (true_regnum (operands[3]) != true_regnum (operands[1])) 2105 emit_move_insn (operands[3], operands[1]); 2106 2107 /* Generate a cltd if possible and doing so it profitable. */ 2108 if (true_regnum (operands[3]) == 0 2109 && (optimize_size || !TARGET_PENTIUM)) 2110 { 2111 emit_insn (gen_ashrsi3_31 (operands[4], operands[3])); 2112 DONE; 2113 } 2114 2115 if (true_regnum (operands[4]) != true_regnum (operands[1])) 2116 emit_move_insn (operands[4], operands[1]); 2117 2118 emit_insn (gen_ashrsi3_31 (operands[4], operands[4])); 2119 DONE; 2120}") 2121 2122;; Note that the i386 programmers' manual says that the opcodes 2123;; are named movsx..., but the assembler on Unix does not accept that. 2124;; We use what the Unix assembler expects. 2125 2126(define_insn "extendhisi2" 2127 [(set (match_operand:SI 0 "register_operand" "=r") 2128 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] 2129 "" 2130 "* 2131{ 2132 if (REGNO (operands[0]) == 0 2133 && REG_P (operands[1]) && REGNO (operands[1]) == 0 2134 && (optimize_size || ix86_cpu != PROCESSOR_K6)) 2135#ifdef INTEL_SYNTAX 2136 return \"cwde\"; 2137#else 2138 return \"cwtl\"; 2139#endif 2140 2141#ifdef INTEL_SYNTAX 2142 return AS2 (movsx,%1,%0); 2143#else 2144 return AS2 (movs%W0%L0,%1,%0); 2145#endif 2146}") 2147 2148(define_insn "extendqihi2" 2149 [(set (match_operand:HI 0 "register_operand" "=r") 2150 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 2151 "" 2152 "* 2153{ 2154 if (REGNO (operands[0]) == 0 2155 && REG_P (operands[1]) && REGNO (operands[1]) == 0 2156 && (optimize_size || ix86_cpu != PROCESSOR_K6)) 2157 return \"cbtw\"; 2158 2159#ifdef INTEL_SYNTAX 2160 return AS2 (movsx,%1,%0); 2161#else 2162 return AS2 (movs%B0%W0,%1,%0); 2163#endif 2164}") 2165 2166(define_insn "extendqisi2" 2167 [(set (match_operand:SI 0 "register_operand" "=r") 2168 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 2169 "" 2170 "* 2171{ 2172#ifdef INTEL_SYNTAX 2173 return AS2 (movsx,%1,%0); 2174#else 2175 return AS2 (movs%B0%L0,%1,%0); 2176#endif 2177}") 2178 2179 2180;; Truncation of long long -> 32 bit 2181 2182(define_expand "truncdisi2" 2183 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m") 2184 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))] 2185 "" 2186 " 2187{ 2188 /* Don't generate memory->memory moves, go through a register */ 2189 if (TARGET_MOVE 2190 && (reload_in_progress | reload_completed) == 0 2191 && GET_CODE (operands[0]) == MEM 2192 && GET_CODE (operands[1]) == MEM) 2193 { 2194 rtx target = gen_reg_rtx (SImode); 2195 emit_insn (gen_truncdisi2 (target, operands[1])); 2196 emit_move_insn (operands[0], target); 2197 DONE; 2198 } 2199}") 2200 2201(define_insn "" 2202 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m") 2203 (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))] 2204 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" 2205 "* 2206{ 2207 rtx low[2], high[2], xops[2]; 2208 2209 split_di (&operands[1], 1, low, high); 2210 xops[0] = operands[0]; 2211 xops[1] = low[0]; 2212 if (!rtx_equal_p (xops[0], xops[1])) 2213 output_asm_insn (AS2 (mov%L0,%1,%0), xops); 2214 2215 RET; 2216}") 2217 2218(define_insn "" 2219 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m") 2220 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r") 2221 (const_int 32))))] 2222 "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" 2223 "* 2224{ 2225 rtx low[2], high[2], xops[2]; 2226 2227 split_di (&operands[1], 1, low, high); 2228 xops[0] = operands[0]; 2229 xops[1] = high[0]; 2230 if (!rtx_equal_p (xops[0], xops[1])) 2231 output_asm_insn (AS2 (mov%L0,%1,%0), xops); 2232 2233 RET; 2234}") 2235 2236 2237 2238;; Conversions between float and double. 2239 2240(define_expand "extendsfdf2" 2241 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "") 2242 (float_extend:DF 2243 (match_operand:SF 1 "nonimmediate_operand" ""))) 2244 (clobber (match_dup 2)) 2245 (clobber (match_dup 3))])] 2246 "TARGET_80387" 2247 " 2248{ 2249 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 2250 operands[1] = force_reg (SFmode, operands[1]); 2251 2252 operands[2] = assign_386_stack_local (SFmode, 0); 2253 operands[3] = assign_386_stack_local (DFmode, 0); 2254}") 2255 2256(define_insn "" 2257 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!f,!*r") 2258 (float_extend:DF 2259 (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f"))) 2260 (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m")) 2261 (clobber (match_operand:DF 3 "memory_operand" "m,m,m,o"))] 2262 "TARGET_80387 && (GET_CODE (operands[0]) != MEM 2263 || GET_CODE (operands[1]) != MEM)" 2264 "* 2265{ 2266 output_float_extend (insn, operands); 2267 return \"\"; 2268}" 2269 [(set_attr "type" "fld,fpop,fld,fpop")]) 2270 2271(define_split 2272 [(set (match_operand:DF 0 "register_operand" "") 2273 (float_extend:DF (match_operand:SF 1 "register_operand" ""))) 2274 (clobber (match_operand:SF 2 "memory_operand" "")) 2275 (clobber (match_operand:DF 3 "memory_operand" ""))] 2276 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])" 2277 [(set (match_dup 2) 2278 (match_dup 1)) 2279 (set (match_dup 0) 2280 (float_extend:DF (match_dup 2)))] 2281 "") 2282 2283(define_split 2284 [(set (match_operand:DF 0 "register_operand" "") 2285 (float_extend:DF (match_operand:SF 1 "register_operand" ""))) 2286 (clobber (match_operand:SF 2 "memory_operand" "")) 2287 (clobber (match_operand:DF 3 "memory_operand" ""))] 2288 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])" 2289 [(set (match_dup 3) 2290 (float_extend:DF (match_dup 1))) 2291 (set (match_dup 0) 2292 (match_dup 3))] 2293 "") 2294 2295(define_split 2296 [(set (match_operand:DF 0 "nonimmediate_operand" "") 2297 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" ""))) 2298 (clobber (match_operand:SF 2 "memory_operand" "")) 2299 (clobber (match_operand:DF 3 "memory_operand" ""))] 2300 "TARGET_80387 && reload_completed" 2301 [(set (match_dup 0) 2302 (float_extend:DF (match_dup 1)))] 2303 "") 2304 2305(define_insn "" 2306 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m") 2307 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 2308 "TARGET_80387 && (GET_CODE (operands[0]) != MEM 2309 || GET_CODE (operands[1]) != MEM)" 2310 "* 2311{ 2312 output_float_extend (insn, operands); 2313 return \"\"; 2314}" 2315 [(set_attr "type" "fld,fpop")]) 2316 2317(define_expand "extenddfxf2" 2318 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "") 2319 (float_extend:XF 2320 (match_operand:DF 1 "nonimmediate_operand" ""))) 2321 (clobber (match_dup 2)) 2322 (clobber (match_dup 3))])] 2323 "TARGET_80387" 2324 " 2325{ 2326 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 2327 operands[1] = force_reg (DFmode, operands[1]); 2328 2329 operands[2] = assign_386_stack_local (DFmode, 0); 2330 operands[3] = assign_386_stack_local (XFmode, 0); 2331}") 2332 2333(define_insn "" 2334 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r") 2335 (float_extend:XF 2336 (match_operand:DF 1 "nonimmediate_operand" "fm,f,*r,f"))) 2337 (clobber (match_operand:DF 2 "memory_operand" "m,m,o,m")) 2338 (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))] 2339 "TARGET_80387 && (GET_CODE (operands[0]) != MEM 2340 || GET_CODE (operands[1]) != MEM)" 2341 "* 2342{ 2343 output_float_extend (insn, operands); 2344 return \"\"; 2345}" 2346 [(set_attr "type" "fld,fpop,fld,fpop")]) 2347 2348(define_split 2349 [(set (match_operand:XF 0 "register_operand" "") 2350 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 2351 (clobber (match_operand:DF 2 "memory_operand" "")) 2352 (clobber (match_operand:XF 3 "memory_operand" ""))] 2353 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])" 2354 [(set (match_dup 2) 2355 (match_dup 1)) 2356 (set (match_dup 0) 2357 (float_extend:XF (match_dup 2)))] 2358 "") 2359 2360(define_split 2361 [(set (match_operand:XF 0 "register_operand" "") 2362 (float_extend:XF (match_operand:DF 1 "register_operand" ""))) 2363 (clobber (match_operand:DF 2 "memory_operand" "")) 2364 (clobber (match_operand:XF 3 "memory_operand" ""))] 2365 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])" 2366 [(set (match_dup 3) 2367 (float_extend:XF (match_dup 1))) 2368 (set (match_dup 0) 2369 (match_dup 3))] 2370 "") 2371 2372(define_split 2373 [(set (match_operand:XF 0 "nonimmediate_operand" "") 2374 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" ""))) 2375 (clobber (match_operand:DF 2 "memory_operand" "")) 2376 (clobber (match_operand:XF 3 "memory_operand" ""))] 2377 "TARGET_80387 && reload_completed" 2378 [(set (match_dup 0) 2379 (float_extend:XF (match_dup 1)))] 2380 "") 2381 2382(define_insn "" 2383 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 2384 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))] 2385 "TARGET_80387 && (GET_CODE (operands[0]) != MEM 2386 || GET_CODE (operands[1]) != MEM)" 2387 "* 2388{ 2389 output_float_extend (insn, operands); 2390 return \"\"; 2391}" 2392 [(set_attr "type" "fld,fpop")]) 2393 2394(define_expand "extendsfxf2" 2395 [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "") 2396 (float_extend:XF 2397 (match_operand:SF 1 "nonimmediate_operand" ""))) 2398 (clobber (match_dup 2)) 2399 (clobber (match_dup 3))])] 2400 "TARGET_80387" 2401 " 2402{ 2403 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 2404 operands[1] = force_reg (SFmode, operands[1]); 2405 2406 operands[2] = assign_386_stack_local (SFmode, 0); 2407 operands[3] = assign_386_stack_local (XFmode, 0); 2408}") 2409 2410(define_insn "" 2411 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r") 2412 (float_extend:XF 2413 (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f"))) 2414 (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m")) 2415 (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))] 2416 "TARGET_80387 && (GET_CODE (operands[0]) != MEM 2417 || GET_CODE (operands[1]) != MEM)" 2418 "* 2419{ 2420 output_float_extend (insn, operands); 2421 return \"\"; 2422}" 2423 [(set_attr "type" "fld,fpop,fld,fpop")]) 2424 2425(define_split 2426 [(set (match_operand:XF 0 "register_operand" "") 2427 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 2428 (clobber (match_operand:SF 2 "memory_operand" "")) 2429 (clobber (match_operand:XF 3 "memory_operand" ""))] 2430 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])" 2431 [(set (match_dup 2) 2432 (match_dup 1)) 2433 (set (match_dup 0) 2434 (float_extend:XF (match_dup 2)))] 2435 "") 2436 2437(define_split 2438 [(set (match_operand:XF 0 "register_operand" "") 2439 (float_extend:XF (match_operand:SF 1 "register_operand" ""))) 2440 (clobber (match_operand:SF 2 "memory_operand" "")) 2441 (clobber (match_operand:XF 3 "memory_operand" ""))] 2442 "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])" 2443 [(set (match_dup 3) 2444 (float_extend:XF (match_dup 1))) 2445 (set (match_dup 0) 2446 (match_dup 3))] 2447 "") 2448 2449(define_split 2450 [(set (match_operand:XF 0 "nonimmediate_operand" "") 2451 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" ""))) 2452 (clobber (match_operand:SF 2 "memory_operand" "")) 2453 (clobber (match_operand:XF 3 "memory_operand" ""))] 2454 "TARGET_80387 && reload_completed" 2455 [(set (match_dup 0) 2456 (float_extend:XF (match_dup 1)))] 2457 "") 2458 2459(define_insn "" 2460 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 2461 (float_extend:XF 2462 (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 2463 "TARGET_80387 && (GET_CODE (operands[0]) != MEM 2464 || GET_CODE (operands[1]) != MEM)" 2465 "* 2466{ 2467 output_float_extend (insn, operands); 2468 return \"\"; 2469}" 2470 [(set_attr "type" "fld,fpop")]) 2471 2472(define_expand "truncdfsf2" 2473 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") 2474 (float_truncate:SF 2475 (match_operand:DF 1 "register_operand" ""))) 2476 (clobber (match_dup 2))])] 2477 "TARGET_80387" 2478 " 2479{ 2480 operands[2] = (rtx) assign_386_stack_local (SFmode, 0); 2481}") 2482 2483(define_insn "" 2484 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r") 2485 (float_truncate:SF 2486 (match_operand:DF 1 "register_operand" "0,f,f"))) 2487 (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))] 2488 "TARGET_80387" 2489 "* 2490{ 2491 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 2492 rtx xops[1]; 2493 2494 xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2]; 2495 2496 if (stack_top_dies || STACK_REG_P (operands[0])) 2497 output_asm_insn (AS1 (fstp%z0,%0), xops); 2498 else 2499 output_asm_insn (AS1 (fst%z0,%0), xops); 2500 2501 if (STACK_REG_P (operands[0])) 2502 return AS1 (fld%z2,%2); 2503 else if (NON_STACK_REG_P (operands[0])) 2504 return AS2 (mov%L0,%2,%0); 2505 2506 return \"\"; 2507}" 2508 [(set_attr "type" "fpop")]) 2509 2510(define_split 2511 [(set (match_operand:SF 0 "register_operand" "") 2512 (float_truncate:SF (match_operand:DF 1 "register_operand" ""))) 2513 (clobber (match_operand:SF 2 "memory_operand" ""))] 2514 "TARGET_80387 && reload_completed" 2515 [(set (match_dup 2) 2516 (float_truncate:SF (match_dup 1))) 2517 (set (match_dup 0) 2518 (match_dup 2))] 2519 "") 2520 2521(define_split 2522 [(set (match_operand:SF 0 "memory_operand" "") 2523 (float_truncate:SF (match_operand:DF 1 "register_operand" ""))) 2524 (clobber (match_operand:SF 2 "memory_operand" ""))] 2525 "TARGET_80387 && reload_completed" 2526 [(set (match_dup 0) 2527 (float_truncate:SF (match_dup 1)))] 2528 "") 2529 2530;; This cannot output into an f-reg because there is no way to be sure 2531;; of truncating in that case. 2532 2533(define_insn "" 2534 [(set (match_operand:SF 0 "memory_operand" "=m") 2535 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))] 2536 "TARGET_80387" 2537 "* 2538{ 2539 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 2540 2541 if (stack_top_dies) 2542 return AS1 (fstp%z0,%0); 2543 else 2544 return AS1 (fst%z0,%0); 2545}" 2546 [(set_attr "type" "fpop")]) 2547 2548(define_expand "truncxfsf2" 2549 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") 2550 (float_truncate:SF 2551 (match_operand:XF 1 "register_operand" ""))) 2552 (clobber (match_dup 2))])] 2553 "TARGET_80387" 2554 " 2555{ 2556 operands[2] = (rtx) assign_386_stack_local (SFmode, 0); 2557}") 2558 2559(define_insn "" 2560 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r") 2561 (float_truncate:SF 2562 (match_operand:XF 1 "register_operand" "0,f,f"))) 2563 (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))] 2564 "TARGET_80387" 2565 "* 2566{ 2567 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 2568 rtx xops[1]; 2569 2570 xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2]; 2571 2572 if (stack_top_dies || STACK_REG_P (operands[0])) 2573 output_asm_insn (AS1 (fstp%z0,%0), xops); 2574 else 2575 output_asm_insn (AS1 (fst%z0,%0), xops); 2576 2577 if (STACK_REG_P (operands[0])) 2578 return AS1 (fld%z2,%2); 2579 else if (NON_STACK_REG_P (operands[0])) 2580 return AS2 (mov%L0,%2,%0); 2581 2582 return \"\"; 2583}" 2584 [(set_attr "type" "fpop")]) 2585 2586(define_split 2587 [(set (match_operand:SF 0 "register_operand" "") 2588 (float_truncate:SF (match_operand:XF 1 "register_operand" ""))) 2589 (clobber (match_operand:SF 2 "memory_operand" ""))] 2590 "TARGET_80387 && reload_completed" 2591 [(set (match_dup 2) 2592 (float_truncate:SF (match_dup 1))) 2593 (set (match_dup 0) 2594 (match_dup 2))] 2595 "") 2596 2597(define_split 2598 [(set (match_operand:SF 0 "memory_operand" "") 2599 (float_truncate:SF (match_operand:XF 1 "register_operand" ""))) 2600 (clobber (match_operand:SF 2 "memory_operand" ""))] 2601 "TARGET_80387 && reload_completed" 2602 [(set (match_dup 0) 2603 (float_truncate:SF (match_dup 1)))] 2604 "") 2605 2606(define_insn "" 2607 [(set (match_operand:SF 0 "memory_operand" "=m") 2608 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))] 2609 "TARGET_80387" 2610 "* 2611{ 2612 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 2613 2614 if (stack_top_dies) 2615 return AS1 (fstp%z0,%0); 2616 else 2617 return AS1 (fst%z0,%0); 2618}" 2619 [(set_attr "type" "fpop")]) 2620 2621(define_expand "truncxfdf2" 2622 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "") 2623 (float_truncate:DF 2624 (match_operand:XF 1 "register_operand" ""))) 2625 (clobber (match_dup 2))])] 2626 "TARGET_80387" 2627 " 2628{ 2629 operands[2] = (rtx) assign_386_stack_local (DFmode, 0); 2630}") 2631 2632(define_insn "" 2633 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r") 2634 (float_truncate:DF 2635 (match_operand:XF 1 "register_operand" "0,f,f"))) 2636 (clobber (match_operand:DF 2 "memory_operand" "m,m,o"))] 2637 "TARGET_80387" 2638 "* 2639{ 2640 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 2641 rtx xops[2]; 2642 2643 xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2]; 2644 2645 if (stack_top_dies || STACK_REG_P (operands[0])) 2646 output_asm_insn (AS1 (fstp%z0,%0), xops); 2647 else 2648 output_asm_insn (AS1 (fst%z0,%0), xops); 2649 2650 if (STACK_REG_P (operands[0])) 2651 return AS1 (fld%z2,%2); 2652 else if (NON_STACK_REG_P (operands[0])) 2653 { 2654 xops[0] = operands[0]; 2655 xops[1] = operands[2]; 2656 output_asm_insn (output_move_double (xops), xops); 2657 } 2658 2659 return \"\"; 2660}" 2661 [(set_attr "type" "fpop")]) 2662 2663(define_split 2664 [(set (match_operand:DF 0 "register_operand" "") 2665 (float_truncate:DF (match_operand:XF 1 "register_operand" ""))) 2666 (clobber (match_operand:DF 2 "memory_operand" ""))] 2667 "TARGET_80387 && reload_completed" 2668 [(set (match_dup 2) 2669 (float_truncate:DF (match_dup 1))) 2670 (set (match_dup 0) 2671 (match_dup 2))] 2672 "") 2673 2674(define_split 2675 [(set (match_operand:DF 0 "memory_operand" "") 2676 (float_truncate:DF (match_operand:XF 1 "register_operand" ""))) 2677 (clobber (match_operand:DF 2 "memory_operand" ""))] 2678 "TARGET_80387 && reload_completed" 2679 [(set (match_dup 0) 2680 (float_truncate:DF (match_dup 1)))] 2681 "") 2682 2683(define_insn "" 2684 [(set (match_operand:DF 0 "memory_operand" "=m") 2685 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))] 2686 "TARGET_80387" 2687 "* 2688{ 2689 int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; 2690 2691 if (stack_top_dies) 2692 return AS1 (fstp%z0,%0); 2693 else 2694 return AS1 (fst%z0,%0); 2695}" 2696 [(set_attr "type" "fpop")]) 2697 2698;; Conversions between floating point and fix point. 2699 2700(define_expand "fix_truncsfsi2" 2701 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 2702 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "")))) 2703 (clobber (match_dup 2)) 2704 (clobber (match_dup 3)) 2705 (clobber (match_dup 4)) 2706 (clobber (match_scratch:HI 5 ""))])] 2707 "TARGET_80387" 2708 " 2709{ 2710 operands[2] = (rtx) assign_386_stack_local (HImode, 0); 2711 operands[3] = (rtx) assign_386_stack_local (HImode, 1); 2712 operands[4] = (rtx) assign_386_stack_local (SImode, 0); 2713}") 2714 2715(define_insn "" 2716 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r") 2717 (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f,f")))) 2718 (clobber (match_operand:HI 2 "memory_operand" "m,m")) 2719 (clobber (match_operand:HI 3 "memory_operand" "m,m")) 2720 (clobber (match_operand:SI 4 "memory_operand" "m,m")) 2721 (clobber (match_scratch:HI 5 "=&r,&r"))] 2722 "TARGET_80387" 2723 "* return output_fix_trunc (insn, operands);" 2724 [(set_attr "type" "fpop")]) 2725 2726(define_expand "fix_truncsfdi2" 2727 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 2728 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "")))) 2729 (clobber (match_dup 1)) 2730 (clobber (match_dup 2)) 2731 (clobber (match_dup 3)) 2732 (clobber (match_dup 4)) 2733 (clobber (match_scratch:HI 5 ""))])] 2734 "TARGET_80387" 2735 " 2736{ 2737 operands[1] = copy_to_mode_reg (SFmode, operands[1]); 2738 operands[2] = (rtx) assign_386_stack_local (HImode, 0); 2739 operands[3] = (rtx) assign_386_stack_local (HImode, 1); 2740 operands[4] = (rtx) assign_386_stack_local (DImode, 0); 2741}") 2742 2743(define_insn "" 2744 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r") 2745 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f,f")))) 2746 (clobber (match_dup 1)) 2747 (clobber (match_operand:HI 2 "memory_operand" "m,m")) 2748 (clobber (match_operand:HI 3 "memory_operand" "m,m")) 2749 (clobber (match_operand:DI 4 "memory_operand" "m,o")) 2750 (clobber (match_scratch:HI 5 "=&r,&r"))] 2751 "TARGET_80387" 2752 "* return output_fix_trunc (insn, operands);" 2753 [(set_attr "type" "fpop")]) 2754 2755(define_expand "fix_truncdfsi2" 2756 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 2757 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "")))) 2758 (clobber (match_dup 2)) 2759 (clobber (match_dup 3)) 2760 (clobber (match_dup 4)) 2761 (clobber (match_scratch:HI 5 ""))])] 2762 "TARGET_80387" 2763 " 2764{ 2765 operands[2] = (rtx) assign_386_stack_local (HImode, 0); 2766 operands[3] = (rtx) assign_386_stack_local (HImode, 1); 2767 operands[4] = (rtx) assign_386_stack_local (SImode, 0); 2768}") 2769 2770(define_insn "" 2771 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r") 2772 (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f,f")))) 2773 (clobber (match_operand:HI 2 "memory_operand" "m,m")) 2774 (clobber (match_operand:HI 3 "memory_operand" "m,m")) 2775 (clobber (match_operand:SI 4 "memory_operand" "m,m")) 2776 (clobber (match_scratch:HI 5 "=&r,&r"))] 2777 "TARGET_80387" 2778 "* return output_fix_trunc (insn, operands);" 2779 [(set_attr "type" "fpop")]) 2780 2781(define_expand "fix_truncdfdi2" 2782 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 2783 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "")))) 2784 (clobber (match_dup 1)) 2785 (clobber (match_dup 2)) 2786 (clobber (match_dup 3)) 2787 (clobber (match_dup 4)) 2788 (clobber (match_scratch:HI 5 ""))])] 2789 "TARGET_80387" 2790 " 2791{ 2792 operands[1] = copy_to_mode_reg (DFmode, operands[1]); 2793 operands[2] = (rtx) assign_386_stack_local (HImode, 0); 2794 operands[3] = (rtx) assign_386_stack_local (HImode, 1); 2795 operands[4] = (rtx) assign_386_stack_local (DImode, 0); 2796}") 2797 2798(define_insn "" 2799 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r") 2800 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f,f")))) 2801 (clobber (match_dup 1)) 2802 (clobber (match_operand:HI 2 "memory_operand" "m,m")) 2803 (clobber (match_operand:HI 3 "memory_operand" "m,m")) 2804 (clobber (match_operand:DI 4 "memory_operand" "m,o")) 2805 (clobber (match_scratch:HI 5 "=&r,&r"))] 2806 "TARGET_80387" 2807 "* return output_fix_trunc (insn, operands);" 2808 [(set_attr "type" "fpop")]) 2809 2810(define_expand "fix_truncxfsi2" 2811 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") 2812 (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "")))) 2813 (clobber (match_dup 2)) 2814 (clobber (match_dup 3)) 2815 (clobber (match_dup 4)) 2816 (clobber (match_scratch:HI 5 ""))])] 2817 "TARGET_80387" 2818 " 2819{ 2820 operands[2] = (rtx) assign_386_stack_local (HImode, 0); 2821 operands[3] = (rtx) assign_386_stack_local (HImode, 1); 2822 operands[4] = (rtx) assign_386_stack_local (SImode, 0); 2823}") 2824 2825(define_insn "" 2826 [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!&r") 2827 (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f,f")))) 2828 (clobber (match_operand:HI 2 "memory_operand" "m,m")) 2829 (clobber (match_operand:HI 3 "memory_operand" "m,m")) 2830 (clobber (match_operand:SI 4 "memory_operand" "m,m")) 2831 (clobber (match_scratch:HI 5 "=&r,&r"))] 2832 "TARGET_80387" 2833 "* return output_fix_trunc (insn, operands);" 2834 [(set_attr "type" "fpop")]) 2835 2836(define_expand "fix_truncxfdi2" 2837 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") 2838 (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "")))) 2839 (clobber (match_dup 1)) 2840 (clobber (match_dup 2)) 2841 (clobber (match_dup 3)) 2842 (clobber (match_dup 4)) 2843 (clobber (match_scratch:HI 5 ""))])] 2844 "TARGET_80387" 2845 " 2846{ 2847 operands[1] = copy_to_mode_reg (XFmode, operands[1]); 2848 operands[2] = (rtx) assign_386_stack_local (HImode, 0); 2849 operands[3] = (rtx) assign_386_stack_local (HImode, 1); 2850 operands[4] = (rtx) assign_386_stack_local (DImode, 0); 2851}") 2852 2853(define_insn "" 2854 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!&r") 2855 (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f,f")))) 2856 (clobber (match_dup 1)) 2857 (clobber (match_operand:HI 2 "memory_operand" "m,m")) 2858 (clobber (match_operand:HI 3 "memory_operand" "m,m")) 2859 (clobber (match_operand:DI 4 "memory_operand" "m,o")) 2860 (clobber (match_scratch:HI 5 "=&r,&r"))] 2861 "TARGET_80387" 2862 "* return output_fix_trunc (insn, operands);" 2863 [(set_attr "type" "fpop")]) 2864 2865;; Conversion between fixed point and floating point. 2866 2867;; ??? Possibly represent floatunssidf2 here in gcc2. 2868 2869(define_expand "floatsisf2" 2870 [(parallel [(set (match_operand:SF 0 "register_operand" "") 2871 (float:SF (match_operand:SI 1 "nonimmediate_operand" ""))) 2872 (clobber (match_dup 2))])] 2873 "TARGET_80387" 2874 "operands[2] = assign_386_stack_local (SImode, 0);") 2875 2876(define_insn "" 2877 [(set (match_operand:SF 0 "register_operand" "=f,f") 2878 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,!r"))) 2879 (clobber (match_operand:SI 2 "memory_operand" "m,m"))] 2880 "TARGET_80387" 2881 "#") 2882 2883(define_split 2884 [(set (match_operand:SF 0 "register_operand" "") 2885 (float:SF (match_operand:SI 1 "memory_operand" ""))) 2886 (clobber (match_operand:SI 2 "memory_operand" ""))] 2887 "TARGET_80387 && reload_completed" 2888 [(set (match_dup 0) 2889 (float:SF (match_dup 1)))] 2890 "") 2891 2892(define_split 2893 [(set (match_operand:SF 0 "register_operand" "") 2894 (float:SF (match_operand:SI 1 "register_operand" ""))) 2895 (clobber (match_operand:SI 2 "memory_operand" ""))] 2896 "TARGET_80387 && reload_completed" 2897 [(set (match_dup 2) 2898 (match_dup 1)) 2899 (set (match_dup 0) 2900 (float:SF (match_dup 2)))] 2901 "") 2902 2903(define_insn "" 2904 [(set (match_operand:SF 0 "register_operand" "=f") 2905 (float:SF (match_operand:SI 1 "memory_operand" "m")))] 2906 "TARGET_80387" 2907 "* return AS1 (fild%z1,%1);" 2908 [(set_attr "type" "fpop")]) 2909 2910(define_expand "floathisf2" 2911 [(parallel [(set (match_operand:SF 0 "register_operand" "") 2912 (float:SF (match_operand:HI 1 "nonimmediate_operand" ""))) 2913 (clobber (match_dup 2))])] 2914 "TARGET_80387" 2915 "operands[2] = assign_386_stack_local (HImode, 0);") 2916 2917(define_insn "" 2918 [(set (match_operand:SF 0 "register_operand" "=f,f") 2919 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,!r"))) 2920 (clobber (match_operand:HI 2 "memory_operand" "m,m"))] 2921 "TARGET_80387" 2922 "#") 2923 2924(define_split 2925 [(set (match_operand:SF 0 "register_operand" "") 2926 (float:SF (match_operand:HI 1 "memory_operand" ""))) 2927 (clobber (match_operand:HI 2 "memory_operand" ""))] 2928 "TARGET_80387 && reload_completed" 2929 [(set (match_dup 0) 2930 (float:SF (match_dup 1)))] 2931 "") 2932 2933(define_split 2934 [(set (match_operand:SF 0 "register_operand" "") 2935 (float:SF (match_operand:HI 1 "register_operand" ""))) 2936 (clobber (match_operand:HI 2 "memory_operand" ""))] 2937 "TARGET_80387 && reload_completed" 2938 [(set (match_dup 2) 2939 (match_dup 1)) 2940 (set (match_dup 0) 2941 (float:SF (match_dup 2)))] 2942 "") 2943 2944(define_insn "" 2945 [(set (match_operand:SF 0 "register_operand" "=f") 2946 (float:SF (match_operand:HI 1 "memory_operand" "m")))] 2947 "TARGET_80387" 2948 "* return AS1 (fild%z1,%1);" 2949 [(set_attr "type" "fpop")]) 2950 2951(define_expand "floatdisf2" 2952 [(parallel [(set (match_operand:SF 0 "register_operand" "") 2953 (float:SF (match_operand:DI 1 "nonimmediate_operand" ""))) 2954 (clobber (match_dup 2))])] 2955 "TARGET_80387" 2956 "operands[2] = assign_386_stack_local (DImode, 0);") 2957 2958(define_insn "" 2959 [(set (match_operand:SF 0 "register_operand" "=f,f") 2960 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,!r"))) 2961 (clobber (match_operand:DI 2 "memory_operand" "m,o"))] 2962 "TARGET_80387" 2963 "#") 2964 2965(define_split 2966 [(set (match_operand:SF 0 "register_operand" "") 2967 (float:SF (match_operand:DI 1 "memory_operand" ""))) 2968 (clobber (match_operand:DI 2 "memory_operand" ""))] 2969 "TARGET_80387 && reload_completed" 2970 [(set (match_dup 0) 2971 (float:SF (match_dup 1)))] 2972 "") 2973 2974(define_split 2975 [(set (match_operand:SF 0 "register_operand" "") 2976 (float:SF (match_operand:DI 1 "register_operand" ""))) 2977 (clobber (match_operand:DI 2 "memory_operand" ""))] 2978 "TARGET_80387 && reload_completed" 2979 [(set (match_dup 2) 2980 (match_dup 1)) 2981 (set (match_dup 0) 2982 (float:SF (match_dup 2)))] 2983 "") 2984 2985(define_insn "" 2986 [(set (match_operand:SF 0 "register_operand" "=f") 2987 (float:SF (match_operand:DI 1 "memory_operand" "m")))] 2988 "TARGET_80387" 2989 "* return AS1 (fild%z1,%1);" 2990 [(set_attr "type" "fpop")]) 2991 2992(define_expand "floatsidf2" 2993 [(parallel [(set (match_operand:DF 0 "register_operand" "") 2994 (float:DF (match_operand:SI 1 "nonimmediate_operand" ""))) 2995 (clobber (match_dup 2))])] 2996 "TARGET_80387" 2997 "operands[2] = assign_386_stack_local (SImode, 0);") 2998 2999(define_insn "" 3000 [(set (match_operand:DF 0 "register_operand" "=f,f") 3001 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,!r"))) 3002 (clobber (match_operand:SI 2 "memory_operand" "m,m"))] 3003 "TARGET_80387" 3004 "#") 3005 3006(define_split 3007 [(set (match_operand:DF 0 "register_operand" "") 3008 (float:DF (match_operand:SI 1 "memory_operand" ""))) 3009 (clobber (match_operand:SI 2 "memory_operand" ""))] 3010 "TARGET_80387 && reload_completed" 3011 [(set (match_dup 0) 3012 (float:DF (match_dup 1)))] 3013 "") 3014 3015(define_split 3016 [(set (match_operand:DF 0 "register_operand" "") 3017 (float:DF (match_operand:SI 1 "register_operand" ""))) 3018 (clobber (match_operand:SI 2 "memory_operand" ""))] 3019 "TARGET_80387 && reload_completed" 3020 [(set (match_dup 2) 3021 (match_dup 1)) 3022 (set (match_dup 0) 3023 (float:DF (match_dup 2)))] 3024 "") 3025 3026(define_insn "" 3027 [(set (match_operand:DF 0 "register_operand" "=f") 3028 (float:DF (match_operand:SI 1 "memory_operand" "m")))] 3029 "TARGET_80387" 3030 "* return AS1 (fild%z1,%1);" 3031 [(set_attr "type" "fpop")]) 3032 3033(define_expand "floathidf2" 3034 [(parallel [(set (match_operand:DF 0 "register_operand" "") 3035 (float:DF (match_operand:HI 1 "nonimmediate_operand" ""))) 3036 (clobber (match_dup 2))])] 3037 "TARGET_80387" 3038 "operands[2] = assign_386_stack_local (HImode, 0);") 3039 3040(define_insn "" 3041 [(set (match_operand:DF 0 "register_operand" "=f,f") 3042 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,!r"))) 3043 (clobber (match_operand:HI 2 "memory_operand" "m,m"))] 3044 "TARGET_80387" 3045 "#") 3046 3047(define_split 3048 [(set (match_operand:DF 0 "register_operand" "") 3049 (float:DF (match_operand:HI 1 "memory_operand" ""))) 3050 (clobber (match_operand:HI 2 "memory_operand" ""))] 3051 "TARGET_80387 && reload_completed" 3052 [(set (match_dup 0) 3053 (float:DF (match_dup 1)))] 3054 "") 3055 3056(define_split 3057 [(set (match_operand:DF 0 "register_operand" "") 3058 (float:DF (match_operand:HI 1 "register_operand" ""))) 3059 (clobber (match_operand:HI 2 "memory_operand" ""))] 3060 "TARGET_80387 && reload_completed" 3061 [(set (match_dup 2) 3062 (match_dup 1)) 3063 (set (match_dup 0) 3064 (float:DF (match_dup 2)))] 3065 "") 3066 3067(define_insn "" 3068 [(set (match_operand:DF 0 "register_operand" "=f") 3069 (float:DF (match_operand:HI 1 "memory_operand" "m")))] 3070 "TARGET_80387" 3071 "* return AS1 (fild%z1,%1);" 3072 [(set_attr "type" "fpop")]) 3073 3074(define_expand "floatdidf2" 3075 [(parallel [(set (match_operand:DF 0 "register_operand" "") 3076 (float:DF (match_operand:DI 1 "nonimmediate_operand" ""))) 3077 (clobber (match_dup 2))])] 3078 "TARGET_80387" 3079 "operands[2] = assign_386_stack_local (DImode, 0);") 3080 3081(define_insn "" 3082 [(set (match_operand:DF 0 "register_operand" "=f,f") 3083 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,!r"))) 3084 (clobber (match_operand:DI 2 "memory_operand" "m,o"))] 3085 "TARGET_80387" 3086 "#") 3087 3088(define_split 3089 [(set (match_operand:DF 0 "register_operand" "") 3090 (float:DF (match_operand:DI 1 "memory_operand" ""))) 3091 (clobber (match_operand:DI 2 "memory_operand" ""))] 3092 "TARGET_80387 && reload_completed" 3093 [(set (match_dup 0) 3094 (float:DF (match_dup 1)))] 3095 "") 3096 3097(define_split 3098 [(set (match_operand:DF 0 "register_operand" "") 3099 (float:DF (match_operand:DI 1 "register_operand" ""))) 3100 (clobber (match_operand:DI 2 "memory_operand" ""))] 3101 "TARGET_80387 && reload_completed" 3102 [(set (match_dup 2) 3103 (match_dup 1)) 3104 (set (match_dup 0) 3105 (float:DF (match_dup 2)))] 3106 "") 3107 3108(define_insn "" 3109 [(set (match_operand:DF 0 "register_operand" "=f") 3110 (float:DF (match_operand:DI 1 "memory_operand" "m")))] 3111 "TARGET_80387" 3112 "* return AS1 (fild%z1,%1);" 3113 [(set_attr "type" "fpop")]) 3114 3115(define_expand "floatsixf2" 3116 [(parallel [(set (match_operand:XF 0 "register_operand" "") 3117 (float:XF (match_operand:SI 1 "nonimmediate_operand" ""))) 3118 (clobber (match_dup 2))])] 3119 "TARGET_80387" 3120 "operands[2] = assign_386_stack_local (SImode, 0);") 3121 3122(define_insn "" 3123 [(set (match_operand:XF 0 "register_operand" "=f,f") 3124 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!r"))) 3125 (clobber (match_operand:SI 2 "memory_operand" "m,m"))] 3126 "TARGET_80387" 3127 "#") 3128 3129(define_split 3130 [(set (match_operand:XF 0 "register_operand" "") 3131 (float:XF (match_operand:SI 1 "memory_operand" ""))) 3132 (clobber (match_operand:SI 2 "memory_operand" ""))] 3133 "TARGET_80387 && reload_completed" 3134 [(set (match_dup 0) 3135 (float:XF (match_dup 1)))] 3136 "") 3137 3138(define_split 3139 [(set (match_operand:XF 0 "register_operand" "") 3140 (float:XF (match_operand:SI 1 "register_operand" ""))) 3141 (clobber (match_operand:SI 2 "memory_operand" ""))] 3142 "TARGET_80387 && reload_completed" 3143 [(set (match_dup 2) 3144 (match_dup 1)) 3145 (set (match_dup 0) 3146 (float:XF (match_dup 2)))] 3147 "") 3148 3149(define_insn "" 3150 [(set (match_operand:XF 0 "register_operand" "=f") 3151 (float:XF (match_operand:SI 1 "memory_operand" "m")))] 3152 "TARGET_80387" 3153 "* return AS1 (fild%z1,%1);" 3154 [(set_attr "type" "fpop")]) 3155 3156(define_expand "floathixf2" 3157 [(parallel [(set (match_operand:XF 0 "register_operand" "") 3158 (float:XF (match_operand:HI 1 "nonimmediate_operand" ""))) 3159 (clobber (match_dup 2))])] 3160 "TARGET_80387" 3161 "operands[2] = assign_386_stack_local (HImode, 0);") 3162 3163(define_insn "" 3164 [(set (match_operand:XF 0 "register_operand" "=f,f") 3165 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,!r"))) 3166 (clobber (match_operand:HI 2 "memory_operand" "m,m"))] 3167 "TARGET_80387" 3168 "#") 3169 3170(define_split 3171 [(set (match_operand:XF 0 "register_operand" "") 3172 (float:XF (match_operand:HI 1 "memory_operand" ""))) 3173 (clobber (match_operand:HI 2 "memory_operand" ""))] 3174 "TARGET_80387 && reload_completed" 3175 [(set (match_dup 0) 3176 (float:XF (match_dup 1)))] 3177 "") 3178 3179(define_split 3180 [(set (match_operand:XF 0 "register_operand" "") 3181 (float:XF (match_operand:HI 1 "register_operand" ""))) 3182 (clobber (match_operand:HI 2 "memory_operand" ""))] 3183 "TARGET_80387 && reload_completed" 3184 [(set (match_dup 2) 3185 (match_dup 1)) 3186 (set (match_dup 0) 3187 (float:XF (match_dup 2)))] 3188 "") 3189 3190(define_insn "" 3191 [(set (match_operand:XF 0 "register_operand" "=f") 3192 (float:XF (match_operand:HI 1 "memory_operand" "m")))] 3193 "TARGET_80387" 3194 "* return AS1 (fild%z1,%1);" 3195 [(set_attr "type" "fpop")]) 3196 3197(define_expand "floatdixf2" 3198 [(parallel [(set (match_operand:XF 0 "register_operand" "") 3199 (float:XF (match_operand:DI 1 "nonimmediate_operand" ""))) 3200 (clobber (match_dup 2))])] 3201 "TARGET_80387" 3202 "operands[2] = assign_386_stack_local (DImode, 0);") 3203 3204(define_insn "" 3205 [(set (match_operand:XF 0 "register_operand" "=f,f") 3206 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,!r"))) 3207 (clobber (match_operand:DI 2 "memory_operand" "m,o"))] 3208 "TARGET_80387" 3209 "#") 3210 3211(define_split 3212 [(set (match_operand:XF 0 "register_operand" "") 3213 (float:XF (match_operand:DI 1 "memory_operand" ""))) 3214 (clobber (match_operand:DI 2 "memory_operand" ""))] 3215 "TARGET_80387 && reload_completed" 3216 [(set (match_dup 0) 3217 (float:XF (match_dup 1)))] 3218 "") 3219 3220(define_split 3221 [(set (match_operand:XF 0 "register_operand" "") 3222 (float:XF (match_operand:DI 1 "register_operand" ""))) 3223 (clobber (match_operand:DI 2 "memory_operand" ""))] 3224 "TARGET_80387 && reload_completed" 3225 [(set (match_dup 2) 3226 (match_dup 1)) 3227 (set (match_dup 0) 3228 (float:XF (match_dup 2)))] 3229 "") 3230 3231(define_insn "" 3232 [(set (match_operand:XF 0 "register_operand" "=f") 3233 (float:XF (match_operand:DI 1 "memory_operand" "m")))] 3234 "TARGET_80387" 3235 "* return AS1 (fild%z1,%1);" 3236 [(set_attr "type" "fpop")]) 3237 3238;;- add instructions 3239 3240(define_insn "*addsidi3_1" 3241 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,!&r,!r,o,!o") 3242 (plus:DI (match_operand:DI 1 "general_operand" "0,0,0,o,riF,riF,o") 3243 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,roi,roi,ri,ri")))) 3244 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,&r"))] 3245 "" 3246 "* 3247{ 3248 rtx low[3], high[3], xops[7]; 3249 3250 CC_STATUS_INIT; 3251 3252 split_di (operands, 2, low, high); 3253 high[2] = const0_rtx; 3254 low[2] = operands[2]; 3255 3256 if (!rtx_equal_p (operands[0], operands[1])) 3257 { 3258 xops[0] = high[0]; 3259 xops[1] = low[0]; 3260 xops[2] = high[1]; 3261 xops[3] = low[1]; 3262 3263 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 3264 { 3265 output_asm_insn (AS2 (mov%L1,%3,%1), xops); 3266 output_asm_insn (AS2 (mov%L0,%2,%0), xops); 3267 } 3268 else 3269 { 3270 xops[4] = high[2]; 3271 xops[5] = low[2]; 3272 xops[6] = operands[3]; 3273 output_asm_insn (AS2 (mov%L6,%3,%6), xops); 3274 output_asm_insn (AS2 (add%L6,%5,%6), xops); 3275 output_asm_insn (AS2 (mov%L1,%6,%1), xops); 3276 output_asm_insn (AS2 (mov%L6,%2,%6), xops); 3277 output_asm_insn (AS2 (adc%L6,%4,%6), xops); 3278 output_asm_insn (AS2 (mov%L0,%6,%0), xops); 3279 RET; 3280 } 3281 } 3282 3283 output_asm_insn (AS2 (add%L0,%2,%0), low); 3284 output_asm_insn (AS2 (adc%L0,%2,%0), high); 3285 cc_status.value1 = high[0]; 3286 cc_status.flags = CC_NO_OVERFLOW; 3287 RET; 3288}" 3289 [(set_attr "type" "binary")]) 3290 3291(define_insn "addsidi3_2" 3292 [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,&r,!&r,&r,o,o,!o") 3293 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,o,ri,ri,i,r")) 3294 (match_operand:DI 1 "general_operand" "0,0,0,iF,ro,roiF,riF,o,o"))) 3295 (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,X,&r,&r"))] 3296 "" 3297 "* 3298{ 3299 rtx low[3], high[3], xops[7]; 3300 3301 CC_STATUS_INIT; 3302 3303 split_di (operands, 2, low, high); 3304 high[2] = const0_rtx; 3305 low[2] = operands[2]; 3306 3307 if (!rtx_equal_p (operands[0], operands[1])) 3308 { 3309 xops[0] = high[0]; 3310 xops[1] = low[0]; 3311 xops[2] = high[1]; 3312 xops[3] = low[1]; 3313 3314 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 3315 { 3316 if (rtx_equal_p (low[0], operands[2])) 3317 { 3318 output_asm_insn (AS2 (mov%L0,%2,%0), high); 3319 output_asm_insn (AS2 (add%L0,%1,%0), low); 3320 output_asm_insn (AS2 (adc%L0,%1,%0), high); 3321 RET; 3322 } 3323 if (rtx_equal_p (high[0], operands[2])) 3324 { 3325 if (GET_CODE (operands[0]) != MEM) 3326 { 3327 output_asm_insn (AS2 (mov%L0,%2,%0), low); 3328 output_asm_insn (AS2 (mov%L0,%2,%0), high); 3329 output_asm_insn (AS2 (add%L0,%1,%0), low); 3330 output_asm_insn (AS2 (adc%L0,%1,%0), high); 3331 } 3332 else 3333 { 3334 /* It's too late to ask for a scratch now - but this 3335 will probably not happen too often. */ 3336 output_asm_insn (AS2 (add%L1,%2,%1), low); 3337 output_asm_insn (AS2 (mov%L0,%1,%0), low); 3338 output_asm_insn (AS2 (mov%L1,%2,%1), low); 3339 output_asm_insn (AS2 (mov%L0,%2,%0), high); 3340 output_asm_insn (AS2 (adc%L0,%1,%0), high); 3341 output_asm_insn (AS2 (sub%L1,%0,%1), low); 3342 output_asm_insn (AS1 (neg%L1,%1), low); 3343 } 3344 RET; 3345 } 3346 output_asm_insn (AS2 (mov%L1,%3,%1), xops); 3347 output_asm_insn (AS2 (mov%L0,%2,%0), xops); 3348 } 3349 else 3350 { 3351 xops[4] = high[2]; 3352 xops[5] = low[2]; 3353 xops[6] = operands[3]; 3354 output_asm_insn (AS2 (mov%L6,%3,%6), xops); 3355 output_asm_insn (AS2 (add%L6,%5,%6), xops); 3356 output_asm_insn (AS2 (mov%L1,%6,%1), xops); 3357 output_asm_insn (AS2 (mov%L6,%2,%6), xops); 3358 output_asm_insn (AS2 (adc%L6,%4,%6), xops); 3359 output_asm_insn (AS2 (mov%L0,%6,%0), xops); 3360 RET; 3361 } 3362 } 3363 3364 output_asm_insn (AS2 (add%L0,%2,%0), low); 3365 output_asm_insn (AS2 (adc%L0,%2,%0), high); 3366 cc_status.value1 = high[0]; 3367 cc_status.flags = CC_NO_OVERFLOW; 3368 RET; 3369}" 3370 [(set_attr "type" "binary")]) 3371 3372(define_insn "adddi3" 3373 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o") 3374 (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o") 3375 (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o"))) 3376 (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))] 3377 "" 3378 "* 3379{ 3380 rtx low[3], high[3], xops[7], temp; 3381 3382 CC_STATUS_INIT; 3383 3384 if (rtx_equal_p (operands[0], operands[2])) 3385 { 3386 temp = operands[1]; 3387 operands[1] = operands[2]; 3388 operands[2] = temp; 3389 } 3390 3391 split_di (operands, 3, low, high); 3392 if (!rtx_equal_p (operands[0], operands[1])) 3393 { 3394 xops[0] = high[0]; 3395 xops[1] = low[0]; 3396 xops[2] = high[1]; 3397 xops[3] = low[1]; 3398 3399 if (GET_CODE (operands[0]) != MEM) 3400 { 3401 output_asm_insn (AS2 (mov%L1,%3,%1), xops); 3402 output_asm_insn (AS2 (mov%L0,%2,%0), xops); 3403 } 3404 else 3405 { 3406 xops[4] = high[2]; 3407 xops[5] = low[2]; 3408 xops[6] = operands[3]; 3409 output_asm_insn (AS2 (mov%L6,%3,%6), xops); 3410 output_asm_insn (AS2 (add%L6,%5,%6), xops); 3411 output_asm_insn (AS2 (mov%L1,%6,%1), xops); 3412 output_asm_insn (AS2 (mov%L6,%2,%6), xops); 3413 output_asm_insn (AS2 (adc%L6,%4,%6), xops); 3414 output_asm_insn (AS2 (mov%L0,%6,%0), xops); 3415 RET; 3416 } 3417 } 3418 3419 cc_status.value1 = high[0]; 3420 cc_status.flags = CC_NO_OVERFLOW; 3421 3422 if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG) 3423 { 3424 xops[0] = high[0]; 3425 xops[1] = low[0]; 3426 xops[2] = high[2]; 3427 xops[3] = low[2]; 3428 xops[4] = operands[3]; 3429 3430 output_asm_insn (AS2 (mov%L4,%3,%4), xops); 3431 output_asm_insn (AS2 (add%L1,%4,%1), xops); 3432 output_asm_insn (AS2 (mov%L4,%2,%4), xops); 3433 output_asm_insn (AS2 (adc%L0,%4,%0), xops); 3434 } 3435 3436 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0) 3437 { 3438 output_asm_insn (AS2 (add%L0,%2,%0), low); 3439 output_asm_insn (AS2 (adc%L0,%2,%0), high); 3440 } 3441 3442 else 3443 output_asm_insn (AS2 (add%L0,%2,%0), high); 3444 3445 RET; 3446}" 3447 [(set_attr "type" "binary")]) 3448 3449;; On a 486, it is faster to do movl/addl than to do a single leal if 3450;; operands[1] and operands[2] are both registers. 3451 3452(define_expand "addsi3" 3453 [(set (match_operand:SI 0 "nonimmediate_operand" "") 3454 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "") 3455 (match_operand:SI 2 "general_operand" "")))] 3456 "" 3457 "IX86_EXPAND_BINARY_OPERATOR (PLUS, SImode, operands);") 3458 3459(define_insn "" 3460 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r") 3461 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r") 3462 (match_operand:SI 2 "general_operand" "rmi,ri,ri")))] 3463 "ix86_binary_operator_ok (PLUS, SImode, operands)" 3464 "* 3465{ 3466 if (REG_P (operands[0]) && REG_P (operands[1]) 3467 && (REG_P (operands[2]) || CONSTANT_P (operands[2])) 3468 && REGNO (operands[0]) != REGNO (operands[1])) 3469 { 3470 if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2])) 3471 return AS2 (add%L0,%1,%0); 3472 3473 if (operands[2] == stack_pointer_rtx) 3474 { 3475 rtx temp; 3476 3477 temp = operands[1]; 3478 operands[1] = operands[2]; 3479 operands[2] = temp; 3480 } 3481 3482 if (operands[2] != stack_pointer_rtx) 3483 { 3484 CC_STATUS_INIT; 3485 operands[1] = SET_SRC (PATTERN (insn)); 3486 return AS2 (lea%L0,%a1,%0); 3487 } 3488 } 3489 3490 if (!rtx_equal_p (operands[0], operands[1])) 3491 output_asm_insn (AS2 (mov%L0,%1,%0), operands); 3492 3493 if (operands[2] == const1_rtx) 3494 return AS1 (inc%L0,%0); 3495 3496 if (operands[2] == constm1_rtx) 3497 return AS1 (dec%L0,%0); 3498 3499 /* subl $-128,%ebx is smaller than addl $128,%ebx. */ 3500 if (GET_CODE (operands[2]) == CONST_INT 3501 && INTVAL (operands[2]) == 128) 3502 { 3503 /* This doesn't compute the carry bit in the same way 3504 * as add%L0, but we use inc and dec above and they 3505 * don't set the carry bit at all. If inc/dec don't need 3506 * a CC_STATUS_INIT, this doesn't either... */ 3507 operands[2] = GEN_INT (-128); 3508 return AS2 (sub%L0,%2,%0); 3509 } 3510 3511 return AS2 (add%L0,%2,%0); 3512}" 3513 [(set_attr "type" "binary")]) 3514 3515;; addsi3 is faster, so put this after. 3516 3517(define_insn "movsi_lea" 3518 [(set (match_operand:SI 0 "register_operand" "=r") 3519 (match_operand:QI 1 "address_operand" "p"))] 3520 "" 3521 "* 3522{ 3523 /* Adding a constant to a register is faster with an add. */ 3524 /* ??? can this ever happen? */ 3525 if (GET_CODE (operands[1]) == PLUS 3526 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT 3527 && rtx_equal_p (operands[0], XEXP (operands[1], 0))) 3528 { 3529 operands[1] = XEXP (operands[1], 1); 3530 3531 if (operands[1] == const1_rtx) 3532 return AS1 (inc%L0,%0); 3533 3534 if (operands[1] == constm1_rtx) 3535 return AS1 (dec%L0,%0); 3536 3537 return AS2 (add%L0,%1,%0); 3538 } 3539 3540 CC_STATUS_INIT; 3541 return AS2 (lea%L0,%a1,%0); 3542}" 3543 [(set_attr "type" "lea")]) 3544 3545;; ??? `lea' here, for three operand add? If leaw is used, only %bx, 3546;; %si and %di can appear in SET_SRC, and output_asm_insn might not be 3547;; able to handle the operand. But leal always works? 3548 3549(define_expand "addhi3" 3550 [(set (match_operand:HI 0 "general_operand" "") 3551 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "") 3552 (match_operand:HI 2 "general_operand" "")))] 3553 "" 3554 "IX86_EXPAND_BINARY_OPERATOR (PLUS, HImode, operands);") 3555 3556(define_insn "" 3557 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,?r") 3558 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r") 3559 (match_operand:HI 2 "general_operand" "ri,rm,ri")))] 3560 "ix86_binary_operator_ok (PLUS, HImode, operands)" 3561 "* 3562{ 3563 if (REG_P (operands[0]) && REG_P (operands[1]) 3564 && (REG_P (operands[2]) || CONSTANT_P (operands[2])) 3565 && REGNO (operands[0]) != REGNO (operands[1])) 3566 { 3567 if (operands[2] == stack_pointer_rtx) 3568 abort (); 3569 3570 CC_STATUS_INIT; 3571 operands[1] 3572 = gen_rtx_PLUS (SImode, 3573 gen_rtx_REG (SImode, REGNO (operands[1])), 3574 (! REG_P (operands[2]) 3575 ? operands[2] 3576 : gen_rtx_REG (SImode, REGNO (operands[2])))); 3577 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0])); 3578 return AS2 (lea%L0,%a1,%0); 3579 } 3580 3581 /* ??? what about offsettable memory references? */ 3582 if (!TARGET_PENTIUMPRO /* partial stalls are just too painful to risk. */ 3583 && QI_REG_P (operands[0]) 3584 && GET_CODE (operands[2]) == CONST_INT 3585 && (INTVAL (operands[2]) & 0xff) == 0 3586 && i386_cc_probably_useless_p (insn)) 3587 { 3588 int byteval = (INTVAL (operands[2]) >> 8) & 0xff; 3589 CC_STATUS_INIT; 3590 3591 if (byteval == 1) 3592 return AS1 (inc%B0,%h0); 3593 else if (byteval == 255) 3594 return AS1 (dec%B0,%h0); 3595 3596 operands[2] = GEN_INT (byteval); 3597 return AS2 (add%B0,%2,%h0); 3598 } 3599 3600 /* Use a 32-bit operation when possible, to avoid the prefix penalty. */ 3601 if (REG_P (operands[0]) 3602 && i386_aligned_p (operands[2]) 3603 && i386_cc_probably_useless_p (insn)) 3604 { 3605 CC_STATUS_INIT; 3606 3607 if (GET_CODE (operands[2]) == CONST_INT) 3608 { 3609 HOST_WIDE_INT intval = 0xffff & INTVAL (operands[2]); 3610 3611 if (intval == 1) 3612 return AS1 (inc%L0,%k0); 3613 3614 if (intval == 0xffff) 3615 return AS1 (dec%L0,%k0); 3616 3617 operands[2] = i386_sext16_if_const (operands[2]); 3618 } 3619 return AS2 (add%L0,%k2,%k0); 3620 } 3621 3622 if (operands[2] == const1_rtx) 3623 return AS1 (inc%W0,%0); 3624 3625 if (operands[2] == constm1_rtx 3626 || (GET_CODE (operands[2]) == CONST_INT 3627 && INTVAL (operands[2]) == 65535)) 3628 return AS1 (dec%W0,%0); 3629 3630 return AS2 (add%W0,%2,%0); 3631}" 3632 [(set_attr "type" "binary")]) 3633 3634(define_expand "addqi3" 3635 [(set (match_operand:QI 0 "general_operand" "") 3636 (plus:QI (match_operand:QI 1 "general_operand" "") 3637 (match_operand:QI 2 "general_operand" "")))] 3638 "" 3639 "IX86_EXPAND_BINARY_OPERATOR (PLUS, QImode, operands);") 3640 3641(define_insn "" 3642 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,?q") 3643 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q") 3644 (match_operand:QI 2 "general_operand" "qn,qmn,qn")))] 3645 "ix86_binary_operator_ok (PLUS, QImode, operands)" 3646 "* 3647{ 3648 if (REG_P (operands[0]) && REG_P (operands[1]) 3649 && (REG_P (operands[2]) || CONSTANT_P (operands[2])) 3650 && (REGNO (operands[0]) != REGNO (operands[1]) 3651 || NON_QI_REG_P (operands[1]) 3652 || (REG_P (operands[2]) && NON_QI_REG_P (operands[2])))) 3653 { 3654 if (operands[2] == stack_pointer_rtx) 3655 abort (); 3656 3657 CC_STATUS_INIT; 3658 operands[1] 3659 = gen_rtx_PLUS (SImode, 3660 gen_rtx_REG (SImode, REGNO (operands[1])), 3661 (! REG_P (operands[2]) 3662 ? operands[2] 3663 : gen_rtx_REG (SImode, REGNO (operands[2])))); 3664 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0])); 3665 return AS2 (lea%L0,%a1,%0); 3666 } 3667 if (operands[2] == const1_rtx) 3668 return AS1 (inc%B0,%0); 3669 3670 if (operands[2] == constm1_rtx 3671 || (GET_CODE (operands[2]) == CONST_INT 3672 && INTVAL (operands[2]) == 255)) 3673 return AS1 (dec%B0,%0); 3674 3675 return AS2 (add%B0,%2,%0); 3676}" 3677 [(set_attr "type" "binary")]) 3678 3679;Lennart Augustsson <augustss@cs.chalmers.se> 3680;says this pattern just makes slower code: 3681; pushl %ebp 3682; addl $-80,(%esp) 3683;instead of 3684; leal -80(%ebp),%eax 3685; pushl %eax 3686; 3687;(define_insn "" 3688; [(set (match_operand:SI 0 "push_operand" "=<") 3689; (plus:SI (match_operand:SI 1 "register_operand" "%r") 3690; (match_operand:SI 2 "nonmemory_operand" "ri")))] 3691; "" 3692; "* 3693;{ 3694; rtx xops[4]; 3695; xops[0] = operands[0]; 3696; xops[1] = operands[1]; 3697; xops[2] = operands[2]; 3698; xops[3] = gen_rtx_MEM (SImode, stack_pointer_rtx); 3699; output_asm_insn (\"push%z1 %1\", xops); 3700; output_asm_insn (AS2 (add%z3,%2,%3), xops); 3701; RET; 3702;}") 3703 3704;; The patterns that match these are at the end of this file. 3705 3706(define_expand "addxf3" 3707 [(set (match_operand:XF 0 "register_operand" "") 3708 (plus:XF (match_operand:XF 1 "register_operand" "") 3709 (match_operand:XF 2 "register_operand" "")))] 3710 "TARGET_80387" 3711 "") 3712 3713(define_expand "adddf3" 3714 [(set (match_operand:DF 0 "register_operand" "") 3715 (plus:DF (match_operand:DF 1 "nonimmediate_operand" "") 3716 (match_operand:DF 2 "nonimmediate_operand" "")))] 3717 "TARGET_80387" 3718 "") 3719 3720(define_expand "addsf3" 3721 [(set (match_operand:SF 0 "register_operand" "") 3722 (plus:SF (match_operand:SF 1 "nonimmediate_operand" "") 3723 (match_operand:SF 2 "nonimmediate_operand" "")))] 3724 "TARGET_80387" 3725 "") 3726 3727;;- subtract instructions 3728 3729(define_insn "subsidi3" 3730 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,&r,!&r,o,o,!o") 3731 (minus:DI (match_operand:DI 1 "general_operand" "0iF,0,roiF,roiF,riF,o,o") 3732 (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,ri,i,r")))) 3733 (clobber (match_scratch:SI 3 "=X,X,X,X,X,&r,&r"))] 3734 "" 3735 "* 3736{ 3737 rtx low[3], high[3], xops[7]; 3738 3739 CC_STATUS_INIT; 3740 3741 split_di (operands, 2, low, high); 3742 high[2] = const0_rtx; 3743 low[2] = operands[2]; 3744 3745 if (!rtx_equal_p (operands[0], operands[1])) 3746 { 3747 xops[0] = high[0]; 3748 xops[1] = low[0]; 3749 xops[2] = high[1]; 3750 xops[3] = low[1]; 3751 3752 if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) 3753 { 3754 output_asm_insn (AS2 (mov%L1,%3,%1), xops); 3755 output_asm_insn (AS2 (mov%L0,%2,%0), xops); 3756 } 3757 else 3758 { 3759 xops[4] = high[2]; 3760 xops[5] = low[2]; 3761 xops[6] = operands[3]; 3762 output_asm_insn (AS2 (mov%L6,%3,%6), xops); 3763 output_asm_insn (AS2 (sub%L6,%5,%6), xops); 3764 output_asm_insn (AS2 (mov%L1,%6,%1), xops); 3765 output_asm_insn (AS2 (mov%L6,%2,%6), xops); 3766 output_asm_insn (AS2 (sbb%L6,%4,%6), xops); 3767 output_asm_insn (AS2 (mov%L0,%6,%0), xops); 3768 RET; 3769 } 3770 } 3771 3772 output_asm_insn (AS2 (sub%L0,%2,%0), low); 3773 output_asm_insn (AS2 (sbb%L0,%2,%0), high); 3774 cc_status.value1 = high[0]; 3775 cc_status.flags = CC_NO_OVERFLOW; 3776 3777 RET; 3778}" 3779 [(set_attr "type" "binary")]) 3780 3781(define_insn "subdi3" 3782 [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o") 3783 (minus:DI (match_operand:DI 1 "general_operand" "0,0,0iF,or,roiF,roiF") 3784 (match_operand:DI 2 "general_operand" "or,riF,or,iF,roiF,roiF"))) 3785 (clobber (match_scratch:SI 3 "=X,X,&r,&r,X,&r"))] 3786 "" 3787 "* 3788{ 3789 rtx low[3], high[3], xops[7]; 3790 3791 CC_STATUS_INIT; 3792 3793 split_di (operands, 3, low, high); 3794 3795 if (!rtx_equal_p (operands[0], operands[1])) 3796 { 3797 xops[0] = high[0]; 3798 xops[1] = low[0]; 3799 xops[2] = high[1]; 3800 xops[3] = low[1]; 3801 3802 if (GET_CODE (operands[0]) != MEM) 3803 { 3804 output_asm_insn (AS2 (mov%L1,%3,%1), xops); 3805 output_asm_insn (AS2 (mov%L0,%2,%0), xops); 3806 } 3807 else 3808 { 3809 xops[4] = high[2]; 3810 xops[5] = low[2]; 3811 xops[6] = operands[3]; 3812 output_asm_insn (AS2 (mov%L6,%3,%6), xops); 3813 output_asm_insn (AS2 (sub%L6,%5,%6), xops); 3814 output_asm_insn (AS2 (mov%L1,%6,%1), xops); 3815 output_asm_insn (AS2 (mov%L6,%2,%6), xops); 3816 output_asm_insn (AS2 (sbb%L6,%4,%6), xops); 3817 output_asm_insn (AS2 (mov%L0,%6,%0), xops); 3818 RET; 3819 } 3820 } 3821 3822 cc_status.value1 = high[0]; 3823 cc_status.flags = CC_NO_OVERFLOW; 3824 3825 if (GET_CODE (operands[3]) == REG) 3826 { 3827 xops[0] = high[0]; 3828 xops[1] = low[0]; 3829 xops[2] = high[2]; 3830 xops[3] = low[2]; 3831 xops[4] = operands[3]; 3832 3833 output_asm_insn (AS2 (mov%L4,%3,%4), xops); 3834 output_asm_insn (AS2 (sub%L1,%4,%1), xops); 3835 output_asm_insn (AS2 (mov%L4,%2,%4), xops); 3836 output_asm_insn (AS2 (sbb%L0,%4,%0), xops); 3837 } 3838 3839 else if (GET_CODE (low[2]) != CONST_INT || INTVAL (low[2]) != 0) 3840 { 3841 output_asm_insn (AS2 (sub%L0,%2,%0), low); 3842 output_asm_insn (AS2 (sbb%L0,%2,%0), high); 3843 } 3844 3845 else 3846 output_asm_insn (AS2 (sub%L0,%2,%0), high); 3847 3848 3849 RET; 3850}" 3851 [(set_attr "type" "binary")]) 3852 3853(define_expand "subsi3" 3854 [(set (match_operand:SI 0 "nonimmediate_operand" "") 3855 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "") 3856 (match_operand:SI 2 "general_operand" "")))] 3857 "" 3858 "IX86_EXPAND_BINARY_OPERATOR (MINUS, SImode, operands);") 3859 3860(define_insn "" 3861 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 3862 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 3863 (match_operand:SI 2 "general_operand" "ri,rm")))] 3864 "ix86_binary_operator_ok (MINUS, SImode, operands)" 3865 "* return AS2 (sub%L0,%2,%0);" 3866 [(set_attr "type" "binary")]) 3867 3868(define_expand "subhi3" 3869 [(set (match_operand:HI 0 "general_operand" "") 3870 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "") 3871 (match_operand:HI 2 "general_operand" "")))] 3872 "" 3873 "IX86_EXPAND_BINARY_OPERATOR (MINUS, HImode, operands);") 3874 3875(define_insn "" 3876 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 3877 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") 3878 (match_operand:HI 2 "general_operand" "ri,rm")))] 3879 "ix86_binary_operator_ok (MINUS, HImode, operands)" 3880 "* 3881{ 3882 if (REG_P (operands[0]) 3883 && i386_aligned_p (operands[2]) 3884 && i386_cc_probably_useless_p (insn)) 3885 { 3886 CC_STATUS_INIT; 3887 operands[2] = i386_sext16_if_const (operands[2]); 3888 return AS2 (sub%L0,%k2,%k0); 3889 } 3890 return AS2 (sub%W0,%2,%0); 3891}" 3892 [(set_attr "type" "binary")]) 3893 3894(define_expand "subqi3" 3895 [(set (match_operand:QI 0 "general_operand" "") 3896 (minus:QI (match_operand:QI 1 "general_operand" "") 3897 (match_operand:QI 2 "general_operand" "")))] 3898 "" 3899 "IX86_EXPAND_BINARY_OPERATOR (MINUS, QImode, operands);") 3900 3901(define_insn "" 3902 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 3903 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") 3904 (match_operand:QI 2 "general_operand" "qn,qmn")))] 3905 "ix86_binary_operator_ok (MINUS, QImode, operands)" 3906 "* return AS2 (sub%B0,%2,%0);" 3907 [(set_attr "type" "binary")]) 3908 3909;; The patterns that match these are at the end of this file. 3910 3911(define_expand "subxf3" 3912 [(set (match_operand:XF 0 "register_operand" "") 3913 (minus:XF (match_operand:XF 1 "register_operand" "") 3914 (match_operand:XF 2 "register_operand" "")))] 3915 "TARGET_80387" 3916 "") 3917 3918(define_expand "subdf3" 3919 [(set (match_operand:DF 0 "register_operand" "") 3920 (minus:DF (match_operand:DF 1 "nonimmediate_operand" "") 3921 (match_operand:DF 2 "nonimmediate_operand" "")))] 3922 "TARGET_80387" 3923 "") 3924 3925(define_expand "subsf3" 3926 [(set (match_operand:SF 0 "register_operand" "") 3927 (minus:SF (match_operand:SF 1 "nonimmediate_operand" "") 3928 (match_operand:SF 2 "nonimmediate_operand" "")))] 3929 "TARGET_80387" 3930 "") 3931 3932;;- multiply instructions 3933 3934;(define_insn "mulqi3" 3935; [(set (match_operand:QI 0 "register_operand" "=a") 3936; (mult:QI (match_operand:QI 1 "register_operand" "%0") 3937; (match_operand:QI 2 "nonimmediate_operand" "qm")))] 3938; "" 3939; "imul%B0 %2,%0") 3940 3941(define_insn "mulhi3" 3942 [(set (match_operand:HI 0 "register_operand" "=r,r") 3943 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%0,rm") 3944 (match_operand:HI 2 "general_operand" "g,i")))] 3945 "" 3946 "* 3947{ 3948 if (GET_CODE (operands[1]) == REG 3949 && REGNO (operands[1]) == REGNO (operands[0]) 3950 && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG)) 3951 /* Assembler has weird restrictions. */ 3952 return AS2 (imul%W0,%2,%0); 3953 return AS3 (imul%W0,%2,%1,%0); 3954}" 3955 [(set_attr "type" "imul")]) 3956 3957(define_insn "mulsi3" 3958 [(set (match_operand:SI 0 "register_operand" "=r,r") 3959 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm") 3960 (match_operand:SI 2 "general_operand" "g,i")))] 3961 "" 3962 "* 3963{ 3964 if (GET_CODE (operands[1]) == REG 3965 && REGNO (operands[1]) == REGNO (operands[0]) 3966 && (GET_CODE (operands[2]) == MEM || GET_CODE (operands[2]) == REG)) 3967 /* Assembler has weird restrictions. */ 3968 return AS2 (imul%L0,%2,%0); 3969 return AS3 (imul%L0,%2,%1,%0); 3970}" 3971 [(set_attr "type" "imul")]) 3972 3973(define_insn "umulqihi3" 3974 [(set (match_operand:HI 0 "register_operand" "=a") 3975 (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0")) 3976 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))] 3977 "" 3978 "mul%B0 %2" 3979 [(set_attr "type" "imul")]) 3980 3981(define_insn "mulqihi3" 3982 [(set (match_operand:HI 0 "register_operand" "=a") 3983 (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0")) 3984 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))] 3985 "" 3986 "imul%B0 %2" 3987 [(set_attr "type" "imul")]) 3988 3989(define_insn "umulsidi3" 3990 [(set (match_operand:DI 0 "register_operand" "=A") 3991 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 3992 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))] 3993 "TARGET_WIDE_MULTIPLY" 3994 "mul%L0 %2" 3995 [(set_attr "type" "imul")]) 3996 3997(define_insn "mulsidi3" 3998 [(set (match_operand:DI 0 "register_operand" "=A") 3999 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%0")) 4000 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))] 4001 "TARGET_WIDE_MULTIPLY" 4002 "imul%L0 %2" 4003 [(set_attr "type" "imul")]) 4004 4005(define_insn "umulsi3_highpart" 4006 [(set (match_operand:SI 0 "register_operand" "=d") 4007 (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%a")) 4008 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))) 4009 (const_int 32)))) 4010 (clobber (match_scratch:SI 3 "=a"))] 4011 "TARGET_WIDE_MULTIPLY" 4012 "mul%L0 %2" 4013 [(set_attr "type" "imul")]) 4014 4015(define_insn "smulsi3_highpart" 4016 [(set (match_operand:SI 0 "register_operand" "=d") 4017 (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%a")) 4018 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))) 4019 (const_int 32)))) 4020 (clobber (match_scratch:SI 3 "=a"))] 4021 "TARGET_WIDE_MULTIPLY" 4022 "imul%L0 %2" 4023 [(set_attr "type" "imul")]) 4024 4025;; The patterns that match these are at the end of this file. 4026 4027(define_expand "mulxf3" 4028 [(set (match_operand:XF 0 "register_operand" "") 4029 (mult:XF (match_operand:XF 1 "register_operand" "") 4030 (match_operand:XF 2 "register_operand" "")))] 4031 "TARGET_80387" 4032 "") 4033 4034(define_expand "muldf3" 4035 [(set (match_operand:DF 0 "register_operand" "") 4036 (mult:DF (match_operand:DF 1 "register_operand" "") 4037 (match_operand:DF 2 "nonimmediate_operand" "")))] 4038 "TARGET_80387" 4039 "") 4040 4041(define_expand "mulsf3" 4042 [(set (match_operand:SF 0 "register_operand" "") 4043 (mult:SF (match_operand:SF 1 "register_operand" "") 4044 (match_operand:SF 2 "nonimmediate_operand" "")))] 4045 "TARGET_80387" 4046 "") 4047 4048;;- divide instructions 4049 4050(define_insn "divqi3" 4051 [(set (match_operand:QI 0 "register_operand" "=a") 4052 (div:QI (match_operand:HI 1 "register_operand" "0") 4053 (match_operand:QI 2 "nonimmediate_operand" "qm")))] 4054 "" 4055 "idiv%B0 %2") 4056 4057(define_insn "udivqi3" 4058 [(set (match_operand:QI 0 "register_operand" "=a") 4059 (udiv:QI (match_operand:HI 1 "register_operand" "0") 4060 (match_operand:QI 2 "nonimmediate_operand" "qm")))] 4061 "" 4062 "div%B0 %2" 4063 [(set_attr "type" "idiv")]) 4064 4065;; The patterns that match these are at the end of this file. 4066 4067(define_expand "divxf3" 4068 [(set (match_operand:XF 0 "register_operand" "") 4069 (div:XF (match_operand:XF 1 "register_operand" "") 4070 (match_operand:XF 2 "register_operand" "")))] 4071 "TARGET_80387" 4072 "") 4073 4074(define_expand "divdf3" 4075 [(set (match_operand:DF 0 "register_operand" "") 4076 (div:DF (match_operand:DF 1 "register_operand" "") 4077 (match_operand:DF 2 "nonimmediate_operand" "")))] 4078 "TARGET_80387" 4079 "") 4080 4081(define_expand "divsf3" 4082 [(set (match_operand:SF 0 "register_operand" "") 4083 (div:SF (match_operand:SF 1 "register_operand" "") 4084 (match_operand:SF 2 "nonimmediate_operand" "")))] 4085 "TARGET_80387" 4086 "") 4087 4088;; Remainder instructions. 4089 4090(define_insn "divmodsi4" 4091 [(set (match_operand:SI 0 "register_operand" "=a") 4092 (div:SI (match_operand:SI 1 "register_operand" "0") 4093 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 4094 (set (match_operand:SI 3 "register_operand" "=&d") 4095 (mod:SI (match_dup 1) (match_dup 2)))] 4096 "" 4097 "* 4098{ 4099#ifdef INTEL_SYNTAX 4100 output_asm_insn (\"cdq\", operands); 4101#else 4102 output_asm_insn (\"cltd\", operands); 4103#endif 4104 return AS1 (idiv%L0,%2); 4105}" 4106 [(set_attr "type" "idiv")]) 4107 4108(define_insn "divmodhi4" 4109 [(set (match_operand:HI 0 "register_operand" "=a") 4110 (div:HI (match_operand:HI 1 "register_operand" "0") 4111 (match_operand:HI 2 "nonimmediate_operand" "rm"))) 4112 (set (match_operand:HI 3 "register_operand" "=&d") 4113 (mod:HI (match_dup 1) (match_dup 2)))] 4114 "" 4115 "cwtd\;idiv%W0 %2" 4116 [(set_attr "type" "idiv")]) 4117 4118;; ??? Can we make gcc zero extend operand[0]? 4119(define_insn "udivmodsi4" 4120 [(set (match_operand:SI 0 "register_operand" "=a") 4121 (udiv:SI (match_operand:SI 1 "register_operand" "0") 4122 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 4123 (set (match_operand:SI 3 "register_operand" "=&d") 4124 (umod:SI (match_dup 1) (match_dup 2)))] 4125 "" 4126 "* 4127{ 4128 output_asm_insn (AS2 (xor%L3,%3,%3), operands); 4129 return AS1 (div%L0,%2); 4130}" 4131 [(set_attr "type" "idiv")]) 4132 4133;; ??? Can we make gcc zero extend operand[0]? 4134(define_insn "udivmodhi4" 4135 [(set (match_operand:HI 0 "register_operand" "=a") 4136 (udiv:HI (match_operand:HI 1 "register_operand" "0") 4137 (match_operand:HI 2 "nonimmediate_operand" "rm"))) 4138 (set (match_operand:HI 3 "register_operand" "=&d") 4139 (umod:HI (match_dup 1) (match_dup 2)))] 4140 "" 4141 "* 4142{ 4143 output_asm_insn (AS2 (xor%W0,%3,%3), operands); 4144 return AS1 (div%W0,%2); 4145}" 4146 [(set_attr "type" "idiv")]) 4147 4148/* 4149;;this should be a valid double division which we may want to add 4150 4151(define_insn "" 4152 [(set (match_operand:SI 0 "register_operand" "=a") 4153 (udiv:DI (match_operand:DI 1 "register_operand" "a") 4154 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 4155 (set (match_operand:SI 3 "register_operand" "=d") 4156 (umod:SI (match_dup 1) (match_dup 2)))] 4157 "" 4158 "div%L0 %2,%0" 4159 [(set_attr "type" "idiv")]) 4160*/ 4161 4162;;- and instructions 4163 4164;; On i386, 4165;; movzbl %bl,%ebx 4166;; is faster than 4167;; andl $255,%ebx 4168;; 4169;; but if the reg is %eax, then the "andl" is faster. 4170;; 4171;; On i486, the "andl" is always faster than the "movzbl". 4172;; 4173;; On both i386 and i486, a three operand AND is as fast with movzbl or 4174;; movzwl as with andl, if operands[0] != operands[1]. 4175 4176;; The `r' in `rm' for operand 3 looks redundant, but it causes 4177;; optional reloads to be generated if op 3 is a pseudo in a stack slot. 4178 4179(define_insn "andsi3" 4180 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 4181 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 4182 (match_operand:SI 2 "general_operand" "ri,rm")))] 4183 "" 4184 "* 4185{ 4186 HOST_WIDE_INT intval; 4187 if (!rtx_equal_p (operands[0], operands[1]) 4188 && rtx_equal_p (operands[0], operands[2])) 4189 { 4190 rtx tmp; 4191 tmp = operands[1]; 4192 operands[1] = operands[2]; 4193 operands[2] = tmp; 4194 } 4195 switch (GET_CODE (operands[2])) 4196 { 4197 case CONST_INT: 4198 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) 4199 break; 4200 intval = INTVAL (operands[2]); 4201 /* zero-extend 16->32? */ 4202 if (intval == 0xffff && REG_P (operands[0]) 4203 && (! REG_P (operands[1]) 4204 || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0) 4205 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1]))) 4206 { 4207 /* ??? tege: Should forget CC_STATUS only if we clobber a 4208 remembered operand. Fix that later. */ 4209 CC_STATUS_INIT; 4210#ifdef INTEL_SYNTAX 4211 return AS2 (movzx,%w1,%0); 4212#else 4213 return AS2 (movz%W0%L0,%w1,%0); 4214#endif 4215 } 4216 4217 /* zero extend 8->32? */ 4218 if (intval == 0xff && REG_P (operands[0]) 4219 && !(REG_P (operands[1]) && NON_QI_REG_P (operands[1])) 4220 && (! REG_P (operands[1]) 4221 || REGNO (operands[0]) != 0 || REGNO (operands[1]) != 0) 4222 && (!TARGET_ZERO_EXTEND_WITH_AND || ! rtx_equal_p (operands[0], operands[1]))) 4223 { 4224 /* ??? tege: Should forget CC_STATUS only if we clobber a 4225 remembered operand. Fix that later. */ 4226 CC_STATUS_INIT; 4227#ifdef INTEL_SYNTAX 4228 return AS2 (movzx,%b1,%0); 4229#else 4230 return AS2 (movz%B0%L0,%b1,%0); 4231#endif 4232 } 4233 4234 /* Check partial bytes.. non-QI-regs are not available */ 4235 if (REG_P (operands[0]) && ! QI_REG_P (operands[0])) 4236 break; 4237 4238 /* only low byte has zero bits? */ 4239 if (~(intval | 0xff) == 0) 4240 { 4241 intval &= 0xff; 4242 if (REG_P (operands[0])) 4243 { 4244 if (intval == 0) 4245 { 4246 CC_STATUS_INIT; 4247 return AS2 (xor%B0,%b0,%b0); 4248 } 4249 4250 /* we're better off with the 32-bit version if reg != EAX */ 4251 /* the value is sign-extended in 8 bits */ 4252 if (REGNO (operands[0]) != 0 && (intval & 0x80)) 4253 break; 4254 } 4255 4256 CC_STATUS_INIT; 4257 4258 operands[2] = GEN_INT (intval); 4259 4260 if (intval == 0) 4261 return AS2 (mov%B0,%2,%b0); 4262 4263 return AS2 (and%B0,%2,%b0); 4264 } 4265 4266 /* only second byte has zero? */ 4267 if (~(intval | 0xff00) == 0) 4268 { 4269 CC_STATUS_INIT; 4270 4271 intval = (intval >> 8) & 0xff; 4272 operands[2] = GEN_INT (intval); 4273 if (intval == 0) 4274 { 4275 if (REG_P (operands[0])) 4276 return AS2 (xor%B0,%h0,%h0); 4277 operands[0] = adj_offsettable_operand (operands[0], 1); 4278 return AS2 (mov%B0,%2,%b0); 4279 } 4280 4281 if (REG_P (operands[0])) 4282 return AS2 (and%B0,%2,%h0); 4283 4284 operands[0] = adj_offsettable_operand (operands[0], 1); 4285 return AS2 (and%B0,%2,%b0); 4286 } 4287 4288 if (REG_P (operands[0])) 4289 break; 4290 4291 /* third byte has zero bits? */ 4292 if (~(intval | 0xff0000) == 0) 4293 { 4294 intval = (intval >> 16) & 0xff; 4295 operands[0] = adj_offsettable_operand (operands[0], 2); 4296byte_and_operation: 4297 CC_STATUS_INIT; 4298 operands[2] = GEN_INT (intval); 4299 if (intval == 0) 4300 return AS2 (mov%B0,%2,%b0); 4301 return AS2 (and%B0,%2,%b0); 4302 } 4303 4304 /* fourth byte has zero bits? */ 4305 if (~(intval | 0xff000000) == 0) 4306 { 4307 intval = (intval >> 24) & 0xff; 4308 operands[0] = adj_offsettable_operand (operands[0], 3); 4309 goto byte_and_operation; 4310 } 4311 4312 /* Low word is zero? */ 4313 if (intval == 0xffff0000) 4314 { 4315word_zero_and_operation: 4316 CC_STATUS_INIT; 4317 operands[2] = const0_rtx; 4318 return AS2 (mov%W0,%2,%w0); 4319 } 4320 4321 /* High word is zero? */ 4322 if (intval == 0x0000ffff) 4323 { 4324 operands[0] = adj_offsettable_operand (operands[0], 2); 4325 goto word_zero_and_operation; 4326 } 4327 4328 default: 4329 break; 4330 } 4331 4332 return AS2 (and%L0,%2,%0); 4333}" 4334 [(set_attr "type" "binary")]) 4335 4336(define_insn "andhi3" 4337 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 4338 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 4339 (match_operand:HI 2 "general_operand" "ri,rm")))] 4340 "" 4341 "* 4342{ 4343 if (GET_CODE (operands[2]) == CONST_INT 4344 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) 4345 { 4346 /* Can we ignore the upper byte? */ 4347 if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) 4348 && (INTVAL (operands[2]) & 0xff00) == 0xff00) 4349 { 4350 CC_STATUS_INIT; 4351 4352 if ((INTVAL (operands[2]) & 0xff) == 0) 4353 { 4354 operands[2] = const0_rtx; 4355 return AS2 (mov%B0,%2,%b0); 4356 } 4357 4358 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); 4359 return AS2 (and%B0,%2,%b0); 4360 } 4361 4362 /* Can we ignore the lower byte? */ 4363 /* ??? what about offsettable memory references? */ 4364 if (QI_REG_P (operands[0]) && (INTVAL (operands[2]) & 0xff) == 0xff) 4365 { 4366 CC_STATUS_INIT; 4367 4368 if ((INTVAL (operands[2]) & 0xff00) == 0) 4369 { 4370 operands[2] = const0_rtx; 4371 return AS2 (mov%B0,%2,%h0); 4372 } 4373 4374 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff); 4375 return AS2 (and%B0,%2,%h0); 4376 } 4377 4378 /* use 32-bit ops on registers when there are no sign issues.. */ 4379 if (REG_P (operands[0])) 4380 { 4381 if (!(INTVAL (operands[2]) & ~0x7fff)) 4382 return AS2 (and%L0,%2,%k0); 4383 } 4384 } 4385 4386 if (REG_P (operands[0]) 4387 && i386_aligned_p (operands[2])) 4388 { 4389 CC_STATUS_INIT; 4390 /* If op[2] is constant, we should zero-extend it and */ 4391 /* make a note that op[0] has been zero-extended, so */ 4392 /* that we could use 32-bit ops on it forthwith, but */ 4393 /* there is no such reg-note available. Instead we do */ 4394 /* a sign extension as that can result in shorter asm */ 4395 operands[2] = i386_sext16_if_const (operands[2]); 4396 return AS2 (and%L0,%k2,%k0); 4397 } 4398 4399 /* Use a 32-bit word with the upper bits set, invalidate CC */ 4400 if (GET_CODE (operands[2]) == CONST_INT 4401 && i386_aligned_p (operands[0])) 4402 { 4403 HOST_WIDE_INT val = INTVAL (operands[2]); 4404 CC_STATUS_INIT; 4405 val |= ~0xffff; 4406 if (val != INTVAL (operands[2])) 4407 operands[2] = GEN_INT (val); 4408 return AS2 (and%L0,%k2,%k0); 4409 } 4410 4411 return AS2 (and%W0,%2,%0); 4412}" 4413 [(set_attr "type" "binary")]) 4414 4415(define_insn "andqi3" 4416 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 4417 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 4418 (match_operand:QI 2 "general_operand" "qn,qmn")))] 4419 "" 4420 "* return AS2 (and%B0,%2,%0);" 4421 [(set_attr "type" "binary")]) 4422 4423/* I am nervous about these two.. add them later.. 4424;I presume this means that we have something in say op0= eax which is small 4425;and we want to and it with memory so we can do this by just an 4426;andb m,%al and have success. 4427(define_insn "" 4428 [(set (match_operand:SI 0 "general_operand" "=r") 4429 (and:SI (zero_extend:SI 4430 (match_operand:HI 1 "nonimmediate_operand" "rm")) 4431 (match_operand:SI 2 "general_operand" "0")))] 4432 "GET_CODE (operands[2]) == CONST_INT 4433 && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (HImode))" 4434 "and%W0 %1,%0") 4435 4436(define_insn "" 4437 [(set (match_operand:SI 0 "register_operand" "=q") 4438 (and:SI 4439 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")) 4440 (match_operand:SI 2 "register_operand" "0")))] 4441 "GET_CODE (operands[2]) == CONST_INT 4442 && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))" 4443 "and%L0 %1,%0") 4444 4445*/ 4446 4447;;- Bit set (inclusive or) instructions 4448 4449;; This optimizes known byte-wide operations to memory, and in some cases 4450;; to QI registers.. Note that we don't want to use the QI registers too 4451;; aggressively, because often the 32-bit register instruction is the same 4452;; size, and likely to be faster on PentiumPro. 4453(define_insn "iorsi3" 4454 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 4455 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 4456 (match_operand:SI 2 "general_operand" "ri,rm")))] 4457 "" 4458 "* 4459{ 4460 HOST_WIDE_INT intval; 4461 switch (GET_CODE (operands[2])) 4462 { 4463 case CONST_INT: 4464 4465 if (REG_P (operands[0]) && ! QI_REG_P (operands[0])) 4466 break; 4467 4468 /* don't try to optimize volatile accesses */ 4469 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) 4470 break; 4471 4472 intval = INTVAL (operands[2]); 4473 if ((intval & ~0xff) == 0) 4474 { 4475 if (REG_P (operands[0])) 4476 { 4477 /* Do low byte access only for %eax or when high bit is set */ 4478 if (REGNO (operands[0]) != 0 && !(intval & 0x80)) 4479 break; 4480 } 4481 4482byte_or_operation: 4483 CC_STATUS_INIT; 4484 4485 if (intval != INTVAL (operands[2])) 4486 operands[2] = GEN_INT (intval); 4487 4488 if (intval == 0xff) 4489 return AS2 (mov%B0,%2,%b0); 4490 4491 return AS2 (or%B0,%2,%b0); 4492 } 4493 4494 /* second byte? */ 4495 if ((intval & ~0xff00) == 0) 4496 { 4497 intval >>= 8; 4498 4499 if (REG_P (operands[0])) 4500 { 4501 CC_STATUS_INIT; 4502 operands[2] = GEN_INT (intval); 4503 if (intval == 0xff) 4504 return AS2 (mov%B0,%2,%h0); 4505 4506 return AS2 (or%B0,%2,%h0); 4507 } 4508 4509 operands[0] = adj_offsettable_operand (operands[0], 1); 4510 goto byte_or_operation; 4511 } 4512 4513 if (REG_P (operands[0])) 4514 break; 4515 4516 /* third byte? */ 4517 if ((intval & ~0xff0000) == 0) 4518 { 4519 intval >>= 16; 4520 operands[0] = adj_offsettable_operand (operands[0], 2); 4521 goto byte_or_operation; 4522 } 4523 4524 /* fourth byte? */ 4525 if ((intval & ~0xff000000) == 0) 4526 { 4527 intval = (intval >> 24) & 0xff; 4528 operands[0] = adj_offsettable_operand (operands[0], 3); 4529 goto byte_or_operation; 4530 } 4531 4532 default: 4533 break; 4534 } 4535 4536 return AS2 (or%L0,%2,%0); 4537}" 4538 [(set_attr "type" "binary")]) 4539 4540(define_insn "iorhi3" 4541 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 4542 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 4543 (match_operand:HI 2 "general_operand" "ri,rm")))] 4544 "" 4545 "* 4546{ 4547 HOST_WIDE_INT intval; 4548 switch (GET_CODE (operands[2])) 4549 { 4550 case CONST_INT: 4551 4552 if (REG_P (operands[0]) && ! QI_REG_P (operands[0])) 4553 break; 4554 4555 /* don't try to optimize volatile accesses */ 4556 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) 4557 break; 4558 4559 intval = 0xffff & INTVAL (operands[2]); 4560 4561 if ((intval & 0xff00) == 0) 4562 { 4563 if (REG_P (operands[0])) 4564 { 4565 /* Do low byte access only for %eax or when high bit is set */ 4566 if (REGNO (operands[0]) != 0 && !(intval & 0x80)) 4567 break; 4568 } 4569 4570byte_or_operation: 4571 CC_STATUS_INIT; 4572 4573 if (intval == 0xff) 4574 return AS2 (mov%B0,%2,%b0); 4575 4576 return AS2 (or%B0,%2,%b0); 4577 } 4578 4579 /* high byte? */ 4580 if ((intval & 0xff) == 0) 4581 { 4582 intval >>= 8; 4583 operands[2] = GEN_INT (intval); 4584 4585 if (REG_P (operands[0])) 4586 { 4587 CC_STATUS_INIT; 4588 if (intval == 0xff) 4589 return AS2 (mov%B0,%2,%h0); 4590 4591 return AS2 (or%B0,%2,%h0); 4592 } 4593 4594 operands[0] = adj_offsettable_operand (operands[0], 1); 4595 4596 goto byte_or_operation; 4597 } 4598 4599 default: 4600 break; 4601 } 4602 4603 if (REG_P (operands[0]) 4604 && i386_aligned_p (operands[2])) 4605 { 4606 CC_STATUS_INIT; 4607 operands[2] = i386_sext16_if_const (operands[2]); 4608 return AS2 (or%L0,%k2,%k0); 4609 } 4610 4611 if (GET_CODE (operands[2]) == CONST_INT 4612 && i386_aligned_p (operands[0])) 4613 { 4614 CC_STATUS_INIT; 4615 intval = 0xffff & INTVAL (operands[2]); 4616 if (intval != INTVAL (operands[2])) 4617 operands[2] = GEN_INT (intval); 4618 return AS2 (or%L0,%2,%k0); 4619 } 4620 4621 return AS2 (or%W0,%2,%0); 4622}" 4623 [(set_attr "type" "binary")]) 4624 4625(define_insn "iorqi3" 4626 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 4627 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 4628 (match_operand:QI 2 "general_operand" "qn,qmn")))] 4629 "" 4630 "* return AS2 (or%B0,%2,%0);" 4631 [(set_attr "type" "binary")]) 4632 4633;;- xor instructions 4634 4635(define_insn "xorsi3" 4636 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") 4637 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") 4638 (match_operand:SI 2 "general_operand" "ri,rm")))] 4639 "" 4640 "* 4641{ 4642 HOST_WIDE_INT intval; 4643 switch (GET_CODE (operands[2])) 4644 { 4645 case CONST_INT: 4646 4647 if (REG_P (operands[0]) && ! QI_REG_P (operands[0])) 4648 break; 4649 4650 /* don't try to optimize volatile accesses */ 4651 if (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) 4652 break; 4653 4654 intval = INTVAL (operands[2]); 4655 if ((intval & ~0xff) == 0) 4656 { 4657 if (REG_P (operands[0])) 4658 { 4659 /* Do low byte access only for %eax or when high bit is set */ 4660 if (REGNO (operands[0]) != 0 && !(intval & 0x80)) 4661 break; 4662 } 4663 4664byte_xor_operation: 4665 CC_STATUS_INIT; 4666 4667 if (intval == 0xff 4668 && (!TARGET_PENTIUM || optimize_size 4669 || (GET_CODE (operands[0]) == MEM 4670 && memory_address_info (XEXP (operands[0], 0), 1)))) 4671 return AS1 (not%B0,%b0); 4672 4673 if (intval != INTVAL (operands[2])) 4674 operands[2] = GEN_INT (intval); 4675 return AS2 (xor%B0,%2,%b0); 4676 } 4677 4678 /* second byte? */ 4679 if ((intval & ~0xff00) == 0) 4680 { 4681 intval >>= 8; 4682 4683 if (REG_P (operands[0])) 4684 { 4685 CC_STATUS_INIT; 4686 if (intval == 0xff 4687 && (!TARGET_PENTIUM || optimize_size 4688 || (GET_CODE (operands[0]) == MEM 4689 && memory_address_info (XEXP (operands[0], 0), 1)))) 4690 return AS1 (not%B0,%h0); 4691 4692 operands[2] = GEN_INT (intval); 4693 return AS2 (xor%B0,%2,%h0); 4694 } 4695 4696 operands[0] = adj_offsettable_operand (operands[0], 1); 4697 4698 goto byte_xor_operation; 4699 } 4700 4701 if (REG_P (operands[0])) 4702 break; 4703 4704 /* third byte? */ 4705 if ((intval & ~0xff0000) == 0) 4706 { 4707 intval >>= 16; 4708 operands[0] = adj_offsettable_operand (operands[0], 2); 4709 goto byte_xor_operation; 4710 } 4711 4712 /* fourth byte? */ 4713 if ((intval & ~0xff000000) == 0) 4714 { 4715 intval = (intval >> 24) & 0xff; 4716 operands[0] = adj_offsettable_operand (operands[0], 3); 4717 goto byte_xor_operation; 4718 } 4719 4720 default: 4721 break; 4722 } 4723 4724 return AS2 (xor%L0,%2,%0); 4725}" 4726 [(set_attr "type" "binary")]) 4727 4728(define_insn "xorhi3" 4729 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") 4730 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") 4731 (match_operand:HI 2 "general_operand" "ri,rm")))] 4732 "" 4733 "* 4734{ 4735 if (GET_CODE (operands[2]) == CONST_INT 4736 && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) 4737 { 4738 /* Can we ignore the upper byte? */ 4739 if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) 4740 && (INTVAL (operands[2]) & 0xff00) == 0) 4741 { 4742 CC_STATUS_INIT; 4743 if (INTVAL (operands[2]) & 0xffff0000) 4744 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff); 4745 4746 if (INTVAL (operands[2]) == 0xff 4747 && (!TARGET_PENTIUM || optimize_size 4748 || (GET_CODE (operands[0]) == MEM 4749 && memory_address_info (XEXP (operands[0], 0), 1)))) 4750 return AS1 (not%B0,%b0); 4751 4752 return AS2 (xor%B0,%2,%b0); 4753 } 4754 4755 /* Can we ignore the lower byte? */ 4756 /* ??? what about offsettable memory references? */ 4757 if (QI_REG_P (operands[0]) 4758 && (INTVAL (operands[2]) & 0xff) == 0) 4759 { 4760 CC_STATUS_INIT; 4761 operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff); 4762 4763 if (INTVAL (operands[2]) == 0xff 4764 && (!TARGET_PENTIUM || optimize_size 4765 || (GET_CODE (operands[0]) == MEM 4766 && memory_address_info (XEXP (operands[0], 0), 1)))) 4767 return AS1 (not%B0,%h0); 4768 4769 return AS2 (xor%B0,%2,%h0); 4770 } 4771 } 4772 4773 if (REG_P (operands[0]) 4774 && i386_aligned_p (operands[2])) 4775 { 4776 CC_STATUS_INIT; 4777 operands[2] = i386_sext16_if_const (operands[2]); 4778 return AS2 (xor%L0,%k2,%k0); 4779 } 4780 4781 if (GET_CODE (operands[2]) == CONST_INT 4782 && i386_aligned_p (operands[0])) 4783 { 4784 HOST_WIDE_INT intval; 4785 CC_STATUS_INIT; 4786 intval = 0xffff & INTVAL (operands[2]); 4787 if (intval != INTVAL (operands[2])) 4788 operands[2] = GEN_INT (intval); 4789 return AS2 (xor%L0,%2,%k0); 4790 } 4791 4792 return AS2 (xor%W0,%2,%0); 4793}" 4794 [(set_attr "type" "binary")]) 4795 4796(define_insn "xorqi3" 4797 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") 4798 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") 4799 (match_operand:QI 2 "general_operand" "qn,qm")))] 4800 "" 4801 "* return AS2 (xor%B0,%2,%0);" 4802 [(set_attr "type" "binary")]) 4803 4804;; logical operations for DImode 4805 4806(define_insn "anddi3" 4807 [(set (match_operand:DI 0 "general_operand" "=&r,&ro") 4808 (and:DI (match_operand:DI 1 "general_operand" "%0,0") 4809 (match_operand:DI 2 "general_operand" "oriF,riF")))] 4810 "" 4811 "#" 4812 [(set_attr "type" "binary")]) 4813 4814 4815(define_insn "iordi3" 4816 [(set (match_operand:DI 0 "general_operand" "=&r,&ro") 4817 (ior:DI (match_operand:DI 1 "general_operand" "%0,0") 4818 (match_operand:DI 2 "general_operand" "oriF,riF")))] 4819 "" 4820 "#" 4821 [(set_attr "type" "binary")]) 4822 4823(define_insn "xordi3" 4824 [(set (match_operand:DI 0 "general_operand" "=&r,&ro") 4825 (xor:DI (match_operand:DI 1 "general_operand" "%0,0") 4826 (match_operand:DI 2 "general_operand" "oriF,riF")))] 4827 "" 4828 "#" 4829 [(set_attr "type" "binary")]) 4830 4831(define_split 4832 [(set (match_operand:DI 0 "general_operand" "") 4833 (match_operator:DI 3 "ix86_logical_operator" 4834 [(match_operand:DI 1 "general_operand" "") 4835 (match_operand:DI 2 "general_operand" "")]))] 4836 "" 4837 [(set (match_dup 4) (match_op_dup:SI 3 [(match_dup 6) (match_dup 8)])) 4838 (set (match_dup 5) (match_op_dup:SI 3 [(match_dup 7) (match_dup 9)]))] 4839 "split_di (&operands[0], 1, &operands[4], &operands[5]); 4840 split_di (&operands[1], 1, &operands[6], &operands[7]); 4841 split_di (&operands[2], 1, &operands[8], &operands[9]);") 4842 4843;;- negation instructions 4844 4845(define_insn "negdi2" 4846 [(set (match_operand:DI 0 "general_operand" "=&ro") 4847 (neg:DI (match_operand:DI 1 "general_operand" "0")))] 4848 "" 4849 "* 4850{ 4851 rtx xops[2], low[1], high[1]; 4852 4853 CC_STATUS_INIT; 4854 4855 split_di (operands, 1, low, high); 4856 xops[0] = const0_rtx; 4857 xops[1] = high[0]; 4858 4859 output_asm_insn (AS1 (neg%L0,%0), low); 4860 output_asm_insn (AS2 (adc%L1,%0,%1), xops); 4861 output_asm_insn (AS1 (neg%L0,%0), high); 4862 RET; 4863}") 4864 4865(define_insn "negsi2" 4866 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 4867 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))] 4868 "" 4869 "neg%L0 %0") 4870 4871(define_insn "neghi2" 4872 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 4873 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] 4874 "" 4875 "* 4876 if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn)) 4877 { 4878 CC_STATUS_INIT; 4879 return AS1(neg%L0,%k0); 4880 } 4881 return AS1(neg%W0,%0);") 4882 4883(define_insn "negqi2" 4884 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 4885 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))] 4886 "" 4887 "neg%B0 %0") 4888 4889(define_insn "negsf2" 4890 [(set (match_operand:SF 0 "register_operand" "=f") 4891 (neg:SF (match_operand:SF 1 "register_operand" "0")))] 4892 "TARGET_80387" 4893 "fchs" 4894 [(set_attr "type" "fpop")]) 4895 4896(define_insn "negdf2" 4897 [(set (match_operand:DF 0 "register_operand" "=f") 4898 (neg:DF (match_operand:DF 1 "register_operand" "0")))] 4899 "TARGET_80387" 4900 "fchs" 4901 [(set_attr "type" "fpop")]) 4902 4903(define_insn "" 4904 [(set (match_operand:DF 0 "register_operand" "=f") 4905 (neg:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))] 4906 "TARGET_80387" 4907 "fchs" 4908 [(set_attr "type" "fpop")]) 4909 4910(define_insn "negxf2" 4911 [(set (match_operand:XF 0 "register_operand" "=f") 4912 (neg:XF (match_operand:XF 1 "register_operand" "0")))] 4913 "TARGET_80387" 4914 "fchs" 4915 [(set_attr "type" "fpop")]) 4916 4917(define_insn "" 4918 [(set (match_operand:XF 0 "register_operand" "=f") 4919 (neg:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))] 4920 "TARGET_80387" 4921 "fchs" 4922 [(set_attr "type" "fpop")]) 4923 4924;; Absolute value instructions 4925 4926(define_insn "abssf2" 4927 [(set (match_operand:SF 0 "register_operand" "=f") 4928 (abs:SF (match_operand:SF 1 "register_operand" "0")))] 4929 "TARGET_80387" 4930 "fabs" 4931 [(set_attr "type" "fpop")]) 4932 4933(define_insn "absdf2" 4934 [(set (match_operand:DF 0 "register_operand" "=f") 4935 (abs:DF (match_operand:DF 1 "register_operand" "0")))] 4936 "TARGET_80387" 4937 "fabs" 4938 [(set_attr "type" "fpop")]) 4939 4940(define_insn "" 4941 [(set (match_operand:DF 0 "register_operand" "=f") 4942 (abs:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))] 4943 "TARGET_80387" 4944 "fabs" 4945 [(set_attr "type" "fpop")]) 4946 4947(define_insn "absxf2" 4948 [(set (match_operand:XF 0 "register_operand" "=f") 4949 (abs:XF (match_operand:XF 1 "register_operand" "0")))] 4950 "TARGET_80387" 4951 "fabs" 4952 [(set_attr "type" "fpop")]) 4953 4954(define_insn "" 4955 [(set (match_operand:XF 0 "register_operand" "=f") 4956 (abs:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))] 4957 "TARGET_80387" 4958 "fabs" 4959 [(set_attr "type" "fpop")]) 4960 4961(define_insn "sqrtsf2" 4962 [(set (match_operand:SF 0 "register_operand" "=f") 4963 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))] 4964 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387" 4965 "fsqrt") 4966 4967(define_insn "sqrtdf2" 4968 [(set (match_operand:DF 0 "register_operand" "=f") 4969 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))] 4970 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 4971 && (TARGET_IEEE_FP || flag_fast_math) " 4972 "fsqrt") 4973 4974(define_insn "" 4975 [(set (match_operand:DF 0 "register_operand" "=f") 4976 (sqrt:DF (float_extend:DF 4977 (match_operand:SF 1 "register_operand" "0"))))] 4978 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387" 4979 "fsqrt") 4980 4981(define_insn "sqrtxf2" 4982 [(set (match_operand:XF 0 "register_operand" "=f") 4983 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] 4984 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 4985 && (TARGET_IEEE_FP || flag_fast_math) " 4986 "fsqrt") 4987 4988(define_insn "" 4989 [(set (match_operand:XF 0 "register_operand" "=f") 4990 (sqrt:XF (float_extend:XF 4991 (match_operand:DF 1 "register_operand" "0"))))] 4992 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387" 4993 "fsqrt") 4994 4995(define_insn "" 4996 [(set (match_operand:XF 0 "register_operand" "=f") 4997 (sqrt:XF (float_extend:XF 4998 (match_operand:SF 1 "register_operand" "0"))))] 4999 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387" 5000 "fsqrt") 5001 5002(define_insn "sindf2" 5003 [(set (match_operand:DF 0 "register_operand" "=f") 5004 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))] 5005 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" 5006 "fsin") 5007 5008(define_insn "sinsf2" 5009 [(set (match_operand:SF 0 "register_operand" "=f") 5010 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))] 5011 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" 5012 "fsin") 5013 5014(define_insn "" 5015 [(set (match_operand:DF 0 "register_operand" "=f") 5016 (unspec:DF [(float_extend:DF 5017 (match_operand:SF 1 "register_operand" "0"))] 1))] 5018 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" 5019 "fsin") 5020 5021(define_insn "sinxf2" 5022 [(set (match_operand:XF 0 "register_operand" "=f") 5023 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))] 5024 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" 5025 "fsin") 5026 5027(define_insn "cosdf2" 5028 [(set (match_operand:DF 0 "register_operand" "=f") 5029 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))] 5030 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" 5031 "fcos") 5032 5033(define_insn "cossf2" 5034 [(set (match_operand:SF 0 "register_operand" "=f") 5035 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))] 5036 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" 5037 "fcos") 5038 5039(define_insn "" 5040 [(set (match_operand:DF 0 "register_operand" "=f") 5041 (unspec:DF [(float_extend:DF 5042 (match_operand:SF 1 "register_operand" "0"))] 2))] 5043 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" 5044 "fcos") 5045 5046(define_insn "cosxf2" 5047 [(set (match_operand:XF 0 "register_operand" "=f") 5048 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))] 5049 "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" 5050 "fcos") 5051 5052;;- one complement instructions 5053 5054(define_insn "one_cmplsi2" 5055 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5056 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))] 5057 "" 5058 "* 5059{ 5060 /* A Pentium NOT is not pariable. Output it only in case of complex 5061 memory address, because XOR will be inpariable anyway because 5062 of immediate/displacement rule. */ 5063 5064 if (TARGET_PENTIUM && !optimize_size 5065 && (GET_CODE (operands[0]) != MEM 5066 || memory_address_info (XEXP (operands[0], 0), 1) == 0)) 5067 { 5068 rtx xops[2]; 5069 xops[0] = operands[0]; 5070 xops[1] = GEN_INT (0xffffffff); 5071 output_asm_insn (AS2 (xor%L0,%1,%0), xops); 5072 RET; 5073 } 5074 else 5075 return AS1 (not%L0,%0); 5076}") 5077 5078(define_insn "one_cmplhi2" 5079 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 5080 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] 5081 "" 5082 "* 5083{ 5084 /* A Pentium NOT is not pariable. Output it only in case of complex 5085 memory address, because XOR will be inpariable anyway because 5086 of immediate/displacement rule. */ 5087 5088 if (TARGET_PENTIUM && !optimize_size 5089 && (GET_CODE (operands[0]) != MEM 5090 || memory_address_info (XEXP (operands[0], 0), 1) == 0)) 5091 { 5092 rtx xops[2]; 5093 xops[0] = operands[0]; 5094 xops[1] = GEN_INT (0xffff); 5095 if (REG_P (operands[0]) 5096 && i386_cc_probably_useless_p (insn)) 5097 { 5098 CC_STATUS_INIT; 5099 output_asm_insn (AS2 (xor%L0,%1,%k0), xops); 5100 } 5101 else 5102 output_asm_insn (AS2 (xor%W0,%1,%0), xops); 5103 RET; 5104 } 5105 else 5106 { 5107 if (REG_P (operands[0]) 5108 && i386_cc_probably_useless_p (insn)) 5109 { 5110 CC_STATUS_INIT; 5111 return AS1 (not%L0,%k0); 5112 } 5113 return AS1 (not%W0,%0); 5114 } 5115}") 5116 5117(define_insn "one_cmplqi2" 5118 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 5119 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))] 5120 "" 5121 "* 5122{ 5123 /* A Pentium NOT is not pariable. Output it only in case of complex 5124 memory address, because XOR will be inpariable anyway because 5125 of immediate/displacement rule. */ 5126 5127 if (TARGET_PENTIUM && !optimize_size 5128 && (GET_CODE (operands[0]) != MEM 5129 || memory_address_info (XEXP (operands[0], 0), 1) == 0)) 5130 { 5131 rtx xops[2]; 5132 xops[0] = operands[0]; 5133 xops[1] = GEN_INT (0xff); 5134 output_asm_insn (AS2 (xor%B0,%1,%0), xops); 5135 RET; 5136 } 5137 else 5138 return AS1 (not%B0,%0); 5139}") 5140 5141;;- arithmetic shift instructions 5142 5143;; DImode shifts are implemented using the i386 "shift double" opcode, 5144;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count 5145;; is variable, then the count is in %cl and the "imm" operand is dropped 5146;; from the assembler input. 5147 5148;; This instruction shifts the target reg/mem as usual, but instead of 5149;; shifting in zeros, bits are shifted in from reg operand. If the insn 5150;; is a left shift double, bits are taken from the high order bits of 5151;; reg, else if the insn is a shift right double, bits are taken from the 5152;; low order bits of reg. So if %eax is "1234" and %edx is "5678", 5153;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". 5154 5155;; Since sh[lr]d does not change the `reg' operand, that is done 5156;; separately, making all shifts emit pairs of shift double and normal 5157;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to 5158;; support a 63 bit shift, each shift where the count is in a reg expands 5159;; to a pair of shifts, a branch, a shift by 32 and a label. 5160 5161;; If the shift count is a constant, we need never emit more than one 5162;; shift pair, instead using moves and sign extension for counts greater 5163;; than 31. 5164 5165(define_expand "ashldi3" 5166 [(set (match_operand:DI 0 "register_operand" "") 5167 (ashift:DI (match_operand:DI 1 "register_operand" "") 5168 (match_operand:QI 2 "nonmemory_operand" "")))] 5169 "" 5170 " 5171{ 5172 if (GET_CODE (operands[2]) != CONST_INT 5173 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')) 5174 { 5175 operands[2] = copy_to_mode_reg (QImode, operands[2]); 5176 emit_insn (gen_ashldi3_non_const_int (operands[0], operands[1], 5177 operands[2])); 5178 } 5179 else 5180 emit_insn (gen_ashldi3_const_int (operands[0], operands[1], operands[2])); 5181 5182 DONE; 5183}") 5184 5185(define_insn "ashldi3_const_int" 5186 [(set (match_operand:DI 0 "register_operand" "=&r") 5187 (ashift:DI (match_operand:DI 1 "register_operand" "0") 5188 (match_operand:QI 2 "const_int_operand" "J")))] 5189 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')" 5190 "* 5191{ 5192 rtx xops[4], low[1], high[1]; 5193 5194 CC_STATUS_INIT; 5195 5196 split_di (operands, 1, low, high); 5197 xops[0] = operands[2]; 5198 xops[1] = const1_rtx; 5199 xops[2] = low[0]; 5200 xops[3] = high[0]; 5201 5202 if (INTVAL (xops[0]) > 31) 5203 { 5204 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */ 5205 output_asm_insn (AS2 (xor%L2,%2,%2), xops); 5206 5207 if (INTVAL (xops[0]) > 32) 5208 { 5209 xops[0] = GEN_INT (INTVAL (xops[0]) - 32); 5210 output_asm_insn (AS2 (sal%L3,%0,%3), xops); /* Remaining shift */ 5211 } 5212 } 5213 else 5214 { 5215 output_asm_insn (AS3 (shld%L3,%0,%2,%3), xops); 5216 output_asm_insn (AS2 (sal%L2,%0,%2), xops); 5217 } 5218 RET; 5219}") 5220 5221(define_insn "ashldi3_non_const_int" 5222 [(set (match_operand:DI 0 "register_operand" "=&r") 5223 (ashift:DI (match_operand:DI 1 "register_operand" "0") 5224 (match_operand:QI 2 "register_operand" "c")))] 5225 "" 5226 "* 5227{ 5228 rtx xops[5], low[1], high[1]; 5229 5230 CC_STATUS_INIT; 5231 5232 split_di (operands, 1, low, high); 5233 xops[0] = operands[2]; 5234 xops[1] = GEN_INT (32); 5235 xops[2] = low[0]; 5236 xops[3] = high[0]; 5237 xops[4] = gen_label_rtx (); 5238 5239 output_asm_insn (AS3_SHIFT_DOUBLE (shld%L3,%0,%2,%3), xops); 5240 output_asm_insn (AS2 (sal%L2,%0,%2), xops); 5241 output_asm_insn (AS2 (test%B0,%1,%b0), xops); 5242 output_asm_insn (AS1 (je,%X4), xops); 5243 output_asm_insn (AS2 (mov%L3,%2,%3), xops); /* Fast shift by 32 */ 5244 output_asm_insn (AS2 (xor%L2,%2,%2), xops); 5245 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", 5246 CODE_LABEL_NUMBER (xops[4])); 5247 RET; 5248}") 5249 5250(define_expand "ashlsi3" 5251 [(set (match_operand:SI 0 "nonimmediate_operand" "") 5252 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "") 5253 (match_operand:SI 2 "nonmemory_operand" "")))] 5254 "" 5255 "") 5256 5257(define_expand "ashlhi3" 5258 [(set (match_operand:HI 0 "nonimmediate_operand" "") 5259 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "") 5260 (match_operand:HI 2 "nonmemory_operand" "")))] 5261 "" 5262 "") 5263 5264(define_expand "ashlqi3" 5265 [(set (match_operand:QI 0 "nonimmediate_operand" "") 5266 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "") 5267 (match_operand:QI 2 "nonmemory_operand" "")))] 5268 "" 5269 "") 5270 5271;; Pattern for shifts which can be encoded into an lea instruction. 5272;; This is kept as a separate pattern so that regmove can optimize cases 5273;; where we know the source and destination must match. 5274;; 5275;; Do not expose this pattern when optimizing for size since we never want 5276;; to use lea when optimizing for size since mov+sal is smaller than lea. 5277 5278(define_insn "" 5279 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r") 5280 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r") 5281 (match_operand:SI 2 "small_shift_operand" "M,M")))] 5282 "! optimize_size" 5283 "* return output_ashl (insn, operands);") 5284 5285;; Generic left shift pattern to catch all cases not handled by the 5286;; shift pattern above. 5287(define_insn "" 5288 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5289 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0") 5290 (match_operand:SI 2 "nonmemory_operand" "cI")))] 5291 "" 5292 "* return output_ashl (insn, operands);") 5293 5294(define_insn "" 5295 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r") 5296 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r") 5297 (match_operand:HI 2 "small_shift_operand" "M,M")))] 5298 "! optimize_size" 5299 "* return output_ashl (insn, operands);") 5300 5301(define_insn "" 5302 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 5303 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") 5304 (match_operand:HI 2 "nonmemory_operand" "cI")))] 5305 "" 5306 "* return output_ashl (insn, operands);") 5307 5308(define_insn "" 5309 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q") 5310 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,q") 5311 (match_operand:QI 2 "small_shift_operand" "M,M")))] 5312 "! optimize_size" 5313 "* return output_ashl (insn, operands);") 5314 5315;; Generic left shift pattern to catch all cases not handled by the 5316;; shift pattern above. 5317(define_insn "" 5318 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 5319 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") 5320 (match_operand:QI 2 "nonmemory_operand" "cI")))] 5321 "" 5322 "* return output_ashl (insn, operands);") 5323 5324;; See comment above `ashldi3' about how this works. 5325 5326(define_expand "ashrdi3" 5327 [(set (match_operand:DI 0 "register_operand" "") 5328 (ashiftrt:DI (match_operand:DI 1 "register_operand" "") 5329 (match_operand:QI 2 "nonmemory_operand" "")))] 5330 "" 5331 " 5332{ 5333 if (GET_CODE (operands[2]) != CONST_INT 5334 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')) 5335 { 5336 operands[2] = copy_to_mode_reg (QImode, operands[2]); 5337 emit_insn (gen_ashrdi3_non_const_int (operands[0], operands[1], 5338 operands[2])); 5339 } 5340 else 5341 emit_insn (gen_ashrdi3_const_int (operands[0], operands[1], operands[2])); 5342 5343 DONE; 5344}") 5345 5346(define_insn "ashldi3_32" 5347 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m") 5348 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r") 5349 (const_int 32)))] 5350 "" 5351 "* 5352{ 5353 rtx low[2], high[2], xops[4]; 5354 5355 split_di (operands, 2, low, high); 5356 xops[0] = high[0]; 5357 xops[1] = low[1]; 5358 xops[2] = low[0]; 5359 xops[3] = const0_rtx; 5360 if (!rtx_equal_p (xops[0], xops[1])) 5361 output_asm_insn (AS2 (mov%L0,%1,%0), xops); 5362 5363 if (GET_CODE (low[0]) == MEM) 5364 output_asm_insn (AS2 (mov%L2,%3,%2), xops); 5365 else 5366 output_asm_insn (AS2 (xor%L2,%2,%2), xops); 5367 5368 RET; 5369}") 5370 5371(define_insn "ashrdi3_const_int" 5372 [(set (match_operand:DI 0 "register_operand" "=&r") 5373 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") 5374 (match_operand:QI 2 "const_int_operand" "J")))] 5375 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')" 5376 "* 5377{ 5378 rtx xops[4], low[1], high[1]; 5379 5380 CC_STATUS_INIT; 5381 5382 split_di (operands, 1, low, high); 5383 xops[0] = operands[2]; 5384 xops[1] = const1_rtx; 5385 xops[2] = low[0]; 5386 xops[3] = high[0]; 5387 5388 if (INTVAL (xops[0]) > 31) 5389 { 5390 xops[1] = GEN_INT (31); 5391 output_asm_insn (AS2 (mov%L2,%3,%2), xops); 5392 output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */ 5393 5394 if (INTVAL (xops[0]) > 32) 5395 { 5396 xops[0] = GEN_INT (INTVAL (xops[0]) - 32); 5397 output_asm_insn (AS2 (sar%L2,%0,%2), xops); /* Remaining shift */ 5398 } 5399 } 5400 else 5401 { 5402 output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops); 5403 output_asm_insn (AS2 (sar%L3,%0,%3), xops); 5404 } 5405 5406 RET; 5407}") 5408 5409(define_insn "ashrdi3_non_const_int" 5410 [(set (match_operand:DI 0 "register_operand" "=&r") 5411 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") 5412 (match_operand:QI 2 "register_operand" "c")))] 5413 "" 5414 "* 5415{ 5416 rtx xops[5], low[1], high[1]; 5417 5418 CC_STATUS_INIT; 5419 5420 split_di (operands, 1, low, high); 5421 xops[0] = operands[2]; 5422 xops[1] = GEN_INT (32); 5423 xops[2] = low[0]; 5424 xops[3] = high[0]; 5425 xops[4] = gen_label_rtx (); 5426 5427 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops); 5428 output_asm_insn (AS2 (sar%L3,%0,%3), xops); 5429 output_asm_insn (AS2 (test%B0,%1,%b0), xops); 5430 output_asm_insn (AS1 (je,%X4), xops); 5431 xops[1] = GEN_INT (31); 5432 output_asm_insn (AS2 (mov%L2,%3,%2), xops); 5433 output_asm_insn (AS2 (sar%L3,%1,%3), xops); /* shift by 32 */ 5434 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", 5435 CODE_LABEL_NUMBER (xops[4])); 5436 RET; 5437}") 5438 5439(define_insn "ashrsi3_31" 5440 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,d") 5441 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,a") 5442 (const_int 31)))] 5443 "!TARGET_PENTIUM || optimize_size" 5444 "@ 5445 sar%L0 $31,%0 5446 cltd") 5447 5448(define_insn "ashrsi3" 5449 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5450 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 5451 (match_operand:SI 2 "nonmemory_operand" "cI")))] 5452 "" 5453 "* 5454{ 5455 if (REG_P (operands[2])) 5456 return AS2 (sar%L0,%b2,%0); 5457 else 5458 return AS2 (sar%L0,%2,%0); 5459}") 5460 5461(define_insn "ashrhi3" 5462 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 5463 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 5464 (match_operand:HI 2 "nonmemory_operand" "cI")))] 5465 "" 5466 "* 5467{ 5468 if (REG_P (operands[2])) 5469 return AS2 (sar%W0,%b2,%0); 5470 else 5471 return AS2 (sar%W0,%2,%0); 5472}") 5473 5474(define_insn "ashrqi3" 5475 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 5476 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 5477 (match_operand:QI 2 "nonmemory_operand" "cI")))] 5478 "" 5479 "* 5480{ 5481 if (REG_P (operands[2])) 5482 return AS2 (sar%B0,%b2,%0); 5483 else 5484 return AS2 (sar%B0,%2,%0); 5485}") 5486 5487;;- logical shift instructions 5488 5489;; See comment above `ashldi3' about how this works. 5490 5491(define_expand "lshrdi3" 5492 [(set (match_operand:DI 0 "register_operand" "") 5493 (lshiftrt:DI (match_operand:DI 1 "register_operand" "") 5494 (match_operand:QI 2 "nonmemory_operand" "")))] 5495 "" 5496 " 5497{ 5498 if (GET_CODE (operands[2]) != CONST_INT 5499 || ! CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')) 5500 { 5501 operands[2] = copy_to_mode_reg (QImode, operands[2]); 5502 emit_insn (gen_lshrdi3_non_const_int (operands[0], operands[1], 5503 operands[2])); 5504 } 5505 else 5506 emit_insn (gen_lshrdi3_const_int (operands[0], operands[1], operands[2])); 5507 5508 DONE; 5509}") 5510 5511(define_insn "lshrdi3_32" 5512 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m") 5513 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r") 5514 (const_int 32)))] 5515 "" 5516 "* 5517{ 5518 rtx low[2], high[2], xops[4]; 5519 5520 split_di (operands, 2, low, high); 5521 xops[0] = low[0]; 5522 xops[1] = high[1]; 5523 xops[2] = high[0]; 5524 xops[3] = const0_rtx; 5525 if (!rtx_equal_p (xops[0], xops[1])) 5526 output_asm_insn (AS2 (mov%L0,%1,%0), xops); 5527 5528 if (GET_CODE (low[0]) == MEM) 5529 output_asm_insn (AS2 (mov%L2,%3,%2), xops); 5530 else 5531 output_asm_insn (AS2 (xor%L2,%2,%2), xops); 5532 5533 RET; 5534}") 5535 5536(define_insn "lshrdi3_const_int" 5537 [(set (match_operand:DI 0 "register_operand" "=&r") 5538 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") 5539 (match_operand:QI 2 "const_int_operand" "J")))] 5540 "CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'J')" 5541 "* 5542{ 5543 rtx xops[4], low[1], high[1]; 5544 5545 CC_STATUS_INIT; 5546 5547 split_di (operands, 1, low, high); 5548 xops[0] = operands[2]; 5549 xops[1] = const1_rtx; 5550 xops[2] = low[0]; 5551 xops[3] = high[0]; 5552 5553 if (INTVAL (xops[0]) > 31) 5554 { 5555 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */ 5556 output_asm_insn (AS2 (xor%L3,%3,%3), xops); 5557 5558 if (INTVAL (xops[0]) > 32) 5559 { 5560 xops[0] = GEN_INT (INTVAL (xops[0]) - 32); 5561 output_asm_insn (AS2 (shr%L2,%0,%2), xops); /* Remaining shift */ 5562 } 5563 } 5564 else 5565 { 5566 output_asm_insn (AS3 (shrd%L2,%0,%3,%2), xops); 5567 output_asm_insn (AS2 (shr%L3,%0,%3), xops); 5568 } 5569 5570 RET; 5571}") 5572 5573(define_insn "lshrdi3_non_const_int" 5574 [(set (match_operand:DI 0 "register_operand" "=&r") 5575 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") 5576 (match_operand:QI 2 "register_operand" "c")))] 5577 "" 5578 "* 5579{ 5580 rtx xops[5], low[1], high[1]; 5581 5582 CC_STATUS_INIT; 5583 5584 split_di (operands, 1, low, high); 5585 xops[0] = operands[2]; 5586 xops[1] = GEN_INT (32); 5587 xops[2] = low[0]; 5588 xops[3] = high[0]; 5589 xops[4] = gen_label_rtx (); 5590 5591 output_asm_insn (AS3_SHIFT_DOUBLE (shrd%L2,%0,%3,%2), xops); 5592 output_asm_insn (AS2 (shr%L3,%0,%3), xops); 5593 output_asm_insn (AS2 (test%B0,%1,%b0), xops); 5594 output_asm_insn (AS1 (je,%X4), xops); 5595 output_asm_insn (AS2 (mov%L2,%3,%2), xops); /* Fast shift by 32 */ 5596 output_asm_insn (AS2 (xor%L3,%3,%3), xops); 5597 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", 5598 CODE_LABEL_NUMBER (xops[4])); 5599 RET; 5600}") 5601 5602(define_insn "lshrsi3" 5603 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5604 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") 5605 (match_operand:SI 2 "nonmemory_operand" "cI")))] 5606 "" 5607 "* 5608{ 5609 if (REG_P (operands[2])) 5610 return AS2 (shr%L0,%b2,%0); 5611 else 5612 return AS2 (shr%L0,%2,%1); 5613}") 5614 5615(define_insn "lshrhi3" 5616 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 5617 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") 5618 (match_operand:HI 2 "nonmemory_operand" "cI")))] 5619 "" 5620 "* 5621{ 5622 if (REG_P (operands[2])) 5623 return AS2 (shr%W0,%b2,%0); 5624 else 5625 return AS2 (shr%W0,%2,%0); 5626}") 5627 5628(define_insn "lshrqi3" 5629 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 5630 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") 5631 (match_operand:QI 2 "nonmemory_operand" "cI")))] 5632 "" 5633 "* 5634{ 5635 if (REG_P (operands[2])) 5636 return AS2 (shr%B0,%b2,%0); 5637 else 5638 return AS2 (shr%B0,%2,%0); 5639}") 5640 5641;;- rotate instructions 5642 5643(define_insn "rotlsi3" 5644 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5645 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0") 5646 (match_operand:SI 2 "nonmemory_operand" "cI")))] 5647 "" 5648 "* 5649{ 5650 if (REG_P (operands[2])) 5651 return AS2 (rol%L0,%b2,%0); 5652 else 5653 return AS2 (rol%L0,%2,%0); 5654}") 5655 5656(define_insn "rotlhi3" 5657 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 5658 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0") 5659 (match_operand:HI 2 "nonmemory_operand" "cI")))] 5660 "" 5661 "* 5662{ 5663 if (REG_P (operands[2])) 5664 return AS2 (rol%W0,%b2,%0); 5665 else 5666 return AS2 (rol%W0,%2,%0); 5667}") 5668 5669(define_insn "rotlqi3" 5670 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 5671 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0") 5672 (match_operand:QI 2 "nonmemory_operand" "cI")))] 5673 "" 5674 "* 5675{ 5676 if (REG_P (operands[2])) 5677 return AS2 (rol%B0,%b2,%0); 5678 else 5679 return AS2 (rol%B0,%2,%0); 5680}") 5681 5682(define_insn "rotrsi3" 5683 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5684 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0") 5685 (match_operand:SI 2 "nonmemory_operand" "cI")))] 5686 "" 5687 "* 5688{ 5689 if (REG_P (operands[2])) 5690 return AS2 (ror%L0,%b2,%0); 5691 else 5692 return AS2 (ror%L0,%2,%0); 5693}") 5694 5695(define_insn "rotrhi3" 5696 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") 5697 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0") 5698 (match_operand:HI 2 "nonmemory_operand" "cI")))] 5699 "" 5700 "* 5701{ 5702 if (REG_P (operands[2])) 5703 return AS2 (ror%W0,%b2,%0); 5704 else 5705 return AS2 (ror%W0,%2,%0); 5706}") 5707 5708(define_insn "rotrqi3" 5709 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 5710 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0") 5711 (match_operand:QI 2 "nonmemory_operand" "cI")))] 5712 "" 5713 "* 5714{ 5715 if (REG_P (operands[2])) 5716 return AS2 (ror%B0,%b2,%0); 5717 else 5718 return AS2 (ror%B0,%2,%0); 5719}") 5720 5721/* 5722;; This usually looses. But try a define_expand to recognize a few case 5723;; we can do efficiently, such as accessing the "high" QImode registers, 5724;; %ah, %bh, %ch, %dh. 5725;; ??? Note this has a botch on the mode of operand 0, which needs to be 5726;; fixed if this is ever enabled. 5727(define_insn "insv" 5728 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r") 5729 (match_operand:SI 1 "immediate_operand" "i") 5730 (match_operand:SI 2 "immediate_operand" "i")) 5731 (match_operand:SI 3 "nonmemory_operand" "ri"))] 5732 "" 5733 "* 5734{ 5735 if (INTVAL (operands[1]) + INTVAL (operands[2]) > GET_MODE_BITSIZE (SImode)) 5736 abort (); 5737 if (GET_CODE (operands[3]) == CONST_INT) 5738 { 5739 unsigned int mask = (1 << INTVAL (operands[1])) - 1; 5740 operands[1] = GEN_INT (~(mask << INTVAL (operands[2]))); 5741 output_asm_insn (AS2 (and%L0,%1,%0), operands); 5742 operands[3] = GEN_INT (INTVAL (operands[3]) << INTVAL (operands[2])); 5743 output_asm_insn (AS2 (or%L0,%3,%0), operands); 5744 } 5745 else 5746 { 5747 operands[0] = gen_rtx_REG (SImode, REGNO (operands[0])); 5748 if (INTVAL (operands[2])) 5749 output_asm_insn (AS2 (ror%L0,%2,%0), operands); 5750 output_asm_insn (AS3 (shrd%L0,%1,%3,%0), operands); 5751 operands[2] = GEN_INT (BITS_PER_WORD 5752 - INTVAL (operands[1]) - INTVAL (operands[2])); 5753 if (INTVAL (operands[2])) 5754 output_asm_insn (AS2 (ror%L0,%2,%0), operands); 5755 } 5756 RET; 5757}") 5758*/ 5759/* 5760;; ??? There are problems with the mode of operand[3]. The point of this 5761;; is to represent an HImode move to a "high byte" register. 5762 5763(define_expand "insv" 5764 [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "") 5765 (match_operand:SI 1 "immediate_operand" "") 5766 (match_operand:SI 2 "immediate_operand" "")) 5767 (match_operand:QI 3 "nonmemory_operand" "ri"))] 5768 "" 5769 " 5770{ 5771 if (GET_CODE (operands[1]) != CONST_INT 5772 || GET_CODE (operands[2]) != CONST_INT) 5773 FAIL; 5774 5775 if (! (INTVAL (operands[1]) == 8 5776 && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 0)) 5777 && ! INTVAL (operands[1]) == 1) 5778 FAIL; 5779}") 5780*/ 5781 5782;; On i386, the register count for a bit operation is *not* truncated, 5783;; so SHIFT_COUNT_TRUNCATED must not be defined. 5784 5785;; On i486, the shift & or/and code is faster than bts or btr. If 5786;; operands[0] is a MEM, the bt[sr] is half as fast as the normal code. 5787 5788;; On i386, bts is a little faster if operands[0] is a reg, and a 5789;; little slower if operands[0] is a MEM, than the shift & or/and code. 5790;; Use bts & btr, since they reload better. 5791 5792;; General bit set and clear. 5793(define_insn "" 5794 [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+rm") 5795 (const_int 1) 5796 (match_operand:SI 2 "register_operand" "r")) 5797 (match_operand:SI 3 "const_int_operand" "n"))] 5798 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT" 5799 "* 5800{ 5801 CC_STATUS_INIT; 5802 5803 if (INTVAL (operands[3]) == 1) 5804 return AS2 (bts%L0,%2,%0); 5805 else 5806 return AS2 (btr%L0,%2,%0); 5807}") 5808 5809;; Bit complement. See comments on previous pattern. 5810;; ??? Is this really worthwhile? 5811(define_insn "" 5812 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5813 (xor:SI (ashift:SI (const_int 1) 5814 (match_operand:SI 1 "register_operand" "r")) 5815 (match_operand:SI 2 "nonimmediate_operand" "0")))] 5816 "TARGET_USE_BIT_TEST && GET_CODE (operands[1]) != CONST_INT" 5817 "* 5818{ 5819 CC_STATUS_INIT; 5820 5821 return AS2 (btc%L0,%1,%0); 5822}") 5823 5824(define_insn "" 5825 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5826 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "0") 5827 (ashift:SI (const_int 1) 5828 (match_operand:SI 2 "register_operand" "r"))))] 5829 "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT" 5830 "* 5831{ 5832 CC_STATUS_INIT; 5833 5834 return AS2 (btc%L0,%2,%0); 5835}") 5836 5837;; Recognizers for bit-test instructions. 5838 5839;; The bt opcode allows a MEM in operands[0]. But on both i386 and 5840;; i486, it is faster to copy a MEM to REG and then use bt, than to use 5841;; bt on the MEM directly. 5842 5843;; ??? The first argument of a zero_extract must not be reloaded, so 5844;; don't allow a MEM in the operand predicate without allowing it in the 5845;; constraint. 5846 5847(define_insn "" 5848 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r") 5849 (const_int 1) 5850 (match_operand:SI 1 "register_operand" "r")))] 5851 "GET_CODE (operands[1]) != CONST_INT" 5852 "* 5853{ 5854 cc_status.flags |= CC_Z_IN_NOT_C; 5855 return AS2 (bt%L0,%1,%0); 5856}") 5857 5858(define_insn "" 5859 [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r") 5860 (match_operand:SI 1 "const_int_operand" "n") 5861 (match_operand:SI 2 "const_int_operand" "n")))] 5862 "" 5863 "* 5864{ 5865 unsigned int mask; 5866 5867 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]); 5868 operands[1] = GEN_INT (mask); 5869 5870 if (QI_REG_P (operands[0]) 5871 /* A Pentium test is pairable only with eax. Not with ah or al. */ 5872 && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM 5873 || optimize_size)) 5874 { 5875 if ((mask & ~0xff) == 0) 5876 { 5877 cc_status.flags |= CC_NOT_NEGATIVE; 5878 return AS2 (test%B0,%1,%b0); 5879 } 5880 5881 if ((mask & ~0xff00) == 0) 5882 { 5883 cc_status.flags |= CC_NOT_NEGATIVE; 5884 operands[1] = GEN_INT (mask >> 8); 5885 return AS2 (test%B0,%1,%h0); 5886 } 5887 } 5888 5889 return AS2 (test%L0,%1,%0); 5890}") 5891 5892;; ??? All bets are off if operand 0 is a volatile MEM reference. 5893;; The CPU may access unspecified bytes around the actual target byte. 5894 5895(define_insn "" 5896 [(set (cc0) (zero_extract (match_operand:QI 0 "memory_operand" "m") 5897 (match_operand:SI 1 "const_int_operand" "n") 5898 (match_operand:SI 2 "const_int_operand" "n")))] 5899 "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])" 5900 "* 5901{ 5902 unsigned int mask; 5903 5904 mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]); 5905 operands[1] = GEN_INT (mask); 5906 5907 if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) 5908 /* A Pentium test is pairable only with eax. Not with ah or al. */ 5909 && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM 5910 || optimize_size)) 5911 { 5912 if ((mask & ~0xff) == 0) 5913 { 5914 cc_status.flags |= CC_NOT_NEGATIVE; 5915 return AS2 (test%B0,%1,%b0); 5916 } 5917 5918 if ((mask & ~0xff00) == 0) 5919 { 5920 cc_status.flags |= CC_NOT_NEGATIVE; 5921 operands[1] = GEN_INT (mask >> 8); 5922 5923 if (QI_REG_P (operands[0])) 5924 return AS2 (test%B0,%1,%h0); 5925 else 5926 { 5927 operands[0] = adj_offsettable_operand (operands[0], 1); 5928 return AS2 (test%B0,%1,%b0); 5929 } 5930 } 5931 5932 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff0000) == 0) 5933 { 5934 cc_status.flags |= CC_NOT_NEGATIVE; 5935 operands[1] = GEN_INT (mask >> 16); 5936 operands[0] = adj_offsettable_operand (operands[0], 2); 5937 return AS2 (test%B0,%1,%b0); 5938 } 5939 5940 if (GET_CODE (operands[0]) == MEM && (mask & ~0xff000000) == 0) 5941 { 5942 cc_status.flags |= CC_NOT_NEGATIVE; 5943 operands[1] = GEN_INT (mask >> 24); 5944 operands[0] = adj_offsettable_operand (operands[0], 3); 5945 return AS2 (test%B0,%1,%b0); 5946 } 5947 } 5948 5949 if (CONSTANT_P (operands[1]) || GET_CODE (operands[0]) == MEM) 5950 return AS2 (test%L0,%1,%0); 5951 5952 return AS2 (test%L1,%0,%1); 5953}") 5954 5955;; Store-flag instructions. 5956 5957;; For all sCOND expanders, also expand the compare or test insn that 5958;; generates cc0. Generate an equality comparison if `seq' or `sne'. 5959 5960(define_expand "seq" 5961 [(match_dup 1) 5962 (set (match_operand:QI 0 "register_operand" "") 5963 (eq:QI (cc0) (const_int 0)))] 5964 "" 5965 " 5966{ 5967 if (TARGET_IEEE_FP 5968 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT) 5969 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1); 5970 else 5971 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); 5972}") 5973 5974(define_expand "sne" 5975 [(match_dup 1) 5976 (set (match_operand:QI 0 "register_operand" "") 5977 (ne:QI (cc0) (const_int 0)))] 5978 "" 5979 " 5980{ 5981 if (TARGET_IEEE_FP 5982 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT) 5983 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1); 5984 else 5985 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); 5986}") 5987 5988(define_expand "sgt" 5989 [(match_dup 1) 5990 (set (match_operand:QI 0 "register_operand" "") 5991 (gt:QI (cc0) (const_int 0)))] 5992 "" 5993 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 5994 5995(define_expand "sgtu" 5996 [(match_dup 1) 5997 (set (match_operand:QI 0 "register_operand" "") 5998 (gtu:QI (cc0) (const_int 0)))] 5999 "" 6000 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 6001 6002(define_expand "slt" 6003 [(match_dup 1) 6004 (set (match_operand:QI 0 "register_operand" "") 6005 (lt:QI (cc0) (const_int 0)))] 6006 "" 6007 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 6008 6009(define_expand "sltu" 6010 [(match_dup 1) 6011 (set (match_operand:QI 0 "register_operand" "") 6012 (ltu:QI (cc0) (const_int 0)))] 6013 "" 6014 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 6015 6016(define_expand "sge" 6017 [(match_dup 1) 6018 (set (match_operand:QI 0 "register_operand" "") 6019 (ge:QI (cc0) (const_int 0)))] 6020 "" 6021 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 6022 6023(define_expand "sgeu" 6024 [(match_dup 1) 6025 (set (match_operand:QI 0 "register_operand" "") 6026 (geu:QI (cc0) (const_int 0)))] 6027 "" 6028 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 6029 6030(define_expand "sle" 6031 [(match_dup 1) 6032 (set (match_operand:QI 0 "register_operand" "") 6033 (le:QI (cc0) (const_int 0)))] 6034 "" 6035 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 6036 6037(define_expand "sleu" 6038 [(match_dup 1) 6039 (set (match_operand:QI 0 "register_operand" "") 6040 (leu:QI (cc0) (const_int 0)))] 6041 "" 6042 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 6043 6044;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may 6045;; not have any input reloads. A MEM write might need an input reload 6046;; for the address of the MEM. So don't allow MEM as the SET_DEST. 6047 6048(define_insn "*setcc" 6049 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 6050 (match_operator:QI 1 "comparison_operator" [(cc0) (const_int 0)]))] 6051 "reload_completed || register_operand (operands[0], QImode)" 6052 "* 6053{ 6054 enum rtx_code code = GET_CODE (operands[1]); 6055 if (cc_prev_status.flags & CC_TEST_AX) 6056 { 6057 int eq; 6058 HOST_WIDE_INT c; 6059 operands[2] = gen_rtx_REG (SImode, 0); 6060 switch (code) 6061 { 6062 case EQ: 6063 c = 0x4000; 6064 eq = 0; 6065 break; 6066 case NE: 6067 c = 0x4000; 6068 eq = 1; 6069 break; 6070 case GT: 6071 c = 0x4100; 6072 eq = 1; 6073 break; 6074 case LT: 6075 c = 0x100; 6076 eq = 0; 6077 break; 6078 case GE: 6079 c = 0x100; 6080 eq = 1; 6081 break; 6082 case LE: 6083 c = 0x4100; 6084 eq = 0; 6085 break; 6086 default: 6087 abort (); 6088 } 6089 if (!TARGET_PENTIUM || optimize_size) 6090 { 6091 operands[3] = GEN_INT (c >> 8); 6092 output_asm_insn (AS2 (test%B0,%3,%h2), operands); 6093 } 6094 else 6095 { 6096 operands[3] = GEN_INT (c); 6097 output_asm_insn (AS2 (test%L0,%3,%2), operands); 6098 } 6099 return eq ? AS1 (sete,%0) : AS1 (setne, %0); 6100 } 6101 6102 if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT)) 6103 return (char *)0; 6104 return AS1(set%D1,%0); 6105}") 6106 6107 6108;; Basic conditional jump instructions. 6109;; We ignore the overflow flag for signed branch instructions. 6110 6111;; For all bCOND expanders, also expand the compare or test insn that 6112;; generates cc0. Generate an equality comparison if `beq' or `bne'. 6113 6114(define_expand "beq" 6115 [(match_dup 1) 6116 (set (pc) 6117 (if_then_else (eq (cc0) 6118 (const_int 0)) 6119 (label_ref (match_operand 0 "" "")) 6120 (pc)))] 6121 "" 6122 " 6123{ 6124 if (TARGET_IEEE_FP 6125 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT) 6126 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1); 6127 else 6128 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); 6129}") 6130 6131(define_expand "bne" 6132 [(match_dup 1) 6133 (set (pc) 6134 (if_then_else (ne (cc0) 6135 (const_int 0)) 6136 (label_ref (match_operand 0 "" "")) 6137 (pc)))] 6138 "" 6139 " 6140{ 6141 if (TARGET_IEEE_FP 6142 && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT) 6143 operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1); 6144 else 6145 operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); 6146}") 6147 6148 6149(define_expand "bgt" 6150 [(match_dup 1) 6151 (set (pc) 6152 (if_then_else (gt (cc0) 6153 (const_int 0)) 6154 (label_ref (match_operand 0 "" "")) 6155 (pc)))] 6156 "" 6157 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 6158 6159(define_expand "bgtu" 6160 [(match_dup 1) 6161 (set (pc) 6162 (if_then_else (gtu (cc0) 6163 (const_int 0)) 6164 (label_ref (match_operand 0 "" "")) 6165 (pc)))] 6166 "" 6167 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 6168 6169(define_expand "blt" 6170 [(match_dup 1) 6171 (set (pc) 6172 (if_then_else (lt (cc0) 6173 (const_int 0)) 6174 (label_ref (match_operand 0 "" "")) 6175 (pc)))] 6176 "" 6177 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 6178 6179 6180(define_expand "bltu" 6181 [(match_dup 1) 6182 (set (pc) 6183 (if_then_else (ltu (cc0) 6184 (const_int 0)) 6185 (label_ref (match_operand 0 "" "")) 6186 (pc)))] 6187 "" 6188 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 6189 6190(define_expand "bge" 6191 [(match_dup 1) 6192 (set (pc) 6193 (if_then_else (ge (cc0) 6194 (const_int 0)) 6195 (label_ref (match_operand 0 "" "")) 6196 (pc)))] 6197 "" 6198 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 6199 6200(define_expand "bgeu" 6201 [(match_dup 1) 6202 (set (pc) 6203 (if_then_else (geu (cc0) 6204 (const_int 0)) 6205 (label_ref (match_operand 0 "" "")) 6206 (pc)))] 6207 "" 6208 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 6209 6210(define_expand "ble" 6211 [(match_dup 1) 6212 (set (pc) 6213 (if_then_else (le (cc0) 6214 (const_int 0)) 6215 (label_ref (match_operand 0 "" "")) 6216 (pc)))] 6217 "" 6218 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 6219 6220(define_expand "bleu" 6221 [(match_dup 1) 6222 (set (pc) 6223 (if_then_else (leu (cc0) 6224 (const_int 0)) 6225 (label_ref (match_operand 0 "" "")) 6226 (pc)))] 6227 "" 6228 "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") 6229 6230(define_insn "" 6231 [(set (pc) 6232 (if_then_else (match_operator 0 "comparison_operator" 6233 [(cc0) (const_int 0)]) 6234 (label_ref (match_operand 1 "" "")) 6235 (pc)))] 6236 "" 6237 "* 6238{ 6239 enum rtx_code code = GET_CODE (operands[0]); 6240 if (cc_prev_status.flags & CC_TEST_AX) 6241 { 6242 int eq; 6243 HOST_WIDE_INT c; 6244 operands[2] = gen_rtx_REG (SImode, 0); 6245 switch (code) 6246 { 6247 case EQ: 6248 c = 0x4000; 6249 eq = 0; 6250 break; 6251 case NE: 6252 c = 0x4000; 6253 eq = 1; 6254 break; 6255 case GT: 6256 c = 0x4100; 6257 eq = 1; 6258 break; 6259 case LT: 6260 c = 0x100; 6261 eq = 0; 6262 break; 6263 case GE: 6264 c = 0x100; 6265 eq = 1; 6266 break; 6267 case LE: 6268 c = 0x4100; 6269 eq = 0; 6270 break; 6271 default: 6272 abort (); 6273 } 6274 if (!TARGET_PENTIUM || optimize_size) 6275 { 6276 operands[3] = GEN_INT (c >> 8); 6277 output_asm_insn (AS2 (test%B0,%3,%h2), operands); 6278 } 6279 else 6280 { 6281 operands[3] = GEN_INT (c); 6282 output_asm_insn (AS2 (test%L0,%3,%2), operands); 6283 } 6284 return eq ? AS1 (je,%l1) : AS1 (jne, %l1); 6285 } 6286 if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT)) 6287 return (char *)0; 6288 6289 return AS1(j%D0,%l1); 6290}") 6291 6292(define_insn "" 6293 [(set (pc) 6294 (if_then_else (match_operator 0 "comparison_operator" 6295 [(cc0) (const_int 0)]) 6296 (pc) 6297 (label_ref (match_operand 1 "" ""))))] 6298 "" 6299 "* 6300{ 6301 enum rtx_code code = GET_CODE (operands[0]); 6302 if (cc_prev_status.flags & CC_TEST_AX) 6303 { 6304 int eq; 6305 HOST_WIDE_INT c; 6306 operands[2] = gen_rtx_REG (SImode, 0); 6307 switch (code) 6308 { 6309 case EQ: 6310 c = 0x4000; 6311 eq = 1; 6312 break; 6313 case NE: 6314 c = 0x4000; 6315 eq = 0; 6316 break; 6317 case GT: 6318 c = 0x4100; 6319 eq = 0; 6320 break; 6321 case LT: 6322 c = 0x100; 6323 eq = 1; 6324 break; 6325 case GE: 6326 c = 0x100; 6327 eq = 0; 6328 break; 6329 case LE: 6330 c = 0x4100; 6331 eq = 1; 6332 break; 6333 default: 6334 abort (); 6335 } 6336 if (!TARGET_PENTIUM || optimize_size) 6337 { 6338 operands[3] = GEN_INT (c >> 8); 6339 output_asm_insn (AS2 (test%B0,%3,%h2), operands); 6340 } 6341 else 6342 { 6343 operands[3] = GEN_INT (c); 6344 output_asm_insn (AS2 (test%L0,%3,%2), operands); 6345 } 6346 return eq ? AS1 (je,%l1) : AS1 (jne, %l1); 6347 } 6348 if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT)) 6349 return (char *)0; 6350 6351 return AS1(j%d0,%l1); 6352}") 6353 6354;; Unconditional and other jump instructions 6355 6356(define_insn "jump" 6357 [(set (pc) 6358 (label_ref (match_operand 0 "" "")))] 6359 "" 6360 "jmp %l0" 6361 [(set_attr "memory" "none")]) 6362 6363(define_insn "indirect_jump" 6364 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))] 6365 "" 6366 "* 6367{ 6368 CC_STATUS_INIT; 6369 6370 return AS1 (jmp,%*%0); 6371}" 6372 [(set_attr "memory" "none")]) 6373 6374;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i); 6375;; if S does not change i 6376 6377(define_expand "decrement_and_branch_until_zero" 6378 [(parallel [(set (pc) 6379 (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "") 6380 (const_int -1)) 6381 (const_int 0)) 6382 (label_ref (match_operand 1 "" "")) 6383 (pc))) 6384 (set (match_dup 0) 6385 (plus:SI (match_dup 0) 6386 (const_int -1)))])] 6387 "" 6388 "") 6389 6390(define_insn "" 6391 [(set (pc) 6392 (if_then_else (match_operator 0 "arithmetic_comparison_operator" 6393 [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+c*r,m") 6394 (match_operand:SI 2 "general_operand" "rmi,ri")) 6395 (const_int 0)]) 6396 (label_ref (match_operand 3 "" "")) 6397 (pc))) 6398 (set (match_dup 1) 6399 (plus:SI (match_dup 1) 6400 (match_dup 2)))] 6401 "" 6402 "* 6403{ 6404 CC_STATUS_INIT; 6405 6406 if (GET_CODE (operands[1]) == REG && REGNO (operands[2]) == 2 && 6407 operands[2] == constm1_rtx && ix86_cpu == PROCESSOR_K6) 6408 return \"loop %l3\"; 6409 6410 if (operands[2] == constm1_rtx) 6411 output_asm_insn (AS1 (dec%L1,%1), operands); 6412 6413 else if (operands[2] == const1_rtx) 6414 output_asm_insn (AS1 (inc%L1,%1), operands); 6415 6416 else 6417 output_asm_insn (AS2 (add%L1,%2,%1), operands); 6418 6419 return AS1 (%J0,%l3); 6420}") 6421 6422(define_insn "" 6423 [(set (pc) 6424 (if_then_else (match_operator 0 "arithmetic_comparison_operator" 6425 [(minus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m") 6426 (match_operand:SI 2 "general_operand" "rmi,ri")) 6427 (const_int 0)]) 6428 (label_ref (match_operand 3 "" "")) 6429 (pc))) 6430 (set (match_dup 1) 6431 (minus:SI (match_dup 1) 6432 (match_dup 2)))] 6433 "" 6434 "* 6435{ 6436 CC_STATUS_INIT; 6437 if (operands[2] == const1_rtx) 6438 output_asm_insn (AS1 (dec%L1,%1), operands); 6439 6440 else if (operands[1] == constm1_rtx) 6441 output_asm_insn (AS1 (inc%L1,%1), operands); 6442 6443 else 6444 output_asm_insn (AS2 (sub%L1,%2,%1), operands); 6445 6446 return AS1 (%J0,%l3); 6447}") 6448 6449(define_insn "" 6450 [(set (pc) 6451 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g") 6452 (const_int 0)) 6453 (label_ref (match_operand 1 "" "")) 6454 (pc))) 6455 (set (match_dup 0) 6456 (plus:SI (match_dup 0) 6457 (const_int -1)))] 6458 "" 6459 "* 6460{ 6461 CC_STATUS_INIT; 6462 operands[2] = const1_rtx; 6463 output_asm_insn (AS2 (sub%L0,%2,%0), operands); 6464 return \"jnc %l1\"; 6465}") 6466 6467(define_insn "" 6468 [(set (pc) 6469 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g") 6470 (const_int 0)) 6471 (label_ref (match_operand 1 "" "")) 6472 (pc))) 6473 (set (match_dup 0) 6474 (plus:SI (match_dup 0) 6475 (const_int -1)))] 6476 "" 6477 "* 6478{ 6479 CC_STATUS_INIT; 6480 operands[2] = const1_rtx; 6481 output_asm_insn (AS2 (sub%L0,%2,%0), operands); 6482 return \"jc %l1\"; 6483}") 6484 6485(define_insn "" 6486 [(set (pc) 6487 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g") 6488 (const_int 1)) 6489 (label_ref (match_operand 1 "" "")) 6490 (pc))) 6491 (set (match_dup 0) 6492 (plus:SI (match_dup 0) 6493 (const_int -1)))] 6494 "" 6495 "* 6496{ 6497 CC_STATUS_INIT; 6498 output_asm_insn (AS1 (dec%L0,%0), operands); 6499 return \"jnz %l1\"; 6500}") 6501 6502(define_insn "" 6503 [(set (pc) 6504 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g") 6505 (const_int 1)) 6506 (label_ref (match_operand 1 "" "")) 6507 (pc))) 6508 (set (match_dup 0) 6509 (plus:SI (match_dup 0) 6510 (const_int -1)))] 6511 "" 6512 "* 6513{ 6514 CC_STATUS_INIT; 6515 output_asm_insn (AS1 (dec%L0,%0), operands); 6516 return \"jz %l1\"; 6517}") 6518 6519(define_insn "" 6520 [(set (pc) 6521 (if_then_else (ne (match_operand:SI 0 "general_operand" "+g") 6522 (const_int -1)) 6523 (label_ref (match_operand 1 "" "")) 6524 (pc))) 6525 (set (match_dup 0) 6526 (plus:SI (match_dup 0) 6527 (const_int 1)))] 6528 "" 6529 "* 6530{ 6531 CC_STATUS_INIT; 6532 output_asm_insn (AS1 (inc%L0,%0), operands); 6533 return \"jnz %l1\"; 6534}") 6535 6536(define_insn "" 6537 [(set (pc) 6538 (if_then_else (eq (match_operand:SI 0 "general_operand" "+g") 6539 (const_int -1)) 6540 (label_ref (match_operand 1 "" "")) 6541 (pc))) 6542 (set (match_dup 0) 6543 (plus:SI (match_dup 0) 6544 (const_int 1)))] 6545 "" 6546 "* 6547{ 6548 CC_STATUS_INIT; 6549 output_asm_insn (AS1 (inc%L0,%0), operands); 6550 return \"jz %l1\"; 6551}") 6552 6553;; Implement switch statements when generating PIC code. Switches are 6554;; implemented by `tablejump' when not using -fpic. 6555 6556;; Emit code here to do the range checking and make the index zero based. 6557 6558(define_expand "casesi" 6559 [(set (match_dup 5) 6560 (match_operand:SI 0 "general_operand" "")) 6561 (set (match_dup 6) 6562 (minus:SI (match_dup 5) 6563 (match_operand:SI 1 "general_operand" ""))) 6564 (set (cc0) 6565 (compare:CC (match_dup 6) 6566 (match_operand:SI 2 "general_operand" ""))) 6567 (set (pc) 6568 (if_then_else (gtu (cc0) 6569 (const_int 0)) 6570 (label_ref (match_operand 4 "" "")) 6571 (pc))) 6572 (parallel 6573 [(set (pc) 6574 (minus:SI (reg:SI 3) 6575 (mem:SI (plus:SI (mult:SI (match_dup 6) 6576 (const_int 4)) 6577 (label_ref (match_operand 3 "" "")))))) 6578 (clobber (match_scratch:SI 7 ""))])] 6579 "flag_pic" 6580 " 6581{ 6582 operands[5] = gen_reg_rtx (SImode); 6583 operands[6] = gen_reg_rtx (SImode); 6584 current_function_uses_pic_offset_table = 1; 6585}") 6586 6587;; Implement a casesi insn. 6588 6589;; Each entry in the "addr_diff_vec" looks like this as the result of the 6590;; two rules below: 6591;; 6592;; .long _GLOBAL_OFFSET_TABLE_+[.-.L2] 6593;; 6594;; 1. An expression involving an external reference may only use the 6595;; addition operator, and only with an assembly-time constant. 6596;; The example above satisfies this because ".-.L2" is a constant. 6597;; 6598;; 2. The symbol _GLOBAL_OFFSET_TABLE_ is magic, and at link time is 6599;; given the value of "GOT - .", where GOT is the actual address of 6600;; the Global Offset Table. Therefore, the .long above actually 6601;; stores the value "( GOT - . ) + [ . - .L2 ]", or "GOT - .L2". The 6602;; expression "GOT - .L2" by itself would generate an error from as(1). 6603;; 6604;; The pattern below emits code that looks like this: 6605;; 6606;; movl %ebx,reg 6607;; subl TABLE@GOTOFF(%ebx,index,4),reg 6608;; jmp reg 6609;; 6610;; The addr_diff_vec contents may be directly referenced with @GOTOFF, since 6611;; the addr_diff_vec is known to be part of this module. 6612;; 6613;; The subl above calculates "GOT - (( GOT - . ) + [ . - .L2 ])", which 6614;; evaluates to just ".L2". 6615 6616(define_insn "" 6617 [(set (pc) 6618 (minus:SI (reg:SI 3) 6619 (mem:SI (plus:SI 6620 (mult:SI (match_operand:SI 0 "register_operand" "r") 6621 (const_int 4)) 6622 (label_ref (match_operand 1 "" "")))))) 6623 (clobber (match_scratch:SI 2 "=&r"))] 6624 "" 6625 "* 6626{ 6627 rtx xops[4]; 6628 6629 xops[0] = operands[0]; 6630 xops[1] = operands[1]; 6631 xops[2] = operands[2]; 6632 xops[3] = pic_offset_table_rtx; 6633 6634 output_asm_insn (AS2 (mov%L2,%3,%2), xops); 6635 output_asm_insn (\"sub%L2 %l1@GOTOFF(%3,%0,4),%2\", xops); 6636 output_asm_insn (AS1 (jmp,%*%2), xops); 6637 ASM_OUTPUT_ALIGN (asm_out_file, i386_align_jumps); 6638 RET; 6639}") 6640 6641(define_insn "tablejump" 6642 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm")) 6643 (use (label_ref (match_operand 1 "" "")))] 6644 "" 6645 "* 6646{ 6647 CC_STATUS_INIT; 6648 6649 return AS1 (jmp,%*%0); 6650}") 6651 6652;; Call insns. 6653 6654;; If generating PIC code, the predicate indirect_operand will fail 6655;; for operands[0] containing symbolic references on all of the named 6656;; call* patterns. Each named pattern is followed by an unnamed pattern 6657;; that matches any call to a symbolic CONST (ie, a symbol_ref). The 6658;; unnamed patterns are only used while generating PIC code, because 6659;; otherwise the named patterns match. 6660 6661;; Call subroutine returning no value. 6662 6663(define_expand "call_pop" 6664 [(parallel [(call (match_operand:QI 0 "indirect_operand" "") 6665 (match_operand:SI 1 "general_operand" "")) 6666 (set (reg:SI 7) 6667 (plus:SI (reg:SI 7) 6668 (match_operand:SI 3 "immediate_operand" "")))])] 6669 "" 6670 " 6671{ 6672 rtx addr; 6673 6674 if (operands[3] == const0_rtx) 6675 { 6676 emit_insn (gen_call (operands[0], operands[1])); 6677 DONE; 6678 } 6679 6680 if (flag_pic) 6681 current_function_uses_pic_offset_table = 1; 6682 6683 /* With half-pic, force the address into a register. */ 6684 addr = XEXP (operands[0], 0); 6685 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr)) 6686 XEXP (operands[0], 0) = force_reg (Pmode, addr); 6687 6688 if (! expander_call_insn_operand (operands[0], QImode)) 6689 operands[0] 6690 = change_address (operands[0], VOIDmode, 6691 copy_to_mode_reg (Pmode, XEXP (operands[0], 0))); 6692}") 6693 6694(define_insn "" 6695 [(call (match_operand:QI 0 "call_insn_operand" "m") 6696 (match_operand:SI 1 "general_operand" "g")) 6697 (set (reg:SI 7) (plus:SI (reg:SI 7) 6698 (match_operand:SI 3 "immediate_operand" "i")))] 6699 "" 6700 "* 6701{ 6702 if (GET_CODE (operands[0]) == MEM 6703 && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) 6704 { 6705 operands[0] = XEXP (operands[0], 0); 6706 return AS1 (call,%*%0); 6707 } 6708 else 6709 return AS1 (call,%P0); 6710}") 6711 6712(define_insn "" 6713 [(call (mem:QI (match_operand:SI 0 "symbolic_operand" "")) 6714 (match_operand:SI 1 "general_operand" "g")) 6715 (set (reg:SI 7) (plus:SI (reg:SI 7) 6716 (match_operand:SI 3 "immediate_operand" "i")))] 6717 "!HALF_PIC_P ()" 6718 "call %P0") 6719 6720(define_expand "call" 6721 [(call (match_operand:QI 0 "indirect_operand" "") 6722 (match_operand:SI 1 "general_operand" ""))] 6723 ;; Operand 1 not used on the i386. 6724 "" 6725 " 6726{ 6727 rtx addr; 6728 6729 if (flag_pic) 6730 current_function_uses_pic_offset_table = 1; 6731 6732 /* With half-pic, force the address into a register. */ 6733 addr = XEXP (operands[0], 0); 6734 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr)) 6735 XEXP (operands[0], 0) = force_reg (Pmode, addr); 6736 6737 if (! expander_call_insn_operand (operands[0], QImode)) 6738 operands[0] 6739 = change_address (operands[0], VOIDmode, 6740 copy_to_mode_reg (Pmode, XEXP (operands[0], 0))); 6741}") 6742 6743(define_insn "" 6744 [(call (match_operand:QI 0 "call_insn_operand" "m") 6745 (match_operand:SI 1 "general_operand" "g"))] 6746 ;; Operand 1 not used on the i386. 6747 "" 6748 "* 6749{ 6750 if (GET_CODE (operands[0]) == MEM 6751 && ! CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) 6752 { 6753 operands[0] = XEXP (operands[0], 0); 6754 return AS1 (call,%*%0); 6755 } 6756 else 6757 return AS1 (call,%P0); 6758}") 6759 6760(define_insn "" 6761 [(call (mem:QI (match_operand:SI 0 "symbolic_operand" "")) 6762 (match_operand:SI 1 "general_operand" "g"))] 6763 ;; Operand 1 not used on the i386. 6764 "!HALF_PIC_P ()" 6765 "call %P0") 6766 6767;; Call subroutine, returning value in operand 0 6768;; (which must be a hard register). 6769 6770(define_expand "call_value_pop" 6771 [(parallel [(set (match_operand 0 "" "") 6772 (call (match_operand:QI 1 "indirect_operand" "") 6773 (match_operand:SI 2 "general_operand" ""))) 6774 (set (reg:SI 7) 6775 (plus:SI (reg:SI 7) 6776 (match_operand:SI 4 "immediate_operand" "")))])] 6777 "" 6778 " 6779{ 6780 rtx addr; 6781 6782 if (operands[4] == const0_rtx) 6783 { 6784 emit_insn (gen_call_value (operands[0], operands[1], operands[2])); 6785 DONE; 6786 } 6787 6788 if (flag_pic) 6789 current_function_uses_pic_offset_table = 1; 6790 6791 /* With half-pic, force the address into a register. */ 6792 addr = XEXP (operands[1], 0); 6793 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr)) 6794 XEXP (operands[1], 0) = force_reg (Pmode, addr); 6795 6796 if (! expander_call_insn_operand (operands[1], QImode)) 6797 operands[1] 6798 = change_address (operands[1], VOIDmode, 6799 copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); 6800}") 6801 6802(define_insn "" 6803 [(set (match_operand 0 "" "=rf") 6804 (call (match_operand:QI 1 "call_insn_operand" "m") 6805 (match_operand:SI 2 "general_operand" "g"))) 6806 (set (reg:SI 7) (plus:SI (reg:SI 7) 6807 (match_operand:SI 4 "immediate_operand" "i")))] 6808 "" 6809 "* 6810{ 6811 if (GET_CODE (operands[1]) == MEM 6812 && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) 6813 { 6814 operands[1] = XEXP (operands[1], 0); 6815 output_asm_insn (AS1 (call,%*%1), operands); 6816 } 6817 else 6818 output_asm_insn (AS1 (call,%P1), operands); 6819 6820 RET; 6821}") 6822 6823(define_insn "" 6824 [(set (match_operand 0 "" "=rf") 6825 (call (mem:QI (match_operand:SI 1 "symbolic_operand" "")) 6826 (match_operand:SI 2 "general_operand" "g"))) 6827 (set (reg:SI 7) (plus:SI (reg:SI 7) 6828 (match_operand:SI 4 "immediate_operand" "i")))] 6829 "!HALF_PIC_P ()" 6830 "call %P1") 6831 6832(define_expand "call_value" 6833 [(set (match_operand 0 "" "") 6834 (call (match_operand:QI 1 "indirect_operand" "") 6835 (match_operand:SI 2 "general_operand" "")))] 6836 ;; Operand 2 not used on the i386. 6837 "" 6838 " 6839{ 6840 rtx addr; 6841 6842 if (flag_pic) 6843 current_function_uses_pic_offset_table = 1; 6844 6845 /* With half-pic, force the address into a register. */ 6846 addr = XEXP (operands[1], 0); 6847 if (GET_CODE (addr) != REG && HALF_PIC_P () && !CONSTANT_ADDRESS_P (addr)) 6848 XEXP (operands[1], 0) = force_reg (Pmode, addr); 6849 6850 if (! expander_call_insn_operand (operands[1], QImode)) 6851 operands[1] 6852 = change_address (operands[1], VOIDmode, 6853 copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); 6854}") 6855 6856(define_insn "" 6857 [(set (match_operand 0 "" "=rf") 6858 (call (match_operand:QI 1 "call_insn_operand" "m") 6859 (match_operand:SI 2 "general_operand" "g")))] 6860 ;; Operand 2 not used on the i386. 6861 "" 6862 "* 6863{ 6864 if (GET_CODE (operands[1]) == MEM 6865 && ! CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) 6866 { 6867 operands[1] = XEXP (operands[1], 0); 6868 output_asm_insn (AS1 (call,%*%1), operands); 6869 } 6870 else 6871 output_asm_insn (AS1 (call,%P1), operands); 6872 6873 RET; 6874}") 6875 6876(define_insn "" 6877 [(set (match_operand 0 "" "=rf") 6878 (call (mem:QI (match_operand:SI 1 "symbolic_operand" "")) 6879 (match_operand:SI 2 "general_operand" "g")))] 6880 ;; Operand 2 not used on the i386. 6881 "!HALF_PIC_P ()" 6882 "call %P1") 6883 6884;; Call subroutine returning any type. 6885 6886(define_expand "untyped_call" 6887 [(parallel [(call (match_operand 0 "" "") 6888 (const_int 0)) 6889 (match_operand 1 "" "") 6890 (match_operand 2 "" "")])] 6891 "" 6892 " 6893{ 6894 int i; 6895 6896 /* In order to give reg-stack an easier job in validating two 6897 coprocessor registers as containing a possible return value, 6898 simply pretend the untyped call returns a complex long double 6899 value. */ 6900 6901 emit_call_insn (TARGET_80387 6902 ? gen_call_value (gen_rtx_REG (XCmode, FIRST_FLOAT_REG), 6903 operands[0], const0_rtx) 6904 : gen_call (operands[0], const0_rtx)); 6905 6906 for (i = 0; i < XVECLEN (operands[2], 0); i++) 6907 { 6908 rtx set = XVECEXP (operands[2], 0, i); 6909 emit_move_insn (SET_DEST (set), SET_SRC (set)); 6910 } 6911 6912 /* The optimizer does not know that the call sets the function value 6913 registers we stored in the result block. We avoid problems by 6914 claiming that all hard registers are used and clobbered at this 6915 point. */ 6916 emit_insn (gen_blockage ()); 6917 6918 DONE; 6919}") 6920 6921;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 6922;; all of memory. This blocks insns from being moved across this point. 6923 6924(define_insn "blockage" 6925 [(unspec_volatile [(const_int 0)] 0)] 6926 "" 6927 "" 6928 [(set_attr "memory" "none")]) 6929 6930;; Insn emitted into the body of a function to return from a function. 6931;; This is only done if the function's epilogue is known to be simple. 6932;; See comments for simple_386_epilogue in i386.c. 6933 6934(define_expand "return" 6935 [(return)] 6936 "ix86_can_use_return_insn_p ()" 6937 "") 6938 6939(define_insn "return_internal" 6940 [(return)] 6941 "reload_completed" 6942 "ret" 6943 [(set_attr "memory" "none")]) 6944 6945(define_insn "return_pop_internal" 6946 [(return) 6947 (use (match_operand:SI 0 "const_int_operand" ""))] 6948 "reload_completed" 6949 "ret %0" 6950 [(set_attr "memory" "none")]) 6951 6952(define_insn "nop" 6953 [(const_int 0)] 6954 "" 6955 "nop" 6956 [(set_attr "memory" "none")]) 6957 6958(define_expand "prologue" 6959 [(const_int 1)] 6960 "" 6961 " 6962{ 6963 ix86_expand_prologue (); 6964 DONE; 6965}") 6966 6967;; The use of UNSPEC here is currently not necessary - a simple SET of ebp 6968;; to itself would be enough. But this way we are safe even if some optimizer 6969;; becomes too clever in the future. 6970(define_insn "prologue_set_stack_ptr" 6971 [(set (reg:SI 7) 6972 (minus:SI (reg:SI 7) (match_operand:SI 0 "immediate_operand" "i"))) 6973 (set (reg:SI 6) (unspec:SI [(reg:SI 6)] 4))] 6974 "" 6975 "* 6976{ 6977 rtx xops [2]; 6978 6979 xops[0] = operands[0]; 6980 xops[1] = stack_pointer_rtx; 6981 output_asm_insn (AS2 (sub%L1,%0,%1), xops); 6982 RET; 6983}" 6984 [(set_attr "memory" "none")]) 6985 6986(define_insn "prologue_set_got" 6987 [(set (match_operand:SI 0 "" "") 6988 (unspec_volatile 6989 [(plus:SI (match_dup 0) 6990 (plus:SI (match_operand:SI 1 "symbolic_operand" "") 6991 (minus:SI (pc) (match_operand 2 "" ""))))] 1))] 6992 "" 6993 "* 6994{ 6995 char buffer[64]; 6996 6997 if (TARGET_DEEP_BRANCH_PREDICTION) 6998 { 6999 sprintf (buffer, \"addl %s,%%0\", XSTR (operands[1], 0)); 7000 output_asm_insn (buffer, operands); 7001 } 7002 else 7003 { 7004 sprintf (buffer, \"addl %s+[.-%%X2],%%0\", XSTR (operands[1], 0)); 7005 output_asm_insn (buffer, operands); 7006 } 7007 RET; 7008}") 7009 7010(define_insn "prologue_get_pc" 7011 [(set (match_operand:SI 0 "" "") 7012 (unspec_volatile [(plus:SI (pc) (match_operand 1 "" ""))] 2))] 7013 "" 7014 "* 7015{ 7016 output_asm_insn (AS1 (call,%X1), operands); 7017 if (! TARGET_DEEP_BRANCH_PREDICTION) 7018 { 7019 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (operands[1])); 7020 } 7021 RET; 7022}" 7023 [(set_attr "memory" "none")]) 7024 7025(define_insn "prologue_get_pc_and_set_got" 7026 [(unspec_volatile [(match_operand:SI 0 "" "")] 3)] 7027 "" 7028 "* 7029{ 7030 operands[1] = gen_label_rtx (); 7031 output_asm_insn (AS1 (call,%X1), operands); 7032 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", 7033 CODE_LABEL_NUMBER (operands[1])); 7034 output_asm_insn (AS1 (pop%L0,%0), operands); 7035 output_asm_insn (\"addl $%__GLOBAL_OFFSET_TABLE_+[.-%X1],%0\", operands); 7036 RET; 7037}" 7038 [(set_attr "memory" "none")]) 7039 7040(define_expand "epilogue" 7041 [(const_int 1)] 7042 "" 7043 " 7044{ 7045 ix86_expand_epilogue (); 7046 DONE; 7047}") 7048 7049(define_insn "epilogue_set_stack_ptr" 7050 [(set (reg:SI 7) (reg:SI 6)) 7051 (clobber (reg:SI 6))] 7052 "" 7053 "* 7054{ 7055 rtx xops [2]; 7056 7057 xops[0] = frame_pointer_rtx; 7058 xops[1] = stack_pointer_rtx; 7059 output_asm_insn (AS2 (mov%L0,%0,%1), xops); 7060 RET; 7061}" 7062 [(set_attr "memory" "none")]) 7063 7064(define_insn "leave" 7065 [(const_int 2) 7066 (clobber (reg:SI 6)) 7067 (clobber (reg:SI 7))] 7068 "" 7069 "leave" 7070 [(set_attr "memory" "none")]) 7071 7072(define_insn "pop" 7073 [(set (match_operand:SI 0 "register_operand" "r") 7074 (mem:SI (reg:SI 7))) 7075 (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))] 7076 "" 7077 "* 7078{ 7079 output_asm_insn (AS1 (pop%L0,%P0), operands); 7080 RET; 7081}" 7082 [(set_attr "memory" "load")]) 7083 7084(define_expand "movstrsi" 7085 [(parallel [(set (match_operand:BLK 0 "memory_operand" "") 7086 (match_operand:BLK 1 "memory_operand" "")) 7087 (use (match_operand:SI 2 "const_int_operand" "")) 7088 (use (match_operand:SI 3 "const_int_operand" "")) 7089 (clobber (match_scratch:SI 4 "")) 7090 (clobber (match_dup 5)) 7091 (clobber (match_dup 6))])] 7092 "" 7093 " 7094{ 7095 rtx addr0, addr1; 7096 7097 if (GET_CODE (operands[2]) != CONST_INT) 7098 FAIL; 7099 7100 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); 7101 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); 7102 7103 operands[5] = addr0; 7104 operands[6] = addr1; 7105 7106 operands[0] = change_address (operands[0], VOIDmode, addr0); 7107 operands[1] = change_address (operands[1], VOIDmode, addr1); 7108}") 7109 7110;; It might seem that operands 0 & 1 could use predicate register_operand. 7111;; But strength reduction might offset the MEM expression. So we let 7112;; reload put the address into %edi & %esi. 7113 7114(define_insn "" 7115 [(set (mem:BLK (match_operand:SI 0 "address_operand" "D")) 7116 (mem:BLK (match_operand:SI 1 "address_operand" "S"))) 7117 (use (match_operand:SI 2 "const_int_operand" "n")) 7118 (use (match_operand:SI 3 "immediate_operand" "i")) 7119 (clobber (match_scratch:SI 4 "=&c")) 7120 (clobber (match_dup 0)) 7121 (clobber (match_dup 1))] 7122 "" 7123 "* 7124{ 7125 rtx xops[2]; 7126 7127 output_asm_insn (\"cld\", operands); 7128 if (GET_CODE (operands[2]) == CONST_INT) 7129 { 7130 if (INTVAL (operands[2]) & ~0x03) 7131 { 7132 xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff); 7133 xops[1] = operands[4]; 7134 7135 output_asm_insn (AS2 (mov%L1,%0,%1), xops); 7136#ifdef INTEL_SYNTAX 7137 output_asm_insn (\"rep movsd\", xops); 7138#else 7139 output_asm_insn (\"rep\;movsl\", xops); 7140#endif 7141 } 7142 if (INTVAL (operands[2]) & 0x02) 7143 output_asm_insn (\"movsw\", operands); 7144 if (INTVAL (operands[2]) & 0x01) 7145 output_asm_insn (\"movsb\", operands); 7146 } 7147 else 7148 abort (); 7149 RET; 7150}") 7151 7152(define_expand "clrstrsi" 7153 [(set (match_dup 3) (const_int 0)) 7154 (parallel [(set (match_operand:BLK 0 "memory_operand" "") 7155 (const_int 0)) 7156 (use (match_operand:SI 1 "const_int_operand" "")) 7157 (use (match_operand:SI 2 "const_int_operand" "")) 7158 (use (match_dup 3)) 7159 (clobber (match_scratch:SI 4 "")) 7160 (clobber (match_dup 5))])] 7161 "" 7162 " 7163{ 7164 rtx addr0; 7165 7166 if (GET_CODE (operands[1]) != CONST_INT) 7167 FAIL; 7168 7169 addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0)); 7170 7171 operands[3] = gen_reg_rtx (SImode); 7172 operands[5] = addr0; 7173 7174 operands[0] = gen_rtx_MEM (BLKmode, addr0); 7175}") 7176 7177;; It might seem that operand 0 could use predicate register_operand. 7178;; But strength reduction might offset the MEM expression. So we let 7179;; reload put the address into %edi. 7180 7181(define_insn "*bzero" 7182 [(set (mem:BLK (match_operand:SI 0 "address_operand" "D")) 7183 (const_int 0)) 7184 (use (match_operand:SI 1 "const_int_operand" "n")) 7185 (use (match_operand:SI 2 "immediate_operand" "i")) 7186 (use (match_operand:SI 3 "register_operand" "a")) 7187 (clobber (match_scratch:SI 4 "=&c")) 7188 (clobber (match_dup 0))] 7189 "" 7190 "* 7191{ 7192 rtx xops[2]; 7193 7194 output_asm_insn (\"cld\", operands); 7195 if (GET_CODE (operands[1]) == CONST_INT) 7196 { 7197 unsigned int count = INTVAL (operands[1]) & 0xffffffff; 7198 if (count & ~0x03) 7199 { 7200 xops[0] = GEN_INT (count / 4); 7201 xops[1] = operands[4]; 7202 7203 /* K6: stos takes 1 cycle, rep stos takes 8 + %ecx cycles. 7204 80386: 4/5+5n (+2 for set of ecx) 7205 80486: 5/7+5n (+1 for set of ecx) 7206 */ 7207 if (count / 4 < ((int) ix86_cpu < (int)PROCESSOR_PENTIUM ? 4 : 6)) 7208 { 7209 do 7210#ifdef INTEL_SYNTAX 7211 output_asm_insn (\"stosd\", xops); 7212#else 7213 output_asm_insn (\"stosl\", xops); 7214#endif 7215 while ((count -= 4) > 3); 7216 } 7217 else 7218 { 7219 output_asm_insn (AS2 (mov%L1,%0,%1), xops); 7220#ifdef INTEL_SYNTAX 7221 output_asm_insn (\"rep stosd\", xops); 7222#else 7223 output_asm_insn (\"rep\;stosl\", xops); 7224#endif 7225 } 7226 } 7227 if (INTVAL (operands[1]) & 0x02) 7228 output_asm_insn (\"stosw\", operands); 7229 if (INTVAL (operands[1]) & 0x01) 7230 output_asm_insn (\"stosb\", operands); 7231 } 7232 else 7233 abort (); 7234 RET; 7235}") 7236 7237(define_expand "cmpstrsi" 7238 [(parallel [(set (match_operand:SI 0 "general_operand" "") 7239 (compare:SI (match_operand:BLK 1 "general_operand" "") 7240 (match_operand:BLK 2 "general_operand" ""))) 7241 (use (match_operand:SI 3 "general_operand" "")) 7242 (use (match_operand:SI 4 "immediate_operand" "")) 7243 (clobber (match_dup 5)) 7244 (clobber (match_dup 6)) 7245 (clobber (match_dup 3))])] 7246 "" 7247 " 7248{ 7249 rtx addr1, addr2; 7250 7251 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); 7252 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0)); 7253 operands[3] = copy_to_mode_reg (SImode, operands[3]); 7254 7255 operands[5] = addr1; 7256 operands[6] = addr2; 7257 7258 operands[1] = gen_rtx_MEM (BLKmode, addr1); 7259 operands[2] = gen_rtx_MEM (BLKmode, addr2); 7260 7261}") 7262 7263;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is 7264;; zero. Emit extra code to make sure that a zero-length compare is EQ. 7265 7266;; It might seem that operands 0 & 1 could use predicate register_operand. 7267;; But strength reduction might offset the MEM expression. So we let 7268;; reload put the address into %edi & %esi. 7269 7270;; ??? Most comparisons have a constant length, and it's therefore 7271;; possible to know that the length is non-zero, and to avoid the extra 7272;; code to handle zero-length compares. 7273 7274(define_insn "" 7275 [(set (match_operand:SI 0 "register_operand" "=&r") 7276 (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S")) 7277 (mem:BLK (match_operand:SI 2 "address_operand" "D")))) 7278 (use (match_operand:SI 3 "register_operand" "c")) 7279 (use (match_operand:SI 4 "immediate_operand" "i")) 7280 (clobber (match_dup 1)) 7281 (clobber (match_dup 2)) 7282 (clobber (match_dup 3))] 7283 "" 7284 "* 7285{ 7286 rtx xops[2], label; 7287 7288 label = gen_label_rtx (); 7289 7290 output_asm_insn (\"cld\", operands); 7291 output_asm_insn (AS2 (xor%L0,%0,%0), operands); 7292 output_asm_insn (\"repz\;cmps%B2\", operands); 7293 output_asm_insn (\"je %l0\", &label); 7294 7295 xops[0] = operands[0]; 7296 xops[1] = const1_rtx; 7297 output_asm_insn (AS2 (sbb%L0,%0,%0), xops); 7298 if (QI_REG_P (xops[0])) 7299 output_asm_insn (AS2 (or%B0,%1,%b0), xops); 7300 else 7301 output_asm_insn (AS2 (or%L0,%1,%0), xops); 7302 7303 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label)); 7304 RET; 7305}") 7306 7307(define_insn "" 7308 [(set (cc0) 7309 (compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S")) 7310 (mem:BLK (match_operand:SI 1 "address_operand" "D")))) 7311 (use (match_operand:SI 2 "register_operand" "c")) 7312 (use (match_operand:SI 3 "immediate_operand" "i")) 7313 (clobber (match_dup 0)) 7314 (clobber (match_dup 1)) 7315 (clobber (match_dup 2))] 7316 "" 7317 "* 7318{ 7319 rtx xops[2]; 7320 7321 cc_status.flags |= CC_NOT_SIGNED; 7322 7323 xops[0] = gen_rtx_REG (QImode, 0); 7324 xops[1] = CONST0_RTX (QImode); 7325 7326 output_asm_insn (\"cld\", operands); 7327 output_asm_insn (AS2 (test%B0,%1,%0), xops); 7328 return \"repz\;cmps%B2\"; 7329}") 7330 7331 7332;; Note, you cannot optimize away the branch following the bsfl by assuming 7333;; that the destination is not modified if the input is 0, since not all 7334;; x86 implementations do this. 7335 7336(define_expand "ffssi2" 7337 [(set (match_operand:SI 0 "general_operand" "") 7338 (ffs:SI (match_operand:SI 1 "general_operand" "")))] 7339 "" 7340 " 7341{ 7342 rtx label = gen_label_rtx (), temp = gen_reg_rtx (SImode); 7343 7344 emit_insn (gen_ffssi_1 (temp, operands[1])); 7345 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, SImode, 0, 0); 7346 emit_jump_insn (gen_bne (label)); 7347 emit_move_insn (temp, constm1_rtx); 7348 emit_label (label); 7349 temp = expand_binop (SImode, add_optab, temp, const1_rtx, 7350 operands[0], 0, OPTAB_WIDEN); 7351 7352 if (temp != operands[0]) 7353 emit_move_insn (operands[0], temp); 7354 DONE; 7355}") 7356 7357(define_insn "ffssi_1" 7358 [(set (match_operand:SI 0 "register_operand" "=r") 7359 (unspec:SI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))] 7360 "" 7361 "* return AS2 (bsf%L0,%1,%0);") 7362 7363(define_expand "ffshi2" 7364 [(set (match_operand:SI 0 "general_operand" "") 7365 (ffs:HI (match_operand:HI 1 "general_operand" "")))] 7366 "" 7367 " 7368{ 7369 rtx label = gen_label_rtx (), temp = gen_reg_rtx (HImode); 7370 7371 emit_insn (gen_ffshi_1 (temp, operands[1])); 7372 emit_cmp_insn (operands[1], const0_rtx, NE, NULL_RTX, HImode, 0, 0); 7373 emit_jump_insn (gen_bne (label)); 7374 emit_move_insn (temp, constm1_rtx); 7375 emit_label (label); 7376 temp = expand_binop (HImode, add_optab, temp, const1_rtx, 7377 operands[0], 0, OPTAB_WIDEN); 7378 7379 if (temp != operands[0]) 7380 emit_move_insn (operands[0], temp); 7381 DONE; 7382}") 7383 7384(define_insn "ffshi_1" 7385 [(set (match_operand:HI 0 "register_operand" "=r") 7386 (unspec:HI [(match_operand:SI 1 "nonimmediate_operand" "rm")] 5))] 7387 "" 7388 "* return AS2 (bsf%W0,%1,%0);") 7389 7390;; These patterns match the binary 387 instructions for addM3, subM3, 7391;; mulM3 and divM3. There are three patterns for each of DFmode and 7392;; SFmode. The first is the normal insn, the second the same insn but 7393;; with one operand a conversion, and the third the same insn but with 7394;; the other operand a conversion. 7395 7396(define_insn "" 7397 [(set (match_operand:DF 0 "register_operand" "=f,f") 7398 (match_operator:DF 3 "binary_387_op" 7399 [(match_operand:DF 1 "nonimmediate_operand" "0,fm") 7400 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))] 7401 "TARGET_80387" 7402 "* return output_387_binary_op (insn, operands);" 7403 [(set (attr "type") 7404 (cond [(match_operand:DF 3 "is_mul" "") 7405 (const_string "fpmul") 7406 (match_operand:DF 3 "is_div" "") 7407 (const_string "fpdiv") 7408 ] 7409 (const_string "fpop") 7410 ) 7411 )]) 7412 7413(define_insn "" 7414 [(set (match_operand:XF 0 "register_operand" "=f,f") 7415 (match_operator:XF 3 "binary_387_op" 7416 [(match_operand:XF 1 "register_operand" "0,f") 7417 (match_operand:XF 2 "register_operand" "f,0")]))] 7418 "TARGET_80387" 7419 "* return output_387_binary_op (insn, operands);" 7420 [(set (attr "type") 7421 (cond [(match_operand:DF 3 "is_mul" "") 7422 (const_string "fpmul") 7423 (match_operand:DF 3 "is_div" "") 7424 (const_string "fpdiv") 7425 ] 7426 (const_string "fpop") 7427 ) 7428 )]) 7429 7430(define_insn "" 7431 [(set (match_operand:XF 0 "register_operand" "=f,f") 7432 (match_operator:XF 3 "binary_387_op" 7433 [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0")) 7434 (match_operand:XF 2 "register_operand" "0,f")]))] 7435 "TARGET_80387" 7436 "* return output_387_binary_op (insn, operands);" 7437 [(set (attr "type") 7438 (cond [(match_operand:DF 3 "is_mul" "") 7439 (const_string "fpmul") 7440 (match_operand:DF 3 "is_div" "") 7441 (const_string "fpdiv") 7442 ] 7443 (const_string "fpop") 7444 ) 7445 )]) 7446 7447(define_insn "" 7448 [(set (match_operand:XF 0 "register_operand" "=f,f") 7449 (match_operator:XF 3 "binary_387_op" 7450 [(match_operand:XF 1 "register_operand" "0,f") 7451 (float_extend:XF 7452 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 7453 "TARGET_80387" 7454 "* return output_387_binary_op (insn, operands);" 7455 [(set (attr "type") 7456 (cond [(match_operand:DF 3 "is_mul" "") 7457 (const_string "fpmul") 7458 (match_operand:DF 3 "is_div" "") 7459 (const_string "fpdiv") 7460 ] 7461 (const_string "fpop") 7462 ) 7463 )]) 7464 7465(define_insn "" 7466 [(set (match_operand:DF 0 "register_operand" "=f,f") 7467 (match_operator:DF 3 "binary_387_op" 7468 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0")) 7469 (match_operand:DF 2 "register_operand" "0,f")]))] 7470 "TARGET_80387" 7471 "* return output_387_binary_op (insn, operands);" 7472 [(set (attr "type") 7473 (cond [(match_operand:DF 3 "is_mul" "") 7474 (const_string "fpmul") 7475 (match_operand:DF 3 "is_div" "") 7476 (const_string "fpdiv") 7477 ] 7478 (const_string "fpop") 7479 ) 7480 )]) 7481 7482(define_insn "" 7483 [(set (match_operand:DF 0 "register_operand" "=f,f") 7484 (match_operator:DF 3 "binary_387_op" 7485 [(match_operand:DF 1 "register_operand" "0,f") 7486 (float_extend:DF 7487 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 7488 "TARGET_80387" 7489 "* return output_387_binary_op (insn, operands);" 7490 [(set (attr "type") 7491 (cond [(match_operand:DF 3 "is_mul" "") 7492 (const_string "fpmul") 7493 (match_operand:DF 3 "is_div" "") 7494 (const_string "fpdiv") 7495 ] 7496 (const_string "fpop") 7497 ) 7498 )]) 7499 7500(define_insn "" 7501 [(set (match_operand:SF 0 "register_operand" "=f,f") 7502 (match_operator:SF 3 "binary_387_op" 7503 [(match_operand:SF 1 "nonimmediate_operand" "0,fm") 7504 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))] 7505 "TARGET_80387" 7506 "* return output_387_binary_op (insn, operands);" 7507 [(set (attr "type") 7508 (cond [(match_operand:DF 3 "is_mul" "") 7509 (const_string "fpmul") 7510 (match_operand:DF 3 "is_div" "") 7511 (const_string "fpdiv") 7512 ] 7513 (const_string "fpop") 7514 ) 7515 )]) 7516 7517(define_expand "strlensi" 7518 [(parallel [(set (match_dup 4) 7519 (unspec:SI [(mem:BLK (match_operand:BLK 1 "general_operand" "")) 7520 (match_operand:QI 2 "immediate_operand" "") 7521 (match_operand:SI 3 "immediate_operand" "")] 0)) 7522 (clobber (match_dup 1))]) 7523 (set (match_dup 5) 7524 (not:SI (match_dup 4))) 7525 (set (match_operand:SI 0 "register_operand" "") 7526 (plus:SI (match_dup 5) 7527 (const_int -1)))] 7528 "" 7529 " 7530{ 7531 if (TARGET_UNROLL_STRLEN && operands[2] == const0_rtx && optimize > 1) 7532 { 7533 rtx address; 7534 rtx scratch; 7535 7536 /* well it seems that some optimizer does not combine a call like 7537 foo(strlen(bar), strlen(bar)); 7538 when the move and the subtraction is done here. It does calculate 7539 the length just once when these instructions are done inside of 7540 output_strlen_unroll(). But I think since &bar[strlen(bar)] is 7541 often used and I use one fewer register for the lifetime of 7542 output_strlen_unroll() this is better. */ 7543 scratch = gen_reg_rtx (SImode); 7544 address = force_reg (SImode, XEXP (operands[1], 0)); 7545 7546 /* move address to scratch-register 7547 this is done here because the i586 can do the following and 7548 in the same cycle with the following move. */ 7549 if (GET_CODE (operands[3]) != CONST_INT || INTVAL (operands[3]) < 4) 7550 emit_insn (gen_movsi (scratch, address)); 7551 7552 emit_insn (gen_movsi (operands[0], address)); 7553 7554 if(TARGET_USE_Q_REG) 7555 emit_insn (gen_strlensi_unroll5 (operands[0], 7556 operands[3], 7557 scratch, 7558 operands[0])); 7559 else 7560 emit_insn (gen_strlensi_unroll4 (operands[0], 7561 operands[3], 7562 scratch, 7563 operands[0])); 7564 7565 /* gen_strlensi_unroll[45] returns the address of the zero 7566 at the end of the string, like memchr(), so compute the 7567 length by subtracting the startaddress. */ 7568 emit_insn (gen_subsi3 (operands[0], operands[0], address)); 7569 DONE; 7570 } 7571 7572 operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); 7573 operands[4] = gen_reg_rtx (SImode); 7574 operands[5] = gen_reg_rtx (SImode); 7575}") 7576 7577;; It might seem that operands 0 & 1 could use predicate register_operand. 7578;; But strength reduction might offset the MEM expression. So we let 7579;; reload put the address into %edi. 7580 7581(define_insn "" 7582 [(set (match_operand:SI 0 "register_operand" "=&c") 7583 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D")) 7584 (match_operand:QI 2 "immediate_operand" "a") 7585 (match_operand:SI 3 "immediate_operand" "i")] 0)) 7586 (clobber (match_dup 1))] 7587 "" 7588 "* 7589{ 7590 rtx xops[2]; 7591 7592 xops[0] = operands[0]; 7593 xops[1] = constm1_rtx; 7594 output_asm_insn (\"cld\", operands); 7595 output_asm_insn (AS2 (mov%L0,%1,%0), xops); 7596 return \"repnz\;scas%B2\"; 7597}") 7598 7599/* Conditional move define_insns. */ 7600 7601(define_expand "movsicc" 7602 [(set (match_operand:SI 0 "register_operand" "") 7603 (if_then_else:SI (match_operand 1 "comparison_operator" "") 7604 (match_operand:SI 2 "nonimmediate_operand" "") 7605 (match_operand:SI 3 "nonimmediate_operand" "")))] 7606 "TARGET_CMOVE" 7607 " 7608{ 7609 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT) 7610 FAIL; 7611 7612 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), 7613 GET_MODE (i386_compare_op0), 7614 i386_compare_op0, i386_compare_op1); 7615}") 7616 7617(define_insn "" 7618 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 7619 (if_then_else:SI (match_operator 1 "comparison_operator" 7620 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m") 7621 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")]) 7622 (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0") 7623 (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm")))] 7624 "TARGET_CMOVE" 7625 "#") 7626 7627(define_insn "" 7628 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") 7629 (if_then_else:SI (match_operator 1 "comparison_operator" 7630 [(match_operand 2 "nonimmediate_operand" "r,m,r,m") 7631 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")]) 7632 (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0") 7633 (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm")))] 7634 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT" 7635 "#") 7636 7637(define_split 7638 [(set (match_operand:SI 0 "register_operand" "") 7639 (if_then_else:SI (match_operator 1 "comparison_operator" 7640 [(match_operand 2 "nonimmediate_operand" "") 7641 (const_int 0)]) 7642 (match_operand:SI 3 "nonimmediate_operand" "") 7643 (match_operand:SI 4 "nonimmediate_operand" "")))] 7644 "TARGET_CMOVE && reload_completed" 7645 [(set (cc0) 7646 (match_dup 2)) 7647 (set (match_dup 0) 7648 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) 7649 (match_dup 3) (match_dup 4)))] 7650 "") 7651 7652(define_split 7653 [(set (match_operand:SI 0 "register_operand" "") 7654 (if_then_else:SI (match_operator 1 "comparison_operator" 7655 [(match_operand 2 "nonimmediate_operand" "") 7656 (match_operand 3 "general_operand" "")]) 7657 (match_operand:SI 4 "nonimmediate_operand" "") 7658 (match_operand:SI 5 "nonimmediate_operand" "")))] 7659 "TARGET_CMOVE && reload_completed" 7660 [(set (cc0) (compare (match_dup 2) (match_dup 3))) 7661 (set (match_dup 0) 7662 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) 7663 (match_dup 4) (match_dup 5)))] 7664 "") 7665 7666(define_insn "" 7667 [(set (match_operand:SI 0 "register_operand" "=r,r") 7668 (if_then_else:SI (match_operator 1 "comparison_operator" 7669 [(cc0) (const_int 0)]) 7670 (match_operand:SI 2 "nonimmediate_operand" "rm,0") 7671 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))] 7672 "TARGET_CMOVE && reload_completed" 7673 "* return output_int_conditional_move (which_alternative, operands);") 7674 7675(define_expand "movhicc" 7676 [(set (match_operand:HI 0 "register_operand" "") 7677 (if_then_else:HI (match_operand 1 "comparison_operator" "") 7678 (match_operand:HI 2 "nonimmediate_operand" "") 7679 (match_operand:HI 3 "nonimmediate_operand" "")))] 7680 "TARGET_CMOVE" 7681 " 7682{ 7683 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT) 7684 FAIL; 7685 7686 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), 7687 GET_MODE (i386_compare_op0), 7688 i386_compare_op0, i386_compare_op1); 7689}") 7690 7691(define_insn "" 7692 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") 7693 (if_then_else:HI (match_operator 1 "comparison_operator" 7694 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m") 7695 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")]) 7696 (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0") 7697 (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm")))] 7698 "TARGET_CMOVE" 7699 "#") 7700 7701(define_insn "" 7702 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") 7703 (if_then_else:HI (match_operator 1 "comparison_operator" 7704 [(match_operand 2 "nonimmediate_operand" "r,m,r,m") 7705 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")]) 7706 (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0") 7707 (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm")))] 7708 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT" 7709 "#") 7710 7711(define_split 7712 [(set (match_operand:HI 0 "register_operand" "") 7713 (if_then_else:HI (match_operator 1 "comparison_operator" 7714 [(match_operand 2 "nonimmediate_operand" "") 7715 (const_int 0)]) 7716 (match_operand:HI 3 "nonimmediate_operand" "") 7717 (match_operand:HI 4 "nonimmediate_operand" "")))] 7718 "TARGET_CMOVE && reload_completed" 7719 [(set (cc0) 7720 (match_dup 2)) 7721 (set (match_dup 0) 7722 (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)]) 7723 (match_dup 3) (match_dup 4)))] 7724 "") 7725 7726(define_split 7727 [(set (match_operand:HI 0 "register_operand" "") 7728 (if_then_else:HI (match_operator 1 "comparison_operator" 7729 [(match_operand 2 "nonimmediate_operand" "") 7730 (match_operand 3 "general_operand" "")]) 7731 (match_operand:HI 4 "nonimmediate_operand" "") 7732 (match_operand:HI 5 "nonimmediate_operand" "")))] 7733 "TARGET_CMOVE && reload_completed" 7734 [(set (cc0) 7735 (compare (match_dup 2) (match_dup 3))) 7736 (set (match_dup 0) 7737 (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)]) 7738 (match_dup 4) (match_dup 5)))] 7739 "") 7740 7741(define_insn "" 7742 [(set (match_operand:HI 0 "register_operand" "=r,r") 7743 (if_then_else:HI (match_operator 1 "comparison_operator" 7744 [(cc0) (const_int 0)]) 7745 (match_operand:HI 2 "nonimmediate_operand" "rm,0") 7746 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))] 7747 "TARGET_CMOVE && reload_completed" 7748 "* return output_int_conditional_move (which_alternative, operands);") 7749 7750(define_expand "movsfcc" 7751 [(set (match_operand:SF 0 "register_operand" "") 7752 (if_then_else:SF (match_operand 1 "comparison_operator" "") 7753 (match_operand:SF 2 "register_operand" "") 7754 (match_operand:SF 3 "register_operand" "")))] 7755 "TARGET_CMOVE" 7756 " 7757{ 7758 rtx temp; 7759 7760 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT) 7761 FAIL; 7762 7763 /* The floating point conditional move instructions don't directly 7764 support conditions resulting from a signed integer comparison. */ 7765 7766 switch (GET_CODE (operands[1])) 7767 { 7768 case LT: 7769 case LE: 7770 case GE: 7771 case GT: 7772 temp = emit_store_flag (gen_reg_rtx (QImode), 7773 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1, 7774 VOIDmode, 0, 0); 7775 7776 if (!temp) 7777 FAIL; 7778 7779 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx); 7780 break; 7781 7782 default: 7783 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), 7784 GET_MODE (i386_compare_op0), 7785 i386_compare_op0, i386_compare_op1); 7786 break; 7787 } 7788}") 7789 7790(define_insn "" 7791 [(set (match_operand:SF 0 "register_operand" "=f,f,f,f") 7792 (if_then_else:SF (match_operator 1 "comparison_operator" 7793 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m") 7794 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")]) 7795 (match_operand:SF 4 "register_operand" "f,f,0,0") 7796 (match_operand:SF 5 "register_operand" "0,0,f,f")))] 7797 "TARGET_CMOVE 7798 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE 7799 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT" 7800 "#") 7801 7802(define_insn "" 7803 [(set (match_operand:SF 0 "register_operand" "=f,f,f,f") 7804 (if_then_else:SF (match_operator 1 "comparison_operator" 7805 [(match_operand 2 "nonimmediate_operand" "r,m,r,m") 7806 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")]) 7807 (match_operand:SF 4 "register_operand" "f,f,0,0") 7808 (match_operand:SF 5 "register_operand" "0,0,f,f")))] 7809 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT 7810 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE 7811 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT" 7812 "#") 7813 7814(define_split 7815 [(set (match_operand:SF 0 "register_operand" "") 7816 (if_then_else:SF (match_operator 1 "comparison_operator" 7817 [(match_operand 2 "nonimmediate_operand" "") 7818 (const_int 0)]) 7819 (match_operand:SF 3 "register_operand" "") 7820 (match_operand:SF 4 "register_operand" "")))] 7821 "TARGET_CMOVE && reload_completed" 7822 [(set (cc0) 7823 (match_dup 2)) 7824 (set (match_dup 0) 7825 (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)]) 7826 (match_dup 3) (match_dup 4)))] 7827 "") 7828 7829(define_split 7830 [(set (match_operand:SF 0 "register_operand" "") 7831 (if_then_else:SF (match_operator 1 "comparison_operator" 7832 [(match_operand 2 "nonimmediate_operand" "") 7833 (match_operand 3 "general_operand" "")]) 7834 (match_operand:SF 4 "register_operand" "") 7835 (match_operand:SF 5 "register_operand" "")))] 7836 "TARGET_CMOVE && reload_completed" 7837 [(set (cc0) (compare (match_dup 2) (match_dup 3))) 7838 (set (match_dup 0) 7839 (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)]) 7840 (match_dup 4) (match_dup 5)))] 7841 "") 7842 7843(define_insn "" 7844 [(set (match_operand:SF 0 "register_operand" "=f,f") 7845 (if_then_else:SF (match_operator 1 "comparison_operator" 7846 [(cc0) (const_int 0)]) 7847 (match_operand:SF 2 "register_operand" "f,0") 7848 (match_operand:SF 3 "register_operand" "0,f")))] 7849 "TARGET_CMOVE && reload_completed" 7850 "* return output_fp_conditional_move (which_alternative, operands);") 7851 7852(define_expand "movdfcc" 7853 [(set (match_operand:DF 0 "register_operand" "") 7854 (if_then_else:DF (match_operand 1 "comparison_operator" "") 7855 (match_operand:DF 2 "register_operand" "") 7856 (match_operand:DF 3 "register_operand" "")))] 7857 "TARGET_CMOVE" 7858 " 7859{ 7860 rtx temp; 7861 7862 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT) 7863 FAIL; 7864 7865 /* The floating point conditional move instructions don't directly 7866 support conditions resulting from a signed integer comparison. */ 7867 7868 switch (GET_CODE (operands[1])) 7869 { 7870 case LT: 7871 case LE: 7872 case GE: 7873 case GT: 7874 temp = emit_store_flag (gen_reg_rtx (QImode), 7875 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1, 7876 VOIDmode, 0, 0); 7877 7878 if (!temp) 7879 FAIL; 7880 7881 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx); 7882 break; 7883 7884 default: 7885 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), 7886 GET_MODE (i386_compare_op0), 7887 i386_compare_op0, i386_compare_op1); 7888 break; 7889 } 7890}") 7891 7892(define_insn "" 7893 [(set (match_operand:DF 0 "register_operand" "=f,f,f,f") 7894 (if_then_else:DF (match_operator 1 "comparison_operator" 7895 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m") 7896 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")]) 7897 (match_operand:DF 4 "register_operand" "f,f,0,0") 7898 (match_operand:DF 5 "register_operand" "0,0,f,f")))] 7899 "TARGET_CMOVE 7900 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE 7901 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT" 7902 "#") 7903 7904(define_insn "" 7905 [(set (match_operand:DF 0 "register_operand" "=f,f,f,f") 7906 (if_then_else:DF (match_operator 1 "comparison_operator" 7907 [(match_operand 2 "nonimmediate_operand" "r,m,r,m") 7908 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")]) 7909 (match_operand:DF 4 "register_operand" "f,f,0,0") 7910 (match_operand:DF 5 "register_operand" "0,0,f,f")))] 7911 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT 7912 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE 7913 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT" 7914 "#") 7915 7916(define_split 7917 [(set (match_operand:DF 0 "register_operand" "") 7918 (if_then_else:DF (match_operator 1 "comparison_operator" 7919 [(match_operand 2 "nonimmediate_operand" "") 7920 (const_int 0)]) 7921 (match_operand:DF 3 "register_operand" "") 7922 (match_operand:DF 4 "register_operand" "")))] 7923 "TARGET_CMOVE && reload_completed" 7924 [(set (cc0) 7925 (match_dup 2)) 7926 (set (match_dup 0) 7927 (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)]) 7928 (match_dup 3) (match_dup 4)))] 7929 "") 7930 7931(define_split 7932 [(set (match_operand:DF 0 "register_operand" "") 7933 (if_then_else:DF (match_operator 1 "comparison_operator" 7934 [(match_operand 2 "nonimmediate_operand" "") 7935 (match_operand 3 "general_operand" "")]) 7936 (match_operand:DF 4 "register_operand" "") 7937 (match_operand:DF 5 "register_operand" "")))] 7938 "TARGET_CMOVE && reload_completed" 7939 [(set (cc0) (compare (match_dup 2) (match_dup 3))) 7940 (set (match_dup 0) 7941 (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)]) 7942 (match_dup 4) (match_dup 5)))] 7943 "") 7944 7945(define_insn "" 7946 [(set (match_operand:DF 0 "register_operand" "=f,f") 7947 (if_then_else:DF (match_operator 1 "comparison_operator" 7948 [(cc0) (const_int 0)]) 7949 (match_operand:DF 2 "register_operand" "f,0") 7950 (match_operand:DF 3 "register_operand" "0,f")))] 7951 "TARGET_CMOVE && reload_completed" 7952 "* return output_fp_conditional_move (which_alternative, operands);") 7953 7954(define_expand "movxfcc" 7955 [(set (match_operand:XF 0 "register_operand" "") 7956 (if_then_else:XF (match_operand 1 "comparison_operator" "") 7957 (match_operand:XF 2 "register_operand" "") 7958 (match_operand:XF 3 "register_operand" "")))] 7959 "TARGET_CMOVE" 7960 " 7961{ 7962 rtx temp; 7963 7964 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT) 7965 FAIL; 7966 7967 /* The floating point conditional move instructions don't directly 7968 support conditions resulting from a signed integer comparison. */ 7969 7970 switch (GET_CODE (operands[1])) 7971 { 7972 case LT: 7973 case LE: 7974 case GE: 7975 case GT: 7976 temp = emit_store_flag (gen_reg_rtx (QImode), 7977 GET_CODE (operands[1]), i386_compare_op0, i386_compare_op1, 7978 VOIDmode, 0, 0); 7979 7980 if (!temp) 7981 FAIL; 7982 7983 operands[1] = gen_rtx_fmt_ee (NE, QImode, temp, const0_rtx); 7984 break; 7985 7986 default: 7987 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), 7988 GET_MODE (i386_compare_op0), 7989 i386_compare_op0, i386_compare_op1); 7990 break; 7991 } 7992}") 7993 7994(define_insn "" 7995 [(set (match_operand:XF 0 "register_operand" "=f,f,f,f") 7996 (if_then_else:XF (match_operator 1 "comparison_operator" 7997 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m") 7998 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")]) 7999 (match_operand:XF 4 "register_operand" "f,f,0,0") 8000 (match_operand:XF 5 "register_operand" "0,0,f,f")))] 8001 "TARGET_CMOVE 8002 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE 8003 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT" 8004 "#") 8005 8006(define_insn "" 8007 [(set (match_operand:XF 0 "register_operand" "=f,f,f,f") 8008 (if_then_else:XF (match_operator 1 "comparison_operator" 8009 [(match_operand 2 "nonimmediate_operand" "r,m,r,m") 8010 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")]) 8011 (match_operand:XF 4 "register_operand" "f,f,0,0") 8012 (match_operand:XF 5 "register_operand" "0,0,f,f")))] 8013 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT 8014 && GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != LE 8015 && GET_CODE (operands[1]) != GE && GET_CODE (operands[1]) != GT" 8016 "#") 8017 8018(define_split 8019 [(set (match_operand:XF 0 "register_operand" "") 8020 (if_then_else:XF (match_operator 1 "comparison_operator" 8021 [(match_operand 2 "nonimmediate_operand" "") 8022 (const_int 0)]) 8023 (match_operand:XF 3 "register_operand" "") 8024 (match_operand:XF 4 "register_operand" "")))] 8025 "TARGET_CMOVE && reload_completed" 8026 [(set (cc0) 8027 (match_dup 2)) 8028 (set (match_dup 0) 8029 (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)]) 8030 (match_dup 3) (match_dup 4)))] 8031 "") 8032 8033(define_split 8034 [(set (match_operand:XF 0 "register_operand" "") 8035 (if_then_else:XF (match_operator 1 "comparison_operator" 8036 [(match_operand 2 "nonimmediate_operand" "") 8037 (match_operand 3 "general_operand" "")]) 8038 (match_operand:XF 4 "register_operand" "") 8039 (match_operand:XF 5 "register_operand" "")))] 8040 "TARGET_CMOVE && reload_completed" 8041 [(set (cc0) (compare (match_dup 2) (match_dup 3))) 8042 (set (match_dup 0) 8043 (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)]) 8044 (match_dup 4) (match_dup 5)))] 8045 "") 8046 8047(define_insn "" 8048 [(set (match_operand:XF 0 "register_operand" "=f,f") 8049 (if_then_else:XF (match_operator 1 "comparison_operator" 8050 [(cc0) (const_int 0)]) 8051 (match_operand:XF 2 "register_operand" "f,0") 8052 (match_operand:XF 3 "register_operand" "0,f")))] 8053 "TARGET_CMOVE && reload_completed" 8054 "* return output_fp_conditional_move (which_alternative, operands);") 8055 8056(define_expand "movdicc" 8057 [(set (match_operand:DI 0 "register_operand" "") 8058 (if_then_else:DI (match_operand 1 "comparison_operator" "") 8059 (match_operand:DI 2 "nonimmediate_operand" "") 8060 (match_operand:DI 3 "nonimmediate_operand" "")))] 8061 "TARGET_CMOVE" 8062 " 8063{ 8064 if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT) 8065 FAIL; 8066 8067 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), 8068 GET_MODE (i386_compare_op0), 8069 i386_compare_op0, i386_compare_op1); 8070}") 8071 8072(define_insn "" 8073 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r") 8074 (if_then_else:DI (match_operator 1 "comparison_operator" 8075 [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m") 8076 (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn")]) 8077 (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0") 8078 (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro")))] 8079 "TARGET_CMOVE" 8080 "#") 8081 8082(define_insn "" 8083 [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r") 8084 (if_then_else:DI (match_operator 1 "comparison_operator" 8085 [(match_operand 2 "nonimmediate_operand" "r,m,r,m") 8086 (match_operand 3 "general_operand" "rmi,ri,rmi,ri")]) 8087 (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0") 8088 (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro")))] 8089 "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT" 8090 "#") 8091 8092(define_split 8093 [(set (match_operand:DI 0 "register_operand" "") 8094 (if_then_else:DI (match_operator 1 "comparison_operator" 8095 [(match_operand 2 "nonimmediate_operand" "") 8096 (const_int 0)]) 8097 (match_operand:DI 3 "nonimmediate_operand" "") 8098 (match_operand:DI 4 "nonimmediate_operand" "")))] 8099 "TARGET_CMOVE && reload_completed" 8100 [(set (cc0) 8101 (match_dup 2)) 8102 (set (match_dup 5) 8103 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) 8104 (match_dup 7) (match_dup 9))) 8105 (set (match_dup 6) 8106 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) 8107 (match_dup 8) (match_dup 10)))] 8108 "split_di (&operands[0], 1, &operands[5], &operands[6]); 8109 split_di (&operands[3], 1, &operands[7], &operands[8]); 8110 split_di (&operands[4], 1, &operands[9], &operands[10]);") 8111 8112(define_split 8113 [(set (match_operand:DI 0 "register_operand" "") 8114 (if_then_else:DI (match_operator 1 "comparison_operator" 8115 [(match_operand 2 "nonimmediate_operand" "") 8116 (match_operand 3 "general_operand" "")]) 8117 (match_operand:DI 4 "nonimmediate_operand" "") 8118 (match_operand:DI 5 "nonimmediate_operand" "")))] 8119 "TARGET_CMOVE && reload_completed" 8120 [(set (cc0) (compare (match_dup 2) (match_dup 3))) 8121 (set (match_dup 6) 8122 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) 8123 (match_dup 8) (match_dup 10))) 8124 (set (match_dup 7) 8125 (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) 8126 (match_dup 9) (match_dup 11)))] 8127 "split_di (&operands[0], 1, &operands[6], &operands[7]); 8128 split_di (&operands[4], 1, &operands[8], &operands[9]); 8129 split_di (&operands[5], 1, &operands[10], &operands[11]);") 8130 8131(define_insn "strlensi_unroll" 8132 [(set (match_operand:SI 0 "register_operand" "=&r,&r") 8133 (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "r,r")) 8134 (match_operand:SI 2 "immediate_operand" "i,i")] 0)) 8135 (clobber (match_scratch:SI 3 "=&q,&r"))] 8136 "optimize > 1" 8137 "* return output_strlen_unroll (operands);") 8138 8139;; the only difference between the following patterns is the register preference 8140;; on a pentium using a q-register saves one clock cycle per 4 characters 8141 8142(define_insn "strlensi_unroll4" 8143 [(set (match_operand:SI 0 "register_operand" "=r,r") 8144 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0,0")) 8145 (match_operand:SI 1 "immediate_operand" "i,i") 8146 (match_operand:SI 2 "register_operand" "+q,!r")] 0)) 8147 (clobber (match_dup 2))] 8148 "(TARGET_USE_ANY_REG && optimize > 1)" 8149 "* return output_strlen_unroll (operands);") 8150 8151(define_insn "strlensi_unroll5" 8152 [(set (match_operand:SI 0 "register_operand" "=r") 8153 (unspec:SI [(mem:BLK (match_operand:SI 3 "register_operand" "0")) 8154 (match_operand:SI 1 "immediate_operand" "i") 8155 (match_operand:SI 2 "register_operand" "+q")] 0)) 8156 (clobber (match_dup 2))] 8157 "(TARGET_USE_Q_REG && optimize > 1)" 8158 "* return output_strlen_unroll (operands);" 8159) 8160 8161(define_insn "allocate_stack_worker" 8162 [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] 3) 8163 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0))) 8164 (clobber (match_dup 0))] 8165 "TARGET_STACK_PROBE" 8166 "* return AS1(call,__alloca);" 8167 [(set_attr "memory" "none")]) 8168 8169(define_expand "allocate_stack" 8170 [(set (match_operand:SI 0 "register_operand" "=r") 8171 (minus:SI (reg:SI 7) (match_operand:SI 1 "general_operand" ""))) 8172 (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 1)))] 8173 "TARGET_STACK_PROBE" 8174 " 8175{ 8176#ifdef CHECK_STACK_LIMIT 8177 if (GET_CODE (operands[1]) == CONST_INT 8178 && INTVAL (operands[1]) < CHECK_STACK_LIMIT) 8179 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, 8180 operands[1])); 8181 else 8182#endif 8183 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode, 8184 operands[1]))); 8185 8186 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 8187 DONE; 8188}") 8189 8190(define_expand "exception_receiver" 8191 [(const_int 0)] 8192 "flag_pic" 8193 " 8194{ 8195 load_pic_register (1); 8196 DONE; 8197}") 8198