1;;- Machine description for Intel 860 chip for GNU C compiler 2;; Copyright (C) 1989, 1990, 1997 Free Software Foundation, Inc. 3 4;; This file is part of GNU CC. 5 6;; GNU CC is free software; you can redistribute it and/or modify 7;; it under the terms of the GNU General Public License as published by 8;; the Free Software Foundation; either version 2, or (at your option) 9;; any later version. 10 11;; GNU CC is distributed in the hope that it will be useful, 12;; but WITHOUT ANY WARRANTY; without even the implied warranty of 13;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14;; GNU General Public License for more details. 15 16;; You should have received a copy of the GNU General Public License 17;; along with GNU CC; see the file COPYING. If not, write to 18;; the Free Software Foundation, 59 Temple Place - Suite 330, 19;; Boston, MA 02111-1307, USA. 20 21 22;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 23 24;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code 25;;- updates for most instructions. 26 27;;- Operand classes for the register allocator: 28 29/* Bit-test instructions. */ 30 31(define_insn "" 32 [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r") 33 (match_operand:SI 1 "logic_operand" "rL")) 34 (const_int 0)))] 35 "" 36 "* 37{ 38 CC_STATUS_PARTIAL_INIT; 39 return \"and %1,%0,%?r0\"; 40}") 41 42(define_insn "" 43 [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r") 44 (match_operand:SI 1 "logic_operand" "rL")) 45 (const_int 0)))] 46 "" 47 "* 48{ 49 CC_STATUS_PARTIAL_INIT; 50 cc_status.flags |= CC_NEGATED; 51 return \"and %1,%0,%?r0\"; 52}") 53 54(define_insn "" 55 [(set (cc0) (eq (and:SI (match_operand:SI 0 "register_operand" "r") 56 (match_operand:SI 1 "immediate_operand" "i")) 57 (const_int 0)))] 58 "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0" 59 "* 60{ 61 CC_STATUS_PARTIAL_INIT; 62 return \"andh %H1,%0,%?r0\"; 63}") 64 65(define_insn "" 66 [(set (cc0) (ne (and:SI (match_operand:SI 0 "register_operand" "r") 67 (match_operand:SI 1 "immediate_operand" "i")) 68 (const_int 0)))] 69 "GET_CODE (operands[1]) == CONST_INT && (INTVAL (operands[1]) & 0xffff) == 0" 70 "* 71{ 72 CC_STATUS_PARTIAL_INIT; 73 cc_status.flags |= CC_NEGATED; 74 return \"andh %H1,%0,%?r0\"; 75}") 76 77(define_insn "" 78 [(set (cc0) (eq (ashiftrt:SI 79 (sign_extend:SI 80 (ashift:QI (match_operand:QI 0 "register_operand" "r") 81 (match_operand:QI 1 "logic_int" "n"))) 82 (match_operand:SI 2 "logic_int" "n")) 83 (const_int 0)))] 84 "" 85 "* 86{ 87 int width = 8 - INTVAL (operands[2]); 88 int pos = 8 - width - INTVAL (operands[1]); 89 90 CC_STATUS_PARTIAL_INIT; 91 operands[2] = GEN_INT (~((-1) << width) << pos); 92 return \"and %2,%0,%?r0\"; 93}") 94 95;; ------------------------------------------------------------------------- 96;; SImode signed integer comparisons 97;; ------------------------------------------------------------------------- 98 99(define_insn "cmpeqsi" 100 [(set (cc0) (eq (match_operand:SI 0 "logic_operand" "r,rL") 101 (match_operand:SI 1 "logic_operand" "L,r")))] 102 "" 103 "* 104{ 105 CC_STATUS_PARTIAL_INIT; 106 if (REG_P (operands[0])) 107 return \"xor %1,%0,%?r0\"; 108 else 109 return \"xor %0,%1,%?r0\"; 110}") 111 112(define_insn "cmpnesi" 113 [(set (cc0) (ne (match_operand:SI 0 "logic_operand" "r,rL") 114 (match_operand:SI 1 "logic_operand" "L,r")))] 115 "" 116 "* 117{ 118 CC_STATUS_PARTIAL_INIT; 119 cc_status.flags |= CC_NEGATED; 120 if (REG_P (operands[0])) 121 return \"xor %1,%0,%?r0\"; 122 else 123 return \"xor %0,%1,%?r0\"; 124}") 125 126(define_insn "cmpltsi" 127 [(set (cc0) (lt (match_operand:SI 0 "arith_operand" "r,rI") 128 (match_operand:SI 1 "arith_operand" "I,r")))] 129 "" 130 "* 131{ 132 CC_STATUS_PARTIAL_INIT; 133 if (REG_P (operands[1])) 134 return \"subs %0,%1,%?r0\"; 135 else 136 { 137 cc_status.flags |= CC_REVERSED; 138 operands[1] = GEN_INT (- INTVAL (operands[1])); 139 return \"adds %1,%0,%?r0\"; 140 } 141}") 142 143(define_insn "cmpgtsi" 144 [(set (cc0) (gt (match_operand:SI 0 "arith_operand" "r,rI") 145 (match_operand:SI 1 "arith_operand" "I,r")))] 146 "" 147 "* 148{ 149 CC_STATUS_PARTIAL_INIT; 150 if (REG_P (operands[0])) 151 return \"subs %1,%0,%?r0\"; 152 else 153 { 154 cc_status.flags |= CC_REVERSED; 155 operands[0] = GEN_INT (- INTVAL (operands[0])); 156 return \"adds %0,%1,%?r0\"; 157 } 158}") 159 160(define_insn "cmplesi" 161 [(set (cc0) (le (match_operand:SI 0 "arith_operand" "r,rI") 162 (match_operand:SI 1 "arith_operand" "I,r")))] 163 "" 164 "* 165{ 166 CC_STATUS_PARTIAL_INIT; 167 cc_status.flags |= CC_NEGATED; 168 if (REG_P (operands[0])) 169 return \"subs %1,%0,%?r0\"; 170 else 171 { 172 cc_status.flags |= CC_REVERSED; 173 operands[0] = GEN_INT (- INTVAL (operands[0])); 174 return \"adds %0,%1,%?r0\"; 175 } 176}") 177 178(define_insn "cmpgesi" 179 [(set (cc0) (ge (match_operand:SI 0 "arith_operand" "r,rI") 180 (match_operand:SI 1 "arith_operand" "I,r")))] 181 "" 182 "* 183{ 184 CC_STATUS_PARTIAL_INIT; 185 cc_status.flags |= CC_NEGATED; 186 if (REG_P (operands[1])) 187 return \"subs %0,%1,%?r0\"; 188 else 189 { 190 cc_status.flags |= CC_REVERSED; 191 operands[1] = GEN_INT (- INTVAL (operands[1])); 192 return \"adds %1,%0,%?r0\"; 193 } 194}") 195 196;; ------------------------------------------------------------------------- 197;; SImode unsigned integer comparisons 198;; ------------------------------------------------------------------------- 199 200;; WARNING! There is a small i860 hardware limitation (bug?) which we 201;; may run up against (if we are not careful) when we are trying to do 202;; unsigned comparisons like (x >= 0), (x < 0), (0 <= x), and (0 > x). 203;; Specifically, we must avoid using an `addu' instruction to perform 204;; such comparisons because the result (in the CC bit register) will 205;; come out wrong. (This fact is documented in a footnote on page 7-10 206;; of the 1991 version of the i860 Microprocessor Family Programmer's 207;; Reference Manual). Note that unsigned comparisons of this sort are 208;; always redundant anyway, because an unsigned quantity can never be 209;; less than zero. When we see cases like this, we generate an 210;; `or K,%r0,%r0' instruction instead (where K is a constant 0 or -1) 211;; so as to get the CC bit register set properly for any subsequent 212;; conditional jump instruction. 213 214(define_insn "cmpgeusi" 215 [(set (cc0) (geu (match_operand:SI 0 "arith_operand" "r,rI") 216 (match_operand:SI 1 "arith_operand" "I,r")))] 217 "" 218 "* 219{ 220 CC_STATUS_PARTIAL_INIT; 221 if (REG_P (operands[1])) 222 return \"subu %0,%1,%?r0\"; 223 else 224 { 225 if (INTVAL (operands[1]) == 0) 226 return \"or 0,%?r0,%?r0\"; 227 else 228 { 229 cc_status.flags |= CC_REVERSED; 230 operands[1] = GEN_INT (- INTVAL (operands[1])); 231 return \"addu %1,%0,%?r0\"; 232 } 233 } 234}") 235 236(define_insn "cmpleusi" 237 [(set (cc0) (leu (match_operand:SI 0 "arith_operand" "r,rI") 238 (match_operand:SI 1 "arith_operand" "I,r")))] 239 "" 240 "* 241{ 242 CC_STATUS_PARTIAL_INIT; 243 if (REG_P (operands[0])) 244 return \"subu %1,%0,%?r0\"; 245 else 246 { 247 if (INTVAL (operands[0]) == 0) 248 return \"or 0,%?r0,%?r0\"; 249 else 250 { 251 cc_status.flags |= CC_REVERSED; 252 operands[0] = GEN_INT (- INTVAL (operands[0])); 253 return \"addu %0,%1,%?r0\"; 254 } 255 } 256}") 257 258;; ------------------------------------------------------------------------- 259;; SFmode floating-point comparisons 260;; ------------------------------------------------------------------------- 261 262(define_insn "cmpeqsf" 263 [(set (cc0) (eq (match_operand:SF 0 "reg_or_0_operand" "fG") 264 (match_operand:SF 1 "reg_or_0_operand" "fG")))] 265 "" 266 "* 267{ 268 CC_STATUS_PARTIAL_INIT; 269 return \"pfeq.ss %r0,%r1,%?f0\"; 270}") 271 272(define_insn "cmpnesf" 273 [(set (cc0) (ne (match_operand:SF 0 "reg_or_0_operand" "fG") 274 (match_operand:SF 1 "reg_or_0_operand" "fG")))] 275 "" 276 "* 277{ 278 CC_STATUS_PARTIAL_INIT; 279 cc_status.flags |= CC_NEGATED; 280 return \"pfeq.ss %r1,%r0,%?f0\"; 281}") 282 283;; NOTE: The i860 Programmer's Reference Manual says that when we are 284;; doing (A < B) or (A > B) comparisons, we have to use pfgt for these 285;; in order to be IEEE compliant (in case a trap occurs during these 286;; operations). Conversely, for (A <= B) or (A >= B) comparisons, we 287;; must use pfle to be IEEE compliant. 288 289(define_insn "cmpltsf" 290 [(set (cc0) (lt (match_operand:SF 0 "reg_or_0_operand" "fG") 291 (match_operand:SF 1 "reg_or_0_operand" "fG")))] 292 "" 293 "* 294{ 295 CC_STATUS_PARTIAL_INIT; 296 return \"pfgt.ss %r1,%r0,%?f0\"; 297}") 298 299(define_insn "cmpgtsf" 300 [(set (cc0) (gt (match_operand:SF 0 "reg_or_0_operand" "fG") 301 (match_operand:SF 1 "reg_or_0_operand" "fG")))] 302 "" 303 "* 304{ 305 CC_STATUS_PARTIAL_INIT; 306 return \"pfgt.ss %r0,%r1,%?f0\"; 307}") 308 309;; NOTE: The pfle opcode doesn't do what you think it does. It is 310;; bass-ackwards. It *clears* the CC flag if the first operand is 311;; less than or equal to the second. Thus, we have to set CC_NEGATED 312;; for the following two patterns. 313 314(define_insn "cmplesf" 315 [(set (cc0) (le (match_operand:SF 0 "reg_or_0_operand" "fG") 316 (match_operand:SF 1 "reg_or_0_operand" "fG")))] 317 "" 318 "* 319{ 320 CC_STATUS_PARTIAL_INIT; 321 cc_status.flags |= CC_NEGATED; 322 return \"pfle.ss %r0,%r1,%?f0\"; 323}") 324 325(define_insn "cmpgesf" 326 [(set (cc0) (ge (match_operand:SF 0 "reg_or_0_operand" "fG") 327 (match_operand:SF 1 "reg_or_0_operand" "fG")))] 328 "" 329 "* 330{ 331 CC_STATUS_PARTIAL_INIT; 332 cc_status.flags |= CC_NEGATED; 333 return \"pfle.ss %r1,%r0,%?f0\"; 334}") 335 336;; ------------------------------------------------------------------------- 337;; DFmode floating-point comparisons 338;; ------------------------------------------------------------------------- 339 340(define_insn "cmpeqdf" 341 [(set (cc0) (eq (match_operand:DF 0 "reg_or_0_operand" "fG") 342 (match_operand:DF 1 "reg_or_0_operand" "fG")))] 343 "" 344 "* 345{ 346 CC_STATUS_PARTIAL_INIT; 347 return \"pfeq.dd %r0,%r1,%?f0\"; 348}") 349 350(define_insn "cmpnedf" 351 [(set (cc0) (ne (match_operand:DF 0 "reg_or_0_operand" "fG") 352 (match_operand:DF 1 "reg_or_0_operand" "fG")))] 353 "" 354 "* 355{ 356 CC_STATUS_PARTIAL_INIT; 357 cc_status.flags |= CC_NEGATED; 358 return \"pfeq.dd %r1,%r0,%?f0\"; 359}") 360 361;; NOTE: The i860 Programmer's Reference Manual says that when we are 362;; doing (A < B) or (A > B) comparisons, we have to use pfgt for these 363;; in order to be IEEE compliant (in case a trap occurs during these 364;; operations). Conversely, for (A <= B) or (A >= B) comparisons, we 365;; must use pfle to be IEEE compliant. 366 367(define_insn "cmpltdf" 368 [(set (cc0) (lt (match_operand:DF 0 "reg_or_0_operand" "fG") 369 (match_operand:DF 1 "reg_or_0_operand" "fG")))] 370 "" 371 "* 372{ 373 CC_STATUS_PARTIAL_INIT; 374 return \"pfgt.dd %r1,%r0,%?f0\"; 375}") 376 377(define_insn "cmpgtdf" 378 [(set (cc0) (gt (match_operand:DF 0 "reg_or_0_operand" "fG") 379 (match_operand:DF 1 "reg_or_0_operand" "fG")))] 380 "" 381 "* 382{ 383 CC_STATUS_PARTIAL_INIT; 384 return \"pfgt.dd %r0,%r1,%?f0\"; 385}") 386 387;; NOTE: The pfle opcode doesn't do what you think it does. It is 388;; bass-ackwards. It *clears* the CC flag if the first operand is 389;; less than or equal to the second. Thus, we have to set CC_NEGATED 390;; for the following two patterns. 391 392(define_insn "cmpledf" 393 [(set (cc0) (le (match_operand:DF 0 "reg_or_0_operand" "fG") 394 (match_operand:DF 1 "reg_or_0_operand" "fG")))] 395 "" 396 "* 397{ 398 CC_STATUS_PARTIAL_INIT; 399 cc_status.flags |= CC_NEGATED; 400 return \"pfle.dd %r0,%r1,%?f0\"; 401}") 402 403(define_insn "cmpgedf" 404 [(set (cc0) (ge (match_operand:DF 0 "reg_or_0_operand" "fG") 405 (match_operand:DF 1 "reg_or_0_operand" "fG")))] 406 "" 407 "* 408{ 409 CC_STATUS_PARTIAL_INIT; 410 cc_status.flags |= CC_NEGATED; 411 return \"pfle.dd %r1,%r0,%?f0\"; 412}") 413 414;; ------------------------------------------------------------------------ 415;; Integer EQ/NE comparisons against constant values which will fit in the 416;; 16-bit immediate field of an instruction. These are made by combining. 417;; ------------------------------------------------------------------------ 418 419(define_insn "" 420 [(set (cc0) (eq (zero_extend:SI (match_operand:HI 0 "load_operand" "m")) 421 (match_operand:SI 1 "small_int" "I")))] 422 "INTVAL (operands[1]) >= 0" 423 "* 424{ 425 CC_STATUS_PARTIAL_INIT; 426 return \"ld.s %0,%?r31\;xor %1,%?r31,%?r0\"; 427}") 428 429(define_insn "" 430 [(set (cc0) (eq (match_operand:SI 0 "small_int" "I") 431 (zero_extend:SI (match_operand:HI 1 "load_operand" "m"))))] 432 "INTVAL (operands[0]) >= 0" 433 "* 434{ 435 CC_STATUS_PARTIAL_INIT; 436 return \"ld.s %1,%?r31\;xor %0,%?r31,%?r0\"; 437}") 438 439;; ------------------------------------------------------------------------ 440;; Define the real conditional branch instructions. 441;; ------------------------------------------------------------------------ 442 443(define_insn "cbranch" 444 [(set (pc) (if_then_else (eq (cc0) (const_int 0)) 445 (label_ref (match_operand 0 "" "")) 446 (pc)))] 447 "" 448 "* 449{ 450 if ((cc_prev_status.flags & CC_NEGATED) == 0) 451 return \"bnc %l0\"; 452 else 453 return \"bc %l0\"; 454}") 455 456(define_insn "flipped_cbranch" 457 [(set (pc) (if_then_else (ne (cc0) 458 (const_int 0)) 459 (pc) 460 (label_ref (match_operand 0 "" ""))))] 461 "" 462 "* 463{ 464 if ((cc_prev_status.flags & CC_NEGATED) == 0) 465 return \"bnc %l0\"; 466 else 467 return \"bc %l0\"; 468}") 469 470(define_insn "inverse_cbranch" 471 [(set (pc) (if_then_else (eq (cc0) 472 (const_int 0)) 473 (pc) 474 (label_ref (match_operand 0 "" ""))))] 475 "" 476 "* 477{ 478 if ((cc_prev_status.flags & CC_NEGATED) == 0) 479 return \"bc %l0\"; 480 else 481 return \"bnc %l0\"; 482}") 483 484 485(define_insn "flipped_inverse_cbranch" 486 [(set (pc) (if_then_else (ne (cc0) 487 (const_int 0)) 488 (label_ref (match_operand 0 "" "")) 489 (pc)))] 490 "" 491 "* 492{ 493 if ((cc_prev_status.flags & CC_NEGATED) == 0) 494 return \"bc %l0\"; 495 else 496 return \"bnc %l0\"; 497}") 498 499;; Simple BTE/BTNE compare-and-branch insns made by combining. 500;; Note that it is wrong to add similar patterns for QI or HImode 501;; because bte/btne always compare the whole register. 502 503(define_insn "" 504 [(set (pc) 505 (if_then_else (eq (match_operand:SI 0 "register_operand" "r") 506 (match_operand:SI 1 "bte_operand" "rK")) 507 (label_ref (match_operand 2 "" "")) 508 (pc)))] 509 "" 510 "bte %1,%0,%2") 511 512(define_insn "" 513 [(set (pc) 514 (if_then_else (ne (match_operand:SI 0 "register_operand" "r") 515 (match_operand:SI 1 "bte_operand" "rK")) 516 (label_ref (match_operand 2 "" "")) 517 (pc)))] 518 "" 519 "btne %1,%0,%2") 520 521(define_insn "" 522 [(set (pc) 523 (if_then_else (eq (match_operand:SI 0 "register_operand" "r") 524 (match_operand:SI 1 "bte_operand" "rK")) 525 (pc) 526 (label_ref (match_operand 2 "" ""))))] 527 "" 528 "btne %1,%0,%2") 529 530(define_insn "" 531 [(set (pc) 532 (if_then_else (ne (match_operand:SI 0 "register_operand" "r") 533 (match_operand:SI 1 "bte_operand" "rK")) 534 (pc) 535 (label_ref (match_operand 2 "" ""))))] 536 "" 537 "bte %1,%0,%2") 538 539;; Load byte/halfword, zero-extend, & compare-and-branch insns. 540;; These are made by combining. 541 542(define_insn "" 543 [(set (pc) 544 (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "memory_operand" "m")) 545 (match_operand:SI 1 "bte_operand" "K")) 546 (label_ref (match_operand 2 "" "")) 547 (pc))) 548 (match_scratch:SI 3 "=r")] 549 "" 550 "ld.b %0,%3;bte %1,%3,%2") 551 552(define_insn "" 553 [(set (pc) 554 (if_then_else (ne (zero_extend:SI (match_operand:QI 0 "memory_operand" "m")) 555 (match_operand:SI 1 "bte_operand" "K")) 556 (label_ref (match_operand 2 "" "")) 557 (pc))) 558 (match_scratch:SI 3 "=r")] 559 "" 560 "ld.b %0,%3;btne %1,%3,%2") 561 562(define_insn "" 563 [(set (pc) 564 (if_then_else (eq (zero_extend:SI (match_operand:QI 0 "memory_operand" "m")) 565 (match_operand:SI 1 "bte_operand" "K")) 566 (pc) 567 (label_ref (match_operand 2 "" "")))) 568 (match_scratch:SI 3 "=r")] 569 "" 570 "ld.b %0,%3;btne %1,%3,%2") 571 572(define_insn "" 573 [(set (pc) 574 (if_then_else (ne (zero_extend:SI (match_operand:QI 0 "memory_operand" "m")) 575 (match_operand:SI 1 "bte_operand" "K")) 576 (pc) 577 (label_ref (match_operand 2 "" "")))) 578 (match_scratch:SI 3 "=r")] 579 "" 580 "ld.b %0,%3;bte %1,%3,%2") 581 582(define_insn "" 583 [(set (pc) 584 (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "memory_operand" "m")) 585 (match_operand:SI 1 "bte_operand" "K")) 586 (label_ref (match_operand 2 "" "")) 587 (pc))) 588 (match_scratch:SI 3 "=r")] 589 "" 590 "ld.s %0,%3;bte %1,%3,%2") 591 592(define_insn "" 593 [(set (pc) 594 (if_then_else (ne (zero_extend:SI (match_operand:HI 0 "memory_operand" "m")) 595 (match_operand:SI 1 "bte_operand" "K")) 596 (label_ref (match_operand 2 "" "")) 597 (pc))) 598 (match_scratch:SI 3 "=r")] 599 "" 600 "ld.s %0,%3;btne %1,%3,%2") 601 602(define_insn "" 603 [(set (pc) 604 (if_then_else (eq (zero_extend:SI (match_operand:HI 0 "memory_operand" "m")) 605 (match_operand:SI 1 "bte_operand" "K")) 606 (pc) 607 (label_ref (match_operand 2 "" "")))) 608 (match_scratch:SI 3 "=r")] 609 "" 610 "ld.s %0,%3;btne %1,%3,%2") 611 612(define_insn "" 613 [(set (pc) 614 (if_then_else (ne (zero_extend:SI (match_operand:HI 0 "memory_operand" "m")) 615 (match_operand:SI 1 "bte_operand" "K")) 616 (pc) 617 (label_ref (match_operand 2 "" "")))) 618 (match_scratch:SI 3 "=r")] 619 "" 620 "ld.s %0,%3;bte %1,%3,%2") 621 622 623;; Generation of conditionals. 624 625;; We save the compare operands in the cmpxx patterns and use then when 626;; we generate the branch. 627 628(define_expand "cmpsi" 629 [(set (cc0) (compare (match_operand:SI 0 "register_operand" "") 630 (match_operand:SI 1 "compare_operand" "")))] 631 "" 632 " 633{ i860_compare_op0 = operands[0]; 634 i860_compare_op1 = operands[1]; 635 DONE; 636}") 637 638(define_expand "cmpsf" 639 [(set (cc0) (compare (match_operand:SF 0 "register_operand" "") 640 (match_operand:SF 1 "register_operand" "")))] 641 "" 642 " 643{ i860_compare_op0 = operands[0]; 644 i860_compare_op1 = operands[1]; 645 DONE; 646}") 647 648(define_expand "cmpdf" 649 [(set (cc0) (compare (match_operand:DF 0 "register_operand" "") 650 (match_operand:DF 1 "register_operand" "")))] 651 "" 652 " 653{ i860_compare_op0 = operands[0]; 654 i860_compare_op1 = operands[1]; 655 DONE; 656}") 657 658;; These are the standard-named conditional branch patterns. 659;; Detailed comments are found in the first one only. 660 661(define_expand "beq" 662 [(set (pc) 663 (if_then_else (eq (cc0) 664 (const_int 0)) 665 (label_ref (match_operand 0 "" "")) 666 (pc)))] 667 "" 668 " 669{ 670 /* Emit a single-condition compare insn according to 671 the type of operands and the condition to be tested. */ 672 673 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT) 674 emit_insn (gen_cmpeqsi (i860_compare_op0, i860_compare_op1)); 675 else if (GET_MODE (i860_compare_op0) == SFmode) 676 emit_insn (gen_cmpeqsf (i860_compare_op0, i860_compare_op1)); 677 else if (GET_MODE (i860_compare_op0) == DFmode) 678 emit_insn (gen_cmpeqdf (i860_compare_op0, i860_compare_op1)); 679 else 680 abort (); 681 682 /* Emit branch-if-true. */ 683 684 emit_jump_insn (gen_flipped_inverse_cbranch (operands[0])); 685 DONE; 686}") 687 688(define_expand "bne" 689 [(set (pc) 690 (if_then_else (ne (cc0) 691 (const_int 0)) 692 (label_ref (match_operand 0 "" "")) 693 (pc)))] 694 "" 695 " 696{ 697 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT) 698 emit_insn (gen_cmpeqsi (i860_compare_op0, i860_compare_op1)); 699 else if (GET_MODE (i860_compare_op0) == SFmode) 700 emit_insn (gen_cmpeqsf (i860_compare_op0, i860_compare_op1)); 701 else if (GET_MODE (i860_compare_op0) == DFmode) 702 emit_insn (gen_cmpeqdf (i860_compare_op0, i860_compare_op1)); 703 else 704 abort (); 705 706 emit_jump_insn (gen_flipped_cbranch (operands[0])); 707 708 DONE; 709}") 710 711(define_expand "bgt" 712 [(set (pc) 713 (if_then_else (gt (cc0) 714 (const_int 0)) 715 (label_ref (match_operand 0 "" "")) 716 (pc)))] 717 "" 718 " 719{ 720 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT) 721 emit_insn (gen_cmpgtsi (i860_compare_op0, i860_compare_op1)); 722 else if (GET_MODE (i860_compare_op0) == SFmode) 723 emit_insn (gen_cmpgtsf (i860_compare_op0, i860_compare_op1)); 724 else if (GET_MODE (i860_compare_op0) == DFmode) 725 emit_insn (gen_cmpgtdf (i860_compare_op0, i860_compare_op1)); 726 else 727 abort (); 728 729 emit_jump_insn (gen_flipped_inverse_cbranch (operands[0])); 730 DONE; 731}") 732 733(define_expand "blt" 734 [(set (pc) 735 (if_then_else (lt (cc0) 736 (const_int 0)) 737 (label_ref (match_operand 0 "" "")) 738 (pc)))] 739 "" 740 " 741{ 742 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT) 743 emit_insn (gen_cmpltsi (i860_compare_op0, i860_compare_op1)); 744 else if (GET_MODE (i860_compare_op0) == SFmode) 745 emit_insn (gen_cmpltsf (i860_compare_op0, i860_compare_op1)); 746 else if (GET_MODE (i860_compare_op0) == DFmode) 747 emit_insn (gen_cmpltdf (i860_compare_op0, i860_compare_op1)); 748 else 749 abort (); 750 751 emit_jump_insn (gen_flipped_inverse_cbranch (operands[0])); 752 DONE; 753}") 754 755(define_expand "ble" 756 [(set (pc) 757 (if_then_else (le (cc0) 758 (const_int 0)) 759 (label_ref (match_operand 0 "" "")) 760 (pc)))] 761 "" 762 " 763{ 764 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT) 765 { 766 emit_insn (gen_cmpgtsi (i860_compare_op0, i860_compare_op1)); 767 emit_jump_insn (gen_flipped_cbranch (operands[0])); 768 } 769 else 770 { 771 if (GET_MODE (i860_compare_op0) == SFmode) 772 emit_insn (gen_cmplesf (i860_compare_op0, i860_compare_op1)); 773 else if (GET_MODE (i860_compare_op0) == DFmode) 774 emit_insn (gen_cmpledf (i860_compare_op0, i860_compare_op1)); 775 else 776 abort (); 777 emit_jump_insn (gen_flipped_inverse_cbranch (operands[0])); 778 } 779 DONE; 780}") 781 782(define_expand "bge" 783 [(set (pc) 784 (if_then_else (ge (cc0) 785 (const_int 0)) 786 (label_ref (match_operand 0 "" "")) 787 (pc)))] 788 "" 789 " 790{ 791 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) == MODE_INT) 792 { 793 emit_insn (gen_cmpltsi (i860_compare_op0, i860_compare_op1)); 794 emit_jump_insn (gen_flipped_cbranch (operands[0])); 795 } 796 else 797 { 798 if (GET_MODE (i860_compare_op0) == SFmode) 799 emit_insn (gen_cmpgesf (i860_compare_op0, i860_compare_op1)); 800 else if (GET_MODE (i860_compare_op0) == DFmode) 801 emit_insn (gen_cmpgedf (i860_compare_op0, i860_compare_op1)); 802 else 803 abort (); 804 emit_jump_insn (gen_flipped_inverse_cbranch (operands[0])); 805 } 806 DONE; 807}") 808 809(define_expand "bgtu" 810 [(set (pc) 811 (if_then_else (gtu (cc0) 812 (const_int 0)) 813 (label_ref (match_operand 0 "" "")) 814 (pc)))] 815 "" 816 " 817{ 818 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT) 819 abort (); 820 821 emit_insn (gen_cmpleusi (i860_compare_op0, i860_compare_op1)); 822 emit_jump_insn (gen_flipped_cbranch (operands[0])); 823 DONE; 824}") 825 826(define_expand "bltu" 827 [(set (pc) 828 (if_then_else (ltu (cc0) 829 (const_int 0)) 830 (label_ref (match_operand 0 "" "")) 831 (pc)))] 832 "" 833 " 834{ 835 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT) 836 abort (); 837 838 emit_insn (gen_cmpgeusi (i860_compare_op0, i860_compare_op1)); 839 emit_jump_insn (gen_flipped_cbranch (operands[0])); 840 DONE; 841}") 842 843(define_expand "bgeu" 844 [(set (pc) 845 (if_then_else (geu (cc0) 846 (const_int 0)) 847 (label_ref (match_operand 0 "" "")) 848 (pc)))] 849 "" 850 " 851{ 852 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT) 853 abort (); 854 855 emit_insn (gen_cmpgeusi (i860_compare_op0, i860_compare_op1)); 856 emit_jump_insn (gen_flipped_inverse_cbranch (operands[0])); 857 DONE; 858}") 859 860(define_expand "bleu" 861 [(set (pc) 862 (if_then_else (leu (cc0) 863 (const_int 0)) 864 (label_ref (match_operand 0 "" "")) 865 (pc)))] 866 "" 867 " 868{ 869 if (GET_MODE_CLASS (GET_MODE (i860_compare_op0)) != MODE_INT) 870 abort (); 871 872 emit_insn (gen_cmpleusi (i860_compare_op0, i860_compare_op1)); 873 emit_jump_insn (gen_flipped_inverse_cbranch (operands[0])); 874 DONE; 875}") 876 877;; Move instructions 878 879;; Note that source operands for `mov' pseudo-instructions are no longer 880;; allowed (by the svr4 assembler) to be "big" things, i.e. constants that 881;; won't fit in 16-bits. (This includes any sort of a relocatable address 882;; also.) Thus, we must use an explicit orh/or pair of instructions if 883;; the source operand is something "big". 884 885(define_insn "movsi" 886 [(set (match_operand:SI 0 "general_operand" "=r,m,f") 887 (match_operand:SI 1 "general_operand" "rmif,rfJ,rmfJ"))] 888 "" 889 "* 890{ 891 if (GET_CODE (operands[0]) == MEM) 892 { 893 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) 894 return output_store (operands); 895 if (FP_REG_P (operands[1])) 896 return \"fst.l %1,%0\"; 897 return \"st.l %r1,%0\"; 898 } 899 if (GET_CODE (operands[1]) == MEM) 900 { 901 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) 902 return output_load (operands); 903 if (FP_REG_P (operands[0])) 904 return \"fld.l %1,%0\"; 905 return \"ld.l %1,%0\"; 906 } 907 if (FP_REG_P (operands[1]) && FP_REG_P (operands[0])) 908 return \"fmov.ss %1,%0\"; 909 if (FP_REG_P (operands[1])) 910 return \"fxfr %1,%0\"; 911 if (FP_REG_P (operands[0]) && operands[1] == const0_rtx) 912 return \"fmov.ss %?f0,%0\"; 913 if (FP_REG_P (operands[0])) 914 return \"ixfr %1,%0\"; 915 916 if (GET_CODE (operands[1]) == REG) 917 return \"shl %?r0,%1,%0\"; 918 919 CC_STATUS_PARTIAL_INIT; 920 921 if (GET_CODE (operands[1]) == CONST_INT) 922 { 923 if((INTVAL (operands[1]) & 0xffff0000) == 0) 924 return \"or %L1,%?r0,%0\"; 925 if((INTVAL (operands[1]) & 0x0000ffff) == 0) 926 return \"orh %H1,%?r0,%0\"; 927 } 928 return \"orh %H1,%?r0,%0\;or %L1,%0,%0\"; 929}") 930 931(define_insn "movhi" 932 [(set (match_operand:HI 0 "general_operand" "=r,m,!*f,!r") 933 (match_operand:HI 1 "general_operand" "rmi,rJ,rJ*f,*f"))] 934 "" 935 "* 936{ 937 if (GET_CODE (operands[0]) == MEM) 938 { 939 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) 940 return output_store (operands); 941 return \"st.s %r1,%0\"; 942 } 943 if (GET_CODE (operands[1]) == MEM) 944 { 945 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) 946 return output_load (operands); 947 return \"ld.s %1,%0\"; 948 } 949 if (FP_REG_P (operands[1]) && FP_REG_P (operands[0])) 950 return \"fmov.ss %1,%0\"; 951 if (FP_REG_P (operands[1])) 952 return \"fxfr %1,%0\"; 953 if (FP_REG_P (operands[0]) && operands[1] == const0_rtx) 954 return \"fmov.ss %?f0,%0\"; 955 if (FP_REG_P (operands[0])) 956 return \"ixfr %1,%0\"; 957 958 if (GET_CODE (operands[1]) == REG) 959 return \"shl %?r0,%1,%0\"; 960 961 CC_STATUS_PARTIAL_INIT; 962 963 return \"or %L1,%?r0,%0\"; 964}") 965 966(define_insn "movqi" 967 [(set (match_operand:QI 0 "general_operand" "=r,m,!*f,!r") 968 (match_operand:QI 1 "general_operand" "rmi,rJ,rJ*f,*f"))] 969 "" 970 "* 971{ 972 if (GET_CODE (operands[0]) == MEM) 973 { 974 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) 975 return output_store (operands); 976 return \"st.b %r1,%0\"; 977 } 978 if (GET_CODE (operands[1]) == MEM) 979 { 980 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) 981 return output_load (operands); 982 return \"ld.b %1,%0\"; 983 } 984 if (FP_REG_P (operands[1]) && FP_REG_P (operands[0])) 985 return \"fmov.ss %1,%0\"; 986 if (FP_REG_P (operands[1])) 987 return \"fxfr %1,%0\"; 988 if (FP_REG_P (operands[0]) && operands[1] == const0_rtx) 989 return \"fmov.ss %?f0,%0\"; 990 if (FP_REG_P (operands[0])) 991 return \"ixfr %1,%0\"; 992 993 if (GET_CODE (operands[1]) == REG) 994 return \"shl %?r0,%1,%0\"; 995 996 CC_STATUS_PARTIAL_INIT; 997 998 return \"or %L1,%?r0,%0\"; 999}") 1000 1001;; The definition of this insn does not really explain what it does, 1002;; but it should suffice 1003;; that anything generated as this insn will be recognized as one 1004;; and that it won't successfully combine with anything. 1005(define_expand "movstrsi" 1006 [(parallel [(set (match_operand:BLK 0 "general_operand" "") 1007 (match_operand:BLK 1 "general_operand" "")) 1008 (use (match_operand:SI 2 "nonmemory_operand" "")) 1009 (use (match_operand:SI 3 "immediate_operand" "")) 1010 (clobber (match_dup 4)) 1011 (clobber (match_dup 5)) 1012 (clobber (match_dup 6)) 1013 (clobber (match_dup 7)) 1014 (clobber (match_dup 8))])] 1015 "" 1016 " 1017{ 1018 operands[4] = gen_reg_rtx (SImode); 1019 operands[5] = gen_reg_rtx (SImode); 1020 operands[6] = gen_reg_rtx (SImode); 1021 operands[7] = copy_to_mode_reg (SImode, XEXP (operands[0], 0)); 1022 operands[8] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); 1023 1024 operands[0] = change_address (operands[0], VOIDmode, operands[7]); 1025 operands[1] = change_address (operands[1], VOIDmode, operands[8]); 1026}") 1027 1028(define_insn "" 1029 [(set (mem:BLK (match_operand:SI 0 "register_operand" "r")) 1030 (mem:BLK (match_operand:SI 1 "register_operand" "r"))) 1031 (use (match_operand:SI 2 "general_operand" "rn")) 1032 (use (match_operand:SI 3 "immediate_operand" "i")) 1033 (clobber (match_operand:SI 4 "register_operand" "=r")) 1034 (clobber (match_operand:SI 5 "register_operand" "=r")) 1035 (clobber (match_operand:SI 6 "register_operand" "=r")) 1036 (clobber (match_dup 0)) 1037 (clobber (match_dup 1))] 1038 "" 1039 "* return output_block_move (operands);") 1040 1041;; Floating point move insns 1042 1043;; This pattern forces (set (reg:DF ...) (const_double ...)) 1044;; to be reloaded by putting the constant into memory. 1045;; It must come before the more general movdf pattern. 1046(define_insn "" 1047 [(set (match_operand:DF 0 "general_operand" "=r,f,o") 1048 (match_operand:DF 1 "" "mG,m,G"))] 1049 "GET_CODE (operands[1]) == CONST_DOUBLE" 1050 "* 1051{ 1052 if (FP_REG_P (operands[0]) || operands[1] == CONST0_RTX (DFmode)) 1053 return output_fp_move_double (operands); 1054 return output_move_double (operands); 1055}") 1056 1057(define_insn "movdf" 1058 [(set (match_operand:DF 0 "general_operand" "=*rm,*r,?f,?*rm") 1059 (match_operand:DF 1 "general_operand" "*r,m,*rfmG,f"))] 1060 "" 1061 "* 1062{ 1063 if (GET_CODE (operands[0]) == MEM 1064 && CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) 1065 return output_store (operands); 1066 if (GET_CODE (operands[1]) == MEM 1067 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) 1068 return output_load (operands); 1069 1070 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) 1071 return output_fp_move_double (operands); 1072 return output_move_double (operands); 1073}") 1074 1075(define_insn "movdi" 1076 [(set (match_operand:DI 0 "general_operand" "=rm,r,?f,?rm") 1077 (match_operand:DI 1 "general_operand" "r,miF,rfmG,f"))] 1078 "" 1079 "* 1080{ 1081 if (GET_CODE (operands[0]) == MEM 1082 && CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) 1083 return output_store (operands); 1084 if (GET_CODE (operands[1]) == MEM 1085 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) 1086 return output_load (operands); 1087 1088 /* ??? How can we have a DFmode arg here with DImode above? */ 1089 if (FP_REG_P (operands[0]) && operands[1] == CONST0_RTX (DFmode)) 1090 return \"fmov.dd %?f0,%0\"; 1091 1092 if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) 1093 return output_fp_move_double (operands); 1094 return output_move_double (operands); 1095}") 1096 1097;; The alternative m/r is separate from m/f 1098;; The first alternative is separate from the second for the same reason. 1099(define_insn "movsf" 1100 [(set (match_operand:SF 0 "general_operand" "=*rf,*rf,*r,m,m") 1101 (match_operand:SF 1 "general_operand" "*r,fmG,F,*r,f"))] 1102 "" 1103 "* 1104{ 1105 if (GET_CODE (operands[0]) == MEM 1106 && CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) 1107 return output_store (operands); 1108 if (GET_CODE (operands[1]) == MEM 1109 && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) 1110 return output_load (operands); 1111 if (FP_REG_P (operands[0])) 1112 { 1113 if (FP_REG_P (operands[1])) 1114 return \"fmov.ss %1,%0\"; 1115 if (GET_CODE (operands[1]) == REG) 1116 return \"ixfr %1,%0\"; 1117 if (operands[1] == CONST0_RTX (SFmode)) 1118 return \"fmov.ss %?f0,%0\"; 1119 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) 1120 { 1121 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31) 1122 && (cc_prev_status.flags & CC_HI_R31_ADJ) 1123 && cc_prev_status.mdep == XEXP(operands[1],0))) 1124 { 1125 CC_STATUS_INIT; 1126 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; 1127 cc_status.mdep = XEXP (operands[1], 0); 1128 return \"orh %h1,%?r0,%?r31\;fld.l %L1(%?r31),%0\"; 1129 } 1130 return \"fld.l %L1(%?r31),%0\"; 1131 } 1132 return \"fld.l %1,%0\"; 1133 } 1134 if (FP_REG_P (operands[1]) || GET_CODE (operands[1]) == CONST_DOUBLE) 1135 { 1136 if (GET_CODE (operands[0]) == REG && FP_REG_P (operands[1])) 1137 return \"fxfr %1,%0\"; 1138 if (GET_CODE (operands[0]) == REG) 1139 { 1140 CC_STATUS_PARTIAL_INIT; 1141 if (GET_CODE (operands[1]) == CONST_DOUBLE) 1142 { 1143 register unsigned long ul; 1144 1145 ul = sfmode_constant_to_ulong (operands[1]); 1146 if ((ul & 0x0000ffff) == 0) 1147 return \"orh %H1,%?r0,%0\"; 1148 if ((ul & 0xffff0000) == 0) 1149 return \"or %L1,%?r0,%0\"; 1150 } 1151 return \"orh %H1,%?r0,%0\;or %L1,%0,%0\"; 1152 } 1153 /* Now operand 0 must be memory. 1154 If operand 1 is CONST_DOUBLE, its value must be 0. */ 1155 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) 1156 { 1157 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31) 1158 && (cc_prev_status.flags & CC_HI_R31_ADJ) 1159 && XEXP (operands[0], 0) == cc_prev_status.mdep)) 1160 { 1161 CC_STATUS_INIT; 1162 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; 1163 cc_status.mdep = XEXP (operands[0], 0); 1164 output_asm_insn (\"orh %h0,%?r0,%?r31\", operands); 1165 } 1166 return \"fst.l %r1,%L0(%?r31)\"; 1167 } 1168 return \"fst.l %r1,%0\"; 1169 } 1170 if (GET_CODE (operands[0]) == MEM) 1171 return \"st.l %r1,%0\"; 1172 if (GET_CODE (operands[1]) == MEM) 1173 return \"ld.l %1,%0\"; 1174 if (operands[1] == CONST0_RTX (SFmode)) 1175 return \"shl %?r0,%?r0,%0\"; 1176 return \"mov %1,%0\"; 1177}") 1178 1179;; Special load insns for REG+REG addresses. 1180;; Such addresses are not "legitimate" because st rejects them. 1181 1182(define_insn "" 1183 [(set (match_operand:DF 0 "register_operand" "=rf") 1184 (match_operand:DF 1 "indexed_operand" "m"))] 1185 "" 1186 "* 1187{ 1188 if (FP_REG_P (operands[0])) 1189 return output_fp_move_double (operands); 1190 return output_move_double (operands); 1191}") 1192 1193(define_insn "" 1194 [(set (match_operand:SF 0 "register_operand" "=rf") 1195 (match_operand:SF 1 "indexed_operand" "m"))] 1196 "" 1197 "* 1198{ 1199 if (FP_REG_P (operands[0])) 1200 return \"fld.l %1,%0\"; 1201 return \"ld.l %1,%0\"; 1202}") 1203 1204(define_insn "" 1205 [(set (match_operand:SI 0 "register_operand" "=rf") 1206 (match_operand:SI 1 "indexed_operand" "m"))] 1207 "" 1208 "* 1209{ 1210 if (FP_REG_P (operands[0])) 1211 return \"fld.l %1,%0\"; 1212 return \"ld.l %1,%0\"; 1213}") 1214 1215(define_insn "" 1216 [(set (match_operand:HI 0 "register_operand" "=r") 1217 (match_operand:HI 1 "indexed_operand" "m"))] 1218 "" 1219 "ld.s %1,%0") 1220 1221(define_insn "" 1222 [(set (match_operand:QI 0 "register_operand" "=r") 1223 (match_operand:QI 1 "indexed_operand" "m"))] 1224 "" 1225 "ld.b %1,%0") 1226 1227;; Likewise for floating-point store insns. 1228 1229(define_insn "" 1230 [(set (match_operand:DF 0 "indexed_operand" "=m") 1231 (match_operand:DF 1 "register_operand" "f"))] 1232 "" 1233 "fst.d %1,%0") 1234 1235(define_insn "" 1236 [(set (match_operand:SF 0 "indexed_operand" "=m") 1237 (match_operand:SF 1 "register_operand" "f"))] 1238 "" 1239 "fst.l %1,%0") 1240 1241;;- truncation instructions 1242(define_insn "truncsiqi2" 1243 [(set (match_operand:QI 0 "general_operand" "=g") 1244 (truncate:QI 1245 (match_operand:SI 1 "register_operand" "r")))] 1246 "" 1247 "* 1248{ 1249 if (GET_CODE (operands[0]) == MEM) 1250 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) 1251 { 1252 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31) 1253 && (cc_prev_status.flags & CC_HI_R31_ADJ) 1254 && XEXP (operands[0], 0) == cc_prev_status.mdep)) 1255 { 1256 CC_STATUS_INIT; 1257 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; 1258 cc_status.mdep = XEXP (operands[0], 0); 1259 output_asm_insn (\"orh %h0,%?r0,%?r31\", operands); 1260 } 1261 return \"st.b %1,%L0(%?r31)\"; 1262 } 1263 else 1264 return \"st.b %1,%0\"; 1265 return \"shl %?r0,%1,%0\"; 1266}") 1267 1268(define_insn "trunchiqi2" 1269 [(set (match_operand:QI 0 "general_operand" "=g") 1270 (truncate:QI 1271 (match_operand:HI 1 "register_operand" "r")))] 1272 "" 1273 "* 1274{ 1275 if (GET_CODE (operands[0]) == MEM) 1276 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) 1277 { 1278 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31) 1279 && (cc_prev_status.flags & CC_HI_R31_ADJ) 1280 && XEXP (operands[0], 0) == cc_prev_status.mdep)) 1281 { 1282 CC_STATUS_INIT; 1283 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; 1284 cc_status.mdep = XEXP (operands[0], 0); 1285 output_asm_insn (\"orh %h0,%?r0,%?r31\", operands); 1286 } 1287 return \"st.b %1,%L0(%?r31)\"; 1288 } 1289 else 1290 return \"st.b %1,%0\"; 1291 return \"shl %?r0,%1,%0\"; 1292}") 1293 1294(define_insn "truncsihi2" 1295 [(set (match_operand:HI 0 "general_operand" "=g") 1296 (truncate:HI 1297 (match_operand:SI 1 "register_operand" "r")))] 1298 "" 1299 "* 1300{ 1301 if (GET_CODE (operands[0]) == MEM) 1302 if (CONSTANT_ADDRESS_P (XEXP (operands[0], 0))) 1303 { 1304 if (! ((cc_prev_status.flags & CC_KNOW_HI_R31) 1305 && (cc_prev_status.flags & CC_HI_R31_ADJ) 1306 && XEXP (operands[0], 0) == cc_prev_status.mdep)) 1307 { 1308 CC_STATUS_INIT; 1309 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; 1310 cc_status.mdep = XEXP (operands[0], 0); 1311 output_asm_insn (\"orh %h0,%?r0,%?r31\", operands); 1312 } 1313 return \"st.s %1,%L0(%?r31)\"; 1314 } 1315 else 1316 return \"st.s %1,%0\"; 1317 return \"shl %?r0,%1,%0\"; 1318}") 1319 1320;;- zero extension instructions 1321 1322(define_insn "zero_extendhisi2" 1323 [(set (match_operand:SI 0 "register_operand" "=r") 1324 (zero_extend:SI 1325 (match_operand:HI 1 "register_operand" "r")))] 1326 "" 1327 "* 1328{ 1329 CC_STATUS_PARTIAL_INIT; 1330 return \"and 0xffff,%1,%0\"; 1331}") 1332 1333(define_insn "zero_extendqihi2" 1334 [(set (match_operand:HI 0 "register_operand" "=r") 1335 (zero_extend:HI 1336 (match_operand:QI 1 "register_operand" "r")))] 1337 "" 1338 "* 1339{ 1340 CC_STATUS_PARTIAL_INIT; 1341 return \"and 0xff,%1,%0\"; 1342}") 1343 1344(define_insn "zero_extendqisi2" 1345 [(set (match_operand:SI 0 "register_operand" "=r") 1346 (zero_extend:SI 1347 (match_operand:QI 1 "register_operand" "r")))] 1348 "" 1349 "* 1350{ 1351 CC_STATUS_PARTIAL_INIT; 1352 return \"and 0xff,%1,%0\"; 1353}") 1354 1355;; Sign extension instructions. 1356 1357(define_insn "" 1358 [(set (match_operand:SI 0 "register_operand" "=r") 1359 (sign_extend:SI 1360 (match_operand:HI 1 "indexed_operand" "m")))] 1361 "" 1362 "ld.s %1,%0") 1363 1364(define_insn "" 1365 [(set (match_operand:HI 0 "register_operand" "=r") 1366 (sign_extend:HI 1367 (match_operand:QI 1 "indexed_operand" "m")))] 1368 "" 1369 "ld.b %1,%0") 1370 1371(define_insn "" 1372 [(set (match_operand:SI 0 "register_operand" "=r") 1373 (sign_extend:SI 1374 (match_operand:QI 1 "indexed_operand" "m")))] 1375 "" 1376 "ld.b %1,%0") 1377 1378(define_insn "extendhisi2" 1379 [(set (match_operand:SI 0 "register_operand" "=r") 1380 (sign_extend:SI 1381 (match_operand:HI 1 "nonimmediate_operand" "mr")))] 1382 "" 1383 "* 1384{ 1385 if (REG_P (operands[1])) 1386 return \"shl 16,%1,%0\;shra 16,%0,%0\"; 1387 if (GET_CODE (operands[1]) == CONST_INT) 1388 abort (); 1389 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) 1390 { 1391 CC_STATUS_INIT; 1392 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; 1393 cc_status.mdep = XEXP (operands[1], 0); 1394 return \"orh %h1,%?r0,%?r31\;ld.s %L1(%?r31),%0\"; 1395 } 1396 else 1397 return \"ld.s %1,%0\"; 1398}") 1399 1400(define_insn "extendqihi2" 1401 [(set (match_operand:HI 0 "register_operand" "=r") 1402 (sign_extend:HI 1403 (match_operand:QI 1 "nonimmediate_operand" "mr")))] 1404 "" 1405 "* 1406{ 1407 if (REG_P (operands[1])) 1408 return \"shl 24,%1,%0\;shra 24,%0,%0\"; 1409 if (GET_CODE (operands[1]) == CONST_INT) 1410 abort (); 1411 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) 1412 { 1413 CC_STATUS_INIT; 1414 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; 1415 cc_status.mdep = XEXP (operands[1], 0); 1416 return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\"; 1417 } 1418 else 1419 return \"ld.b %1,%0\"; 1420}") 1421 1422(define_insn "extendqisi2" 1423 [(set (match_operand:SI 0 "register_operand" "=r") 1424 (sign_extend:SI 1425 (match_operand:QI 1 "nonimmediate_operand" "mr")))] 1426 "" 1427 "* 1428{ 1429 if (REG_P (operands[1])) 1430 return \"shl 24,%1,%0\;shra 24,%0,%0\"; 1431 if (GET_CODE (operands[1]) == CONST_INT) 1432 abort (); 1433 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) 1434 { 1435 CC_STATUS_INIT; 1436 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; 1437 cc_status.mdep = XEXP (operands[1], 0); 1438 return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\"; 1439 } 1440 else 1441 return \"ld.b %1,%0\"; 1442}") 1443 1444;; Signed bitfield extractions come out looking like 1445;; (shiftrt (sign_extend (shift <Y> <C1>)) <C2>) 1446;; which we expand poorly as four shift insns. 1447;; These patterns yield two shifts: 1448;; (shiftrt (shift <Y> <C3>) <C4>) 1449(define_insn "" 1450 [(set (match_operand:SI 0 "register_operand" "=r") 1451 (ashiftrt:SI 1452 (sign_extend:SI 1453 (match_operand:QI 1 "register_operand" "r")) 1454 (match_operand:SI 2 "logic_int" "n")))] 1455 "INTVAL (operands[2]) < 8" 1456 "* 1457{ 1458 return \"shl 24,%1,%0\;shra 24+%2,%0,%0\"; 1459}") 1460 1461(define_insn "" 1462 [(set (match_operand:SI 0 "register_operand" "=r") 1463 (ashiftrt:SI 1464 (sign_extend:SI 1465 (subreg:QI (ashift:SI (match_operand:SI 1 "register_operand" "r") 1466 (match_operand:SI 2 "logic_int" "n")) 0)) 1467 (match_operand:SI 3 "logic_int" "n")))] 1468 "INTVAL (operands[3]) < 8" 1469 "* 1470{ 1471 return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\"; 1472}") 1473 1474(define_insn "" 1475 [(set (match_operand:SI 0 "register_operand" "=r") 1476 (ashiftrt:SI 1477 (sign_extend:SI 1478 (ashift:QI (match_operand:QI 1 "register_operand" "r") 1479 (match_operand:QI 2 "logic_int" "n"))) 1480 (match_operand:SI 3 "logic_int" "n")))] 1481 "INTVAL (operands[3]) < 8" 1482 "* 1483{ 1484 return \"shl 0x18+%2,%1,%0\;shra 0x18+%3,%0,%0\"; 1485}") 1486 1487;; Special patterns for optimizing bit-field instructions. 1488 1489;; First two patterns are for bitfields that came from memory 1490;; testing only the high bit. They work with old combiner. 1491 1492(define_insn "" 1493 [(set (cc0) 1494 (eq (zero_extend:SI (subreg:QI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r") 1495 (const_int 7)) 0)) 1496 (const_int 0)))] 1497 "" 1498 "* 1499{ 1500 CC_STATUS_PARTIAL_INIT; 1501 return \"and 128,%0,%?r0\"; 1502}") 1503 1504(define_insn "" 1505 [(set (cc0) 1506 (eq (sign_extend:SI (subreg:QI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r") 1507 (const_int 7)) 0)) 1508 (const_int 0)))] 1509 "" 1510 "* 1511{ 1512 CC_STATUS_PARTIAL_INIT; 1513 return \"and 128,%0,%?r0\"; 1514}") 1515 1516;; next two patterns are good for bitfields coming from memory 1517;; (via pseudo-register) or from a register, though this optimization 1518;; is only good for values contained wholly within the bottom 13 bits 1519(define_insn "" 1520 [(set (cc0) 1521 (eq 1522 (and:SI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r") 1523 (match_operand:SI 1 "logic_int" "n")) 1524 (match_operand:SI 2 "logic_int" "n")) 1525 (const_int 0)))] 1526 "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))" 1527 "* 1528{ 1529 CC_STATUS_PARTIAL_INIT; 1530 operands[2] = GEN_INT ((INTVAL (operands[2]) << INTVAL (operands[1]))); 1531 return \"and %2,%0,%?r0\"; 1532}") 1533 1534(define_insn "" 1535 [(set (cc0) 1536 (eq 1537 (and:SI (ashiftrt:SI (match_operand:SI 0 "register_operand" "r") 1538 (match_operand:SI 1 "logic_int" "n")) 1539 (match_operand:SI 2 "logic_int" "n")) 1540 (const_int 0)))] 1541 "LOGIC_INTVAL (INTVAL (operands[2]) << INTVAL (operands[1]))" 1542 "* 1543{ 1544 CC_STATUS_PARTIAL_INIT; 1545 operands[2] = GEN_INT ((INTVAL (operands[2]) << INTVAL (operands[1]))); 1546 return \"and %2,%0,%?r0\"; 1547}") 1548 1549;; Conversions between float and double. 1550 1551(define_insn "extendsfdf2" 1552 [(set (match_operand:DF 0 "register_operand" "=f") 1553 (float_extend:DF 1554 (match_operand:SF 1 "register_operand" "f")))] 1555 "" 1556 "fmov.sd %1,%0") 1557 1558(define_insn "truncdfsf2" 1559 [(set (match_operand:SF 0 "register_operand" "=f") 1560 (float_truncate:SF 1561 (match_operand:DF 1 "register_operand" "f")))] 1562 "" 1563 "fmov.ds %1,%0") 1564 1565;; Conversion between fixed point and floating point. 1566;; Note that among the fix-to-float insns 1567;; the ones that start with SImode come first. 1568;; That is so that an operand that is a CONST_INT 1569;; (and therefore lacks a specific machine mode). 1570;; will be recognized as SImode (which is always valid) 1571;; rather than as QImode or HImode. 1572 1573;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...))) 1574;; to be reloaded by putting the constant into memory. 1575;; It must come before the more general floatsisf2 pattern. 1576(define_expand "floatsidf2" 1577 [(set (match_dup 2) (match_dup 3)) 1578 (set (match_dup 4) (xor:SI (match_operand:SI 1 "register_operand" "") 1579 (const_int -2147483648))) 1580 (set (match_dup 5) (match_dup 3)) 1581 (set (subreg:SI (match_dup 5) 0) (match_dup 4)) 1582 (set (match_operand:DF 0 "register_operand" "") 1583 (minus:DF (match_dup 5) (match_dup 2)))] 1584 "" 1585 " 1586{ 1587 REAL_VALUE_TYPE d; 1588 /* 4503601774854144 is (1 << 30) * ((1 << 22) + (1 << 1)). */ 1589 d = REAL_VALUE_ATOF (\"4503601774854144\", DFmode); 1590 operands[2] = gen_reg_rtx (DFmode); 1591 operands[3] = CONST_DOUBLE_FROM_REAL_VALUE (d, DFmode); 1592 operands[4] = gen_reg_rtx (SImode); 1593 operands[5] = gen_reg_rtx (DFmode); 1594}") 1595 1596;; Floating to fixed conversion. 1597 1598(define_expand "fix_truncdfsi2" 1599 ;; This first insn produces a double-word value 1600 ;; in which only the low word is valid. 1601 [(set (match_dup 2) 1602 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f")))) 1603 (set (match_operand:SI 0 "register_operand" "=f") 1604 (subreg:SI (match_dup 2) 0))] 1605 "" 1606 " 1607{ 1608 operands[2] = gen_reg_rtx (DImode); 1609}") 1610 1611;; Recognize the first insn generated above. 1612;; This RTL looks like a fix_truncdfdi2 insn, 1613;; but we dont call it that, because only 32 bits 1614;; of the result are valid. 1615;; This pattern will work for the intended purposes 1616;; as long as we do not have any fixdfdi2 or fix_truncdfdi2. 1617(define_insn "" 1618 [(set (match_operand:DI 0 "register_operand" "=f") 1619 (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))] 1620 "" 1621 "ftrunc.dd %1,%0") 1622 1623(define_expand "fix_truncsfsi2" 1624 ;; This first insn produces a double-word value 1625 ;; in which only the low word is valid. 1626 [(set (match_dup 2) 1627 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f")))) 1628 (set (match_operand:SI 0 "register_operand" "=f") 1629 (subreg:SI (match_dup 2) 0))] 1630 "" 1631 " 1632{ 1633 operands[2] = gen_reg_rtx (DImode); 1634}") 1635 1636;; Recognize the first insn generated above. 1637;; This RTL looks like a fix_truncsfdi2 insn, 1638;; but we dont call it that, because only 32 bits 1639;; of the result are valid. 1640;; This pattern will work for the intended purposes 1641;; as long as we do not have any fixsfdi2 or fix_truncsfdi2. 1642(define_insn "" 1643 [(set (match_operand:DI 0 "register_operand" "=f") 1644 (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] 1645 "" 1646 "ftrunc.sd %1,%0") 1647 1648;;- arithmetic instructions 1649 1650(define_insn "addsi3" 1651 [(set (match_operand:SI 0 "register_operand" "=r,*f") 1652 (plus:SI (match_operand:SI 1 "nonmemory_operand" "%r,*f") 1653 (match_operand:SI 2 "arith_operand" "rI,*f")))] 1654 "" 1655 "* 1656{ 1657 if (which_alternative == 1) 1658 return \"fiadd.ss %2,%1,%0\"; 1659 CC_STATUS_PARTIAL_INIT; 1660 return \"addu %2,%1,%0\"; 1661}") 1662 1663(define_insn "adddi3" 1664 [(set (match_operand:DI 0 "register_operand" "=f") 1665 (plus:DI (match_operand:DI 1 "register_operand" "%f") 1666 (match_operand:DI 2 "register_operand" "f")))] 1667 "" 1668 "fiadd.dd %1,%2,%0") 1669 1670(define_insn "subsi3" 1671 [(set (match_operand:SI 0 "register_operand" "=r,r,*f") 1672 (minus:SI (match_operand:SI 1 "register_operand" "r,I,*f") 1673 (match_operand:SI 2 "arith_operand" "rI,r,*f")))] 1674 "" 1675 "* 1676{ 1677 if (which_alternative == 2) 1678 return \"fisub.ss %1,%2,%0\"; 1679 CC_STATUS_PARTIAL_INIT; 1680 if (REG_P (operands[2])) 1681 return \"subu %1,%2,%0\"; 1682 operands[2] = GEN_INT (- INTVAL (operands[2])); 1683 return \"addu %2,%1,%0\"; 1684}") 1685 1686(define_insn "subdi3" 1687 [(set (match_operand:DI 0 "register_operand" "=f") 1688 (minus:DI (match_operand:DI 1 "register_operand" "f") 1689 (match_operand:DI 2 "register_operand" "f")))] 1690 "" 1691 "fisub.dd %1,%2,%0") 1692 1693(define_expand "mulsi3" 1694 [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" "")) 1695 (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" "")) 1696 (clobber (match_dup 3)) 1697 (set (subreg:SI (match_dup 3) 0) 1698 (mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0))) 1699 (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))] 1700 "" 1701 " 1702{ 1703 if (WORDS_BIG_ENDIAN) 1704 emit_insn (gen_mulsi3_big (operands[0], operands[1], operands[2])); 1705 else 1706 emit_insn (gen_mulsi3_little (operands[0], operands[1], operands[2])); 1707 DONE; 1708}") 1709 1710(define_expand "mulsi3_little" 1711 [(set (subreg:SI (match_dup 4) 0) (match_operand:SI 1 "general_operand" "")) 1712 (set (subreg:SI (match_dup 5) 0) (match_operand:SI 2 "general_operand" "")) 1713 (clobber (match_dup 3)) 1714 (set (subreg:SI (match_dup 3) 0) 1715 (mult:SI (subreg:SI (match_dup 4) 0) (subreg:SI (match_dup 5) 0))) 1716 (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 0))] 1717 "! WORDS_BIG_ENDIAN" 1718 " 1719{ 1720 operands[3] = gen_reg_rtx (DImode); 1721 operands[4] = gen_reg_rtx (DImode); 1722 operands[5] = gen_reg_rtx (DImode); 1723}") 1724 1725(define_expand "mulsi3_big" 1726 [(set (subreg:SI (match_dup 4) 1) (match_operand:SI 1 "general_operand" "")) 1727 (set (subreg:SI (match_dup 5) 1) (match_operand:SI 2 "general_operand" "")) 1728 (clobber (match_dup 3)) 1729 (set (subreg:SI (match_dup 3) 1) 1730 (mult:SI (subreg:SI (match_dup 4) 1) (subreg:SI (match_dup 5) 1))) 1731 (set (match_operand:SI 0 "register_operand" "") (subreg:SI (match_dup 3) 1))] 1732 "WORDS_BIG_ENDIAN" 1733 " 1734{ 1735 operands[3] = gen_reg_rtx (DImode); 1736 operands[4] = gen_reg_rtx (DImode); 1737 operands[5] = gen_reg_rtx (DImode); 1738}") 1739 1740(define_insn "" 1741 [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 0) 1742 (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 0) 1743 (subreg:SI (match_operand:DI 2 "register_operand" "f") 0)))] 1744 "! WORDS_BIG_ENDIAN" 1745 "fmlow.dd %2,%1,%0") 1746 1747(define_insn "" 1748 [(set (subreg:SI (match_operand:DI 0 "register_operand" "=f") 1) 1749 (mult:SI (subreg:SI (match_operand:DI 1 "register_operand" "f") 1) 1750 (subreg:SI (match_operand:DI 2 "register_operand" "f") 1)))] 1751 "WORDS_BIG_ENDIAN" 1752 "fmlow.dd %2,%1,%0") 1753 1754;;- and instructions (with compliment also) 1755(define_insn "andsi3" 1756 [(set (match_operand:SI 0 "register_operand" "=r") 1757 (and:SI (match_operand:SI 1 "nonmemory_operand" "%r") 1758 (match_operand:SI 2 "nonmemory_operand" "rL")))] 1759 "" 1760 "* 1761{ 1762 rtx xop[3]; 1763 1764 CC_STATUS_PARTIAL_INIT; 1765 if (REG_P (operands[2]) || LOGIC_INT (operands[2])) 1766 return \"and %2,%1,%0\"; 1767 if ((INTVAL (operands[2]) & 0xffff) == 0) 1768 { 1769 operands[2] = GEN_INT ((unsigned) INTVAL (operands[2]) >> 16); 1770 return \"andh %2,%1,%0\"; 1771 } 1772 xop[0] = operands[0]; 1773 xop[1] = operands[1]; 1774 xop[2] = GEN_INT (~INTVAL (operands[2]) & 0xffff); 1775 output_asm_insn (\"andnot %2,%1,%0\", xop); 1776 operands[2] = GEN_INT (~(unsigned) INTVAL (operands[2]) >> 16); 1777 return \"andnoth %2,%0,%0\"; 1778}") 1779 1780(define_insn "" 1781 [(set (match_operand:SI 0 "register_operand" "=r") 1782 (and:SI (not:SI (match_operand:SI 1 "register_operand" "rn")) 1783 (match_operand:SI 2 "register_operand" "r")))] 1784 "" 1785 "* 1786{ 1787 rtx xop[3]; 1788 1789 CC_STATUS_PARTIAL_INIT; 1790 if (REG_P (operands[1]) || LOGIC_INT (operands[1])) 1791 return \"andnot %1,%2,%0\"; 1792 if ((INTVAL (operands[1]) & 0xffff) == 0) 1793 { 1794 operands[1] = GEN_INT ((unsigned) INTVAL (operands[1]) >> 16); 1795 return \"andnoth %1,%2,%0\"; 1796 } 1797 xop[0] = operands[0]; 1798 xop[1] = GEN_INT ((INTVAL (operands[1]) & 0xffff)); 1799 xop[2] = operands[2]; 1800 output_asm_insn (\"andnot %1,%2,%0\", xop); 1801 operands[1] = GEN_INT ((unsigned) INTVAL (operands[1]) >> 16); 1802 return \"andnoth %1,%0,%0\"; 1803}") 1804 1805(define_insn "iorsi3" 1806 [(set (match_operand:SI 0 "register_operand" "=r") 1807 (ior:SI (match_operand:SI 1 "nonmemory_operand" "%r") 1808 (match_operand:SI 2 "nonmemory_operand" "rL")))] 1809 "" 1810 "* 1811{ 1812 rtx xop[3]; 1813 1814 CC_STATUS_PARTIAL_INIT; 1815 if (REG_P (operands[2]) || LOGIC_INT (operands[2])) 1816 return \"or %2,%1,%0\"; 1817 if ((INTVAL (operands[2]) & 0xffff) == 0) 1818 { 1819 operands[2] = GEN_INT ((unsigned) INTVAL (operands[2]) >> 16); 1820 return \"orh %2,%1,%0\"; 1821 } 1822 xop[0] = operands[0]; 1823 xop[1] = operands[1]; 1824 xop[2] = GEN_INT ((INTVAL (operands[2]) & 0xffff)); 1825 output_asm_insn (\"or %2,%1,%0\", xop); 1826 operands[2] = GEN_INT ((unsigned) INTVAL (operands[2]) >> 16); 1827 return \"orh %2,%0,%0\"; 1828}") 1829 1830(define_insn "xorsi3" 1831 [(set (match_operand:SI 0 "register_operand" "=r") 1832 (xor:SI (match_operand:SI 1 "nonmemory_operand" "%r") 1833 (match_operand:SI 2 "nonmemory_operand" "rL")))] 1834 "" 1835 "* 1836{ 1837 rtx xop[3]; 1838 1839 CC_STATUS_PARTIAL_INIT; 1840 if (REG_P (operands[2]) || LOGIC_INT (operands[2])) 1841 return \"xor %2,%1,%0\"; 1842 if ((INTVAL (operands[2]) & 0xffff) == 0) 1843 { 1844 operands[2] = GEN_INT ((unsigned) INTVAL (operands[2]) >> 16); 1845 return \"xorh %2,%1,%0\"; 1846 } 1847 xop[0] = operands[0]; 1848 xop[1] = operands[1]; 1849 xop[2] = GEN_INT ((INTVAL (operands[2]) & 0xffff)); 1850 output_asm_insn (\"xor %2,%1,%0\", xop); 1851 operands[2] = GEN_INT ((unsigned) INTVAL (operands[2]) >> 16); 1852 return \"xorh %2,%0,%0\"; 1853}") 1854 1855;(The i860 instruction set doesn't allow an immediate second operand in 1856; a subtraction.) 1857(define_insn "negsi2" 1858 [(set (match_operand:SI 0 "general_operand" "=r") 1859 (neg:SI (match_operand:SI 1 "arith_operand" "r")))] 1860 "" 1861 "* 1862{ 1863 CC_STATUS_PARTIAL_INIT; 1864 return \"subu %?r0,%1,%0\"; 1865}") 1866 1867(define_insn "one_cmplsi2" 1868 [(set (match_operand:SI 0 "general_operand" "=r") 1869 (not:SI (match_operand:SI 1 "arith_operand" "r")))] 1870 "" 1871 "* 1872{ 1873 CC_STATUS_PARTIAL_INIT; 1874 return \"subu -1,%1,%0\"; 1875}") 1876 1877;; Floating point arithmetic instructions. 1878 1879(define_insn "adddf3" 1880 [(set (match_operand:DF 0 "register_operand" "=f") 1881 (plus:DF (match_operand:DF 1 "register_operand" "f") 1882 (match_operand:DF 2 "register_operand" "f")))] 1883 "" 1884 "fadd.dd %1,%2,%0") 1885 1886(define_insn "addsf3" 1887 [(set (match_operand:SF 0 "register_operand" "=f") 1888 (plus:SF (match_operand:SF 1 "register_operand" "f") 1889 (match_operand:SF 2 "register_operand" "f")))] 1890 "" 1891 "fadd.ss %1,%2,%0") 1892 1893(define_insn "subdf3" 1894 [(set (match_operand:DF 0 "register_operand" "=f") 1895 (minus:DF (match_operand:DF 1 "register_operand" "f") 1896 (match_operand:DF 2 "register_operand" "f")))] 1897 "" 1898 "fsub.dd %1,%2,%0") 1899 1900(define_insn "subsf3" 1901 [(set (match_operand:SF 0 "register_operand" "=f") 1902 (minus:SF (match_operand:SF 1 "register_operand" "f") 1903 (match_operand:SF 2 "register_operand" "f")))] 1904 "" 1905 "fsub.ss %1,%2,%0") 1906 1907(define_insn "muldf3" 1908 [(set (match_operand:DF 0 "register_operand" "=f") 1909 (mult:DF (match_operand:DF 1 "register_operand" "f") 1910 (match_operand:DF 2 "register_operand" "f")))] 1911 "" 1912 "fmul.dd %1,%2,%0") 1913 1914(define_insn "mulsf3" 1915 [(set (match_operand:SF 0 "register_operand" "=f") 1916 (mult:SF (match_operand:SF 1 "register_operand" "f") 1917 (match_operand:SF 2 "register_operand" "f")))] 1918 "" 1919 "fmul.ss %1,%2,%0") 1920 1921(define_insn "negdf2" 1922 [(set (match_operand:DF 0 "register_operand" "=f") 1923 (neg:DF (match_operand:DF 1 "register_operand" "f")))] 1924 "" 1925 "fsub.dd %?f0,%1,%0") 1926 1927(define_insn "negsf2" 1928 [(set (match_operand:SF 0 "register_operand" "=f") 1929 (neg:SF (match_operand:SF 1 "register_operand" "f")))] 1930 "" 1931 "fsub.ss %?f0,%1,%0") 1932 1933(define_insn "divdf3" 1934 [(set (match_operand:DF 0 "register_operand" "=&f") 1935 (div:DF (match_operand:DF 1 "register_operand" "f") 1936 (match_operand:DF 2 "register_operand" "f"))) 1937 (clobber (match_scratch:DF 3 "=&f")) 1938 (clobber (match_scratch:DF 4 "=&f"))] 1939 "" 1940 "* 1941{ 1942 CC_STATUS_PARTIAL_INIT; 1943 if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0) 1944 || (cc_prev_status.flags & CC_HI_R31_ADJ) 1945 || (cc_prev_status.mdep != CONST2_RTX (SFmode))) 1946 { 1947 cc_status.flags |= CC_KNOW_HI_R31; 1948 cc_status.flags &= ~CC_HI_R31_ADJ; 1949 cc_status.mdep = CONST2_RTX (SFmode); 1950 return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\\ 1951orh 0x4000,%?r0,%?r31\;ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\\ 1952fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\ 1953fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\ 1954fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\"; 1955 } 1956 else 1957 return \"frcp.dd %2,%3\;fmul.dd %2,%3,%0\;fmov.dd %?f0,%4\;\\\ 1958ixfr %?r31,%R4\;fsub.dd %4,%0,%0\;\\\ 1959fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\ 1960fmul.dd %3,%0,%3\;fmul.dd %2,%3,%0\;fsub.dd %4,%0,%0\;\\\ 1961fmul.dd %3,%1,%3\;fmul.dd %0,%3,%0\"; 1962}") 1963 1964(define_insn "divsf3" 1965 [(set (match_operand:SF 0 "register_operand" "=&f") 1966 (div:SF (match_operand:SF 1 "register_operand" "f") 1967 (match_operand:SF 2 "register_operand" "f"))) 1968 (clobber (match_scratch:SF 3 "=&f")) 1969 (clobber (match_scratch:SF 4 "=&f"))] 1970 "" 1971 "* 1972{ 1973 CC_STATUS_PARTIAL_INIT; 1974 if (((cc_prev_status.flags & CC_KNOW_HI_R31) == 0) 1975 || (cc_prev_status.flags & CC_HI_R31_ADJ) 1976 || (cc_prev_status.mdep != CONST2_RTX (SFmode))) 1977 { 1978 cc_status.flags |= CC_KNOW_HI_R31; 1979 cc_status.flags &= ~CC_HI_R31_ADJ; 1980 cc_status.mdep = CONST2_RTX (SFmode); 1981 output_asm_insn (\"orh 0x4000,%?r0,%?r31\", operands); 1982 } 1983 return \"ixfr %?r31,%4\;frcp.ss %2,%0\;\\\ 1984fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;fmul.ss %0,%3,%0\;\\\ 1985fmul.ss %2,%0,%3\;fsub.ss %4,%3,%3\;\\\ 1986fmul.ss %1,%0,%4\;fmul.ss %3,%4,%0\"; 1987}") 1988 1989;; Shift instructions 1990 1991;; Optimized special case of shifting. 1992;; Must precede the general case. 1993 1994(define_insn "" 1995 [(set (match_operand:SI 0 "register_operand" "=r") 1996 (ashiftrt:SI (match_operand:SI 1 "memory_operand" "m") 1997 (const_int 24)))] 1998 "" 1999 "* 2000{ 2001 if (CONSTANT_ADDRESS_P (XEXP (operands[1], 0))) 2002 { 2003 CC_STATUS_INIT; 2004 cc_status.flags |= CC_KNOW_HI_R31 | CC_HI_R31_ADJ; 2005 cc_status.mdep = XEXP (operands[1], 0); 2006 return \"orh %h1,%?r0,%?r31\;ld.b %L1(%?r31),%0\"; 2007 } 2008 return \"ld.b %1,%0\"; 2009}") 2010 2011 2012;;- arithmetic shift instructions 2013(define_insn "ashlsi3" 2014 [(set (match_operand:SI 0 "register_operand" "=r") 2015 (ashift:SI (match_operand:SI 1 "register_operand" "r") 2016 (match_operand:SI 2 "shift_operand" "rn")))] 2017 "" 2018 "* 2019{ 2020 return \"shl %2,%1,%0\"; 2021}") 2022 2023(define_insn "ashlhi3" 2024 [(set (match_operand:HI 0 "register_operand" "=r") 2025 (ashift:HI (match_operand:HI 1 "register_operand" "r") 2026 (match_operand:HI 2 "shift_operand" "rn")))] 2027 "" 2028 "* 2029{ 2030 return \"shl %2,%1,%0\"; 2031}") 2032 2033(define_insn "ashlqi3" 2034 [(set (match_operand:QI 0 "register_operand" "=r") 2035 (ashift:QI (match_operand:QI 1 "register_operand" "r") 2036 (match_operand:QI 2 "shift_operand" "rn")))] 2037 "" 2038 "* 2039{ 2040 return \"shl %2,%1,%0\"; 2041}") 2042 2043(define_insn "ashrsi3" 2044 [(set (match_operand:SI 0 "register_operand" "=r") 2045 (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") 2046 (match_operand:SI 2 "shift_operand" "rn")))] 2047 "" 2048 "* 2049{ 2050 return \"shra %2,%1,%0\"; 2051}") 2052 2053(define_insn "lshrsi3" 2054 [(set (match_operand:SI 0 "register_operand" "=r") 2055 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 2056 (match_operand:SI 2 "shift_operand" "rn")))] 2057 "" 2058 "* 2059{ 2060 return \"shr %2,%1,%0\"; 2061}") 2062 2063;; Unconditional and other jump instructions 2064 2065(define_insn "jump" 2066 [(set (pc) (label_ref (match_operand 0 "" "")))] 2067 "" 2068 "* 2069{ 2070 return \"br %l0\;nop\"; 2071}") 2072 2073;; Here are two simple peepholes which fill the delay slot of 2074;; an unconditional branch. 2075 2076(define_peephole 2077 [(set (match_operand:SI 0 "register_operand" "=rf") 2078 (match_operand:SI 1 "single_insn_src_p" "gfG")) 2079 (set (pc) (label_ref (match_operand 2 "" "")))] 2080 "" 2081 "* return output_delayed_branch (\"br %l2\", operands, insn);") 2082 2083(define_peephole 2084 [(set (match_operand:SI 0 "memory_operand" "=m") 2085 (match_operand:SI 1 "reg_or_0_operand" "rfJ")) 2086 (set (pc) (label_ref (match_operand 2 "" "")))] 2087 "" 2088 "* return output_delayed_branch (\"br %l2\", operands, insn);") 2089 2090(define_insn "tablejump" 2091 [(set (pc) (match_operand:SI 0 "register_operand" "r")) 2092 (use (label_ref (match_operand 1 "" "")))] 2093 "" 2094 "bri %0\;nop") 2095 2096(define_peephole 2097 [(set (match_operand:SI 0 "memory_operand" "=m") 2098 (match_operand:SI 1 "reg_or_0_operand" "rfJ")) 2099 (set (pc) (match_operand:SI 2 "register_operand" "r")) 2100 (use (label_ref (match_operand 3 "" "")))] 2101 "" 2102 "* return output_delayed_branch (\"bri %2\", operands, insn);") 2103 2104;;- jump to subroutine 2105(define_expand "call" 2106 [(call (match_operand:SI 0 "memory_operand" "m") 2107 (match_operand 1 "" "i"))] 2108 ;; operand[2] is next_arg_register 2109 "" 2110 " 2111{ 2112 /* Make sure the address is just one reg and will stay that way. */ 2113 if (! call_insn_operand (operands[0], QImode)) 2114 operands[0] 2115 = change_address (operands[0], VOIDmode, 2116 copy_to_mode_reg (Pmode, XEXP (operands[0], 0))); 2117 if (INTVAL (operands[1]) > 0) 2118 { 2119 emit_move_insn (arg_pointer_rtx, stack_pointer_rtx); 2120 emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx)); 2121 } 2122}") 2123 2124;;- jump to subroutine 2125(define_insn "" 2126 [(call (match_operand:SI 0 "call_insn_operand" "m") 2127 (match_operand 1 "" "i"))] 2128 ;; operand[2] is next_arg_register 2129 "" 2130 "* 2131{ 2132 /* strip the MEM. */ 2133 operands[0] = XEXP (operands[0], 0); 2134 CC_STATUS_INIT; 2135 if (GET_CODE (operands[0]) == REG) 2136 return \"calli %0\;nop\"; 2137 return \"call %0\;nop\"; 2138}") 2139 2140(define_peephole 2141 [(set (match_operand:SI 0 "register_operand" "=rf") 2142 (match_operand:SI 1 "single_insn_src_p" "gfG")) 2143 (call (match_operand:SI 2 "memory_operand" "m") 2144 (match_operand 3 "" "i"))] 2145 ;;- Don't use operand 1 for most machines. 2146 "! reg_mentioned_p (operands[0], operands[2])" 2147 "* 2148{ 2149 /* strip the MEM. */ 2150 operands[2] = XEXP (operands[2], 0); 2151 if (GET_CODE (operands[2]) == REG) 2152 return output_delayed_branch (\"calli %2\", operands, insn); 2153 return output_delayed_branch (\"call %2\", operands, insn); 2154}") 2155 2156(define_peephole 2157 [(set (match_operand:SI 0 "memory_operand" "=m") 2158 (match_operand:SI 1 "reg_or_0_operand" "rfJ")) 2159 (call (match_operand:SI 2 "call_insn_operand" "m") 2160 (match_operand 3 "" "i"))] 2161 ;;- Don't use operand 1 for most machines. 2162 "" 2163 "* 2164{ 2165 /* strip the MEM. */ 2166 operands[2] = XEXP (operands[2], 0); 2167 if (GET_CODE (operands[2]) == REG) 2168 return output_delayed_branch (\"calli %2\", operands, insn); 2169 return output_delayed_branch (\"call %2\", operands, insn); 2170}") 2171 2172(define_expand "call_value" 2173 [(set (match_operand 0 "register_operand" "=rf") 2174 (call (match_operand:SI 1 "memory_operand" "m") 2175 (match_operand 2 "" "i")))] 2176 ;; operand 3 is next_arg_register 2177 "" 2178 " 2179{ 2180 /* Make sure the address is just one reg and will stay that way. */ 2181 if (! call_insn_operand (operands[1], QImode)) 2182 operands[1] 2183 = change_address (operands[1], VOIDmode, 2184 copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); 2185 if (INTVAL (operands[2]) > 0) 2186 { 2187 emit_move_insn (arg_pointer_rtx, stack_pointer_rtx); 2188 emit_insn (gen_rtx (USE, VOIDmode, arg_pointer_rtx)); 2189 } 2190}") 2191 2192(define_insn "" 2193 [(set (match_operand 0 "register_operand" "=rf") 2194 (call (match_operand:SI 1 "call_insn_operand" "m") 2195 (match_operand 2 "" "i")))] 2196 ;; operand 3 is next_arg_register 2197 "" 2198 "* 2199{ 2200 /* strip the MEM. */ 2201 operands[1] = XEXP (operands[1], 0); 2202 CC_STATUS_INIT; 2203 if (GET_CODE (operands[1]) == REG) 2204 return \"calli %1\;nop\"; 2205 return \"call %1\;nop\"; 2206}") 2207 2208(define_peephole 2209 [(set (match_operand:SI 0 "register_operand" "=rf") 2210 (match_operand:SI 1 "single_insn_src_p" "gfG")) 2211 (set (match_operand 2 "" "=rf") 2212 (call (match_operand:SI 3 "call_insn_operand" "m") 2213 (match_operand 4 "" "i")))] 2214 ;;- Don't use operand 4 for most machines. 2215 "! reg_mentioned_p (operands[0], operands[3])" 2216 "* 2217{ 2218 /* strip the MEM. */ 2219 operands[3] = XEXP (operands[3], 0); 2220 if (GET_CODE (operands[3]) == REG) 2221 return output_delayed_branch (\"calli %3\", operands, insn); 2222 return output_delayed_branch (\"call %3\", operands, insn); 2223}") 2224 2225(define_peephole 2226 [(set (match_operand:SI 0 "memory_operand" "=m") 2227 (match_operand:SI 1 "reg_or_0_operand" "rJf")) 2228 (set (match_operand 2 "" "=rf") 2229 (call (match_operand:SI 3 "call_insn_operand" "m") 2230 (match_operand 4 "" "i")))] 2231 ;;- Don't use operand 4 for most machines. 2232 "" 2233 "* 2234{ 2235 /* strip the MEM. */ 2236 operands[3] = XEXP (operands[3], 0); 2237 if (GET_CODE (operands[3]) == REG) 2238 return output_delayed_branch (\"calli %3\", operands, insn); 2239 return output_delayed_branch (\"call %3\", operands, insn); 2240}") 2241 2242;; Call subroutine returning any type. 2243 2244(define_expand "untyped_call" 2245 [(parallel [(call (match_operand 0 "" "") 2246 (const_int 0)) 2247 (match_operand 1 "" "") 2248 (match_operand 2 "" "")])] 2249 "" 2250 " 2251{ 2252 int i; 2253 2254 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); 2255 2256 for (i = 0; i < XVECLEN (operands[2], 0); i++) 2257 { 2258 rtx set = XVECEXP (operands[2], 0, i); 2259 emit_move_insn (SET_DEST (set), SET_SRC (set)); 2260 } 2261 2262 /* The optimizer does not know that the call sets the function value 2263 registers we stored in the result block. We avoid problems by 2264 claiming that all hard registers are used and clobbered at this 2265 point. */ 2266 emit_insn (gen_blockage ()); 2267 2268 DONE; 2269}") 2270 2271;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 2272;; all of memory. This blocks insns from being moved across this point. 2273 2274(define_insn "blockage" 2275 [(unspec_volatile [(const_int 0)] 0)] 2276 "" 2277 "") 2278 2279(define_insn "nop" 2280 [(const_int 0)] 2281 "" 2282 "nop") 2283 2284(define_insn "indirect_jump" 2285 [(set (pc) (match_operand:SI 0 "register_operand" "r"))] 2286 "" 2287 "bri %0") 2288 2289;; 2290;; A special insn that does the work to get setup just 2291;; before a table jump. 2292;; 2293(define_insn "" 2294 [(set (match_operand:SI 0 "register_operand" "=r") 2295 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") 2296 (label_ref (match_operand 2 "" "")))))] 2297 "" 2298 "* 2299{ 2300 CC_STATUS_INIT; 2301 return \"orh %H2,%?r0,%?r31\;or %L2,%?r31,%?r31\;ld.l %?r31(%1),%0\"; 2302}") 2303 2304(define_peephole 2305 [(set (match_operand:SI 0 "register_operand" "=rf") 2306 (match_operand:SI 1 "single_insn_src_p" "gfG")) 2307 (set (pc) (match_operand:SI 2 "register_operand" "r")) 2308 (use (label_ref (match_operand 3 "" "")))] 2309 "REGNO (operands[0]) != REGNO (operands[2])" 2310 "* return output_delayed_branch (\"bri %2\", operands, insn);") 2311