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