1;; GCC machine description for Matsushita MN10200 2;; Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. 3;; Contributed by Jeff Law (law@cygnus.com). 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;; Condition code settings. 28;; none - insn does not affect cc 29;; none_0hit - insn does not affect cc but it does modify operand 0 30;; This attribute is used to keep track of when operand 0 changes. 31;; See the description of NOTICE_UPDATE_CC for more info. 32;; set_znv - sets z,n,v to usable values; c is unknown. 33;; set_zn - sets z,n to usable values; v,c is unknown. 34;; compare - compare instruction 35;; clobber - value of cc is unknown 36(define_attr "cc" "none,none_0hit,set_znv,set_zn,compare,clobber" 37 (const_string "clobber")) 38 39;; ---------------------------------------------------------------------- 40;; MOVE INSTRUCTIONS 41;; ---------------------------------------------------------------------- 42;; 43;; Some general notes on move instructions. 44;; 45;; The hardware can't encode nop moves involving data registers, so 46;; we catch them and emit a nop instead. 47;; 48;; Loads/stores to/from address registers must be 16bit aligned, 49;; thus we avoid them for QImode. 50;; 51;; Stores from address registers always store 24bits, so avoid 52;; stores from address registers in HImode, SImode, and SFmode. 53;; 54;; As a result of the various problems using address registers in 55;; QImode, HImode, SImode, and SFmode, we discourage their use via 56;; '*' in their constraints. They're still allowed, but they're never 57;; the preferred class for insns with those modes. 58 59;; movqi 60 61(define_expand "movqi" 62 [(set (match_operand:QI 0 "general_operand" "") 63 (match_operand:QI 1 "general_operand" ""))] 64 "" 65 " 66{ 67 /* One of the ops has to be in a register */ 68 if (!register_operand (operand0, QImode) 69 && !register_operand (operand1, QImode)) 70 operands[1] = copy_to_mode_reg (QImode, operand1); 71}") 72 73;; We avoid memory operations involving address registers because we 74;; can't be sure they'll be suitably aligned. 75;; 76;; We also discourage holding QImode values in address registers. 77(define_insn "" 78 [(set (match_operand:QI 0 "general_operand" "=d,d,*a,d,d,m,d,*a,*a") 79 (match_operand:QI 1 "general_operand" "0,I,I,di,m,d,*a,d,i*a"))] 80 "register_operand (operands[0], QImode) 81 || register_operand (operands[1], QImode)" 82 "@ 83 nop 84 sub %0,%0 85 sub %0,%0 86 mov %S1,%0 87 movbu %1,%0 88 movb %1,%0 89 mov %1,%0 90 mov %1,%0 91 mov %1,%0" 92 [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) 93 94;; movhi 95 96(define_expand "movhi" 97 [(set (match_operand:HI 0 "general_operand" "") 98 (match_operand:HI 1 "general_operand" ""))] 99 "" 100 " 101{ 102 /* One of the ops has to be in a register */ 103 if (!register_operand (operand1, HImode) 104 && !register_operand (operand0, HImode)) 105 operands[1] = copy_to_mode_reg (HImode, operand1); 106}") 107 108(define_insn "" 109 [(set (match_operand:HI 0 "general_operand" "=d,d,*a,d,d,m,d,*a,*a,*a") 110 (match_operand:HI 1 "general_operand" "0,I,I,di,m,d,*a,d,i*a,m"))] 111 "register_operand (operands[0], HImode) 112 || register_operand (operands[1], HImode)" 113 "@ 114 nop 115 sub %0,%0 116 sub %0,%0 117 mov %s1,%0 118 mov %1,%0 119 mov %1,%0 120 mov %1,%0 121 mov %1,%0 122 mov %1,%0 123 mov %A1,%0" 124 [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) 125 126;; movpsi and helpers 127 128(define_expand "movpsi" 129 [(set (match_operand:PSI 0 "general_operand" "") 130 (match_operand:PSI 1 "general_operand" ""))] 131 "" 132 " 133{ 134 /* One of the ops has to be in a register */ 135 if (!register_operand (operand1, PSImode) 136 && !register_operand (operand0, PSImode)) 137 operands[1] = copy_to_mode_reg (PSImode, operand1); 138}") 139 140 141;; Constant and indexed addresses are not valid addresses for PSImode, 142;; therefore they won't be matched by the general movpsi pattern below. 143;; ??? We had patterns to handle indexed addresses, but they kept making 144;; us run out of regs, so they were eliminated. 145 146(define_insn "" 147 [(set (match_operand:PSI 0 "register_operand" "=a") 148 (match_operand:PSI 1 "constant_memory_operand" ""))] 149 "" 150 "mov %A1,%0" 151 [(set_attr "cc" "none_0hit")]) 152 153(define_insn "" 154 [(set (match_operand:PSI 0 "constant_memory_operand" "=X") 155 (match_operand:PSI 1 "register_operand" "a"))] 156 "" 157 "mov %1,%A0" 158 [(set_attr "cc" "none_0hit")]) 159 160;; We want to prefer address registers here because 24bit moves to/from 161;; memory are shorter and faster when done via address registers. 162(define_insn "" 163 [(set (match_operand:PSI 0 "general_operand" "=d,a?d,?da,a,m,?d,m") 164 (match_operand:PSI 1 "general_operand" "0,I,?dai,m,a,m,?d"))] 165 "register_operand (operands[0], PSImode) 166 || register_operand (operands[1], PSImode)" 167 "@ 168 nop 169 sub %0,%0 170 mov %1,%0 171 mov %A1,%0 172 mov %1,%A0 173 movx %A1,%0 174 movx %1,%A0" 175 [(set_attr "cc" "none,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) 176 177(define_expand "movsi" 178 [(set (match_operand:SI 0 "general_operand" "") 179 (match_operand:SI 1 "general_operand" ""))] 180 "" 181 " 182{ 183 /* One of the ops has to be in a register */ 184 if (!register_operand (operand1, SImode) 185 && !register_operand (operand0, SImode)) 186 operands[1] = copy_to_mode_reg (SImode, operand1); 187}") 188 189(define_insn "" 190 [(set (match_operand:SI 0 "general_operand" "=d,d,*a,dm,d,d,*a,*a,*a") 191 (match_operand:SI 1 "general_operand" "0,I,I,d,dim,*a,d,*a,i"))] 192 "register_operand (operands[0], SImode) 193 || register_operand (operands[1], SImode)" 194 "* 195{ 196 switch (which_alternative) 197 { 198 case 0: 199 return \"nop\"; 200 case 1: 201 case 2: 202 return \"sub %H0,%H0\;sub %L0,%L0\"; 203 case 3: 204 case 5: 205 case 6: 206 case 7: 207 return \"mov %H1,%H0\;mov %L1,%L0\"; 208 209 /* The next two cases try to optimize cases where one half 210 of the constant is all zeros, or when the two halves are 211 the same. */ 212 case 4: 213 case 8: 214 if (REG_P (operands[0]) 215 && GET_CODE (operands[1]) == CONST_INT 216 && (INTVAL (operands[1]) & 0xffff0000) == 0) 217 output_asm_insn (\"sub %H0,%H0\", operands); 218 else 219 output_asm_insn (\"mov %h1,%H0\", operands); 220 221 if (GET_CODE (operands[1]) == CONST_INT 222 && ((INTVAL (operands[1]) & 0xffff) 223 == ((INTVAL (operands[1]) >> 16) & 0xffff))) 224 output_asm_insn (\"mov %H0,%L0\", operands); 225 else if (GET_CODE (operands[1]) == CONST_INT 226 && (INTVAL (operands[1]) & 0xffff) == 0) 227 output_asm_insn (\"sub %L0,%L0\", operands); 228 else 229 output_asm_insn (\"mov %o1,%L0\", operands); 230 return \"\"; 231 default: 232 abort(); 233 } 234}" 235 [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) 236 237(define_expand "movsf" 238 [(set (match_operand:SF 0 "general_operand" "") 239 (match_operand:SF 1 "general_operand" ""))] 240 "" 241 " 242{ 243 /* One of the ops has to be in a register */ 244 if (!register_operand (operand1, SFmode) 245 && !register_operand (operand0, SFmode)) 246 operands[1] = copy_to_mode_reg (SFmode, operand1); 247}") 248 249(define_insn "" 250 [(set (match_operand:SF 0 "general_operand" "=d,d,*a,dm,d,d,*a,*a,*a") 251 (match_operand:SF 1 "general_operand" "0,G,G,d,dim,*a,d,*a,i"))] 252 "register_operand (operands[0], SFmode) 253 || register_operand (operands[1], SFmode)" 254 "* 255{ 256 switch (which_alternative) 257 { 258 case 0: 259 return \"nop\"; 260 261 case 1: 262 case 2: 263 return \"sub %H0,%H0\;sub %L0,%L0\"; 264 265 default: 266 { 267 long val = 0; 268 REAL_VALUE_TYPE rv; 269 270 if (GET_CODE (operands[1]) == CONST_DOUBLE) 271 { 272 REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]); 273 REAL_VALUE_TO_TARGET_SINGLE (rv, val); 274 } 275 276 if (GET_CODE (operands[1]) == CONST_INT) 277 val = INTVAL (operands[1]); 278 279 if ((GET_CODE (operands[1]) == CONST_INT 280 || GET_CODE (operands[1]) == CONST_DOUBLE) 281 && (val & 0xffff0000) == 0) 282 output_asm_insn (\"sub %H0,%H0\", operands); 283 else 284 output_asm_insn (\"mov %h1,%H0\", operands); 285 286 if (GET_CODE (operands[1]) == CONST_INT 287 && ((INTVAL (operands[1]) & 0xffff) 288 == ((INTVAL (operands[1]) >> 16) & 0xffff))) 289 output_asm_insn (\"mov %H0,%L0\", operands); 290 else if ((GET_CODE (operands[1]) == CONST_INT 291 || GET_CODE (operands[1]) == CONST_DOUBLE) 292 && (val & 0x0000ffff) == 0) 293 output_asm_insn (\"sub %L0,%L0\", operands); 294 else 295 output_asm_insn (\"mov %o1,%L0\", operands); 296 return \"\"; 297 } 298 } 299}" 300 [(set_attr "cc" "none,clobber,clobber,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit,none_0hit")]) 301 302 303;; ---------------------------------------------------------------------- 304;; TEST INSTRUCTIONS 305;; ---------------------------------------------------------------------- 306 307;; Go ahead and define tsthi and tstpsi so we can eliminate redundant tst insns 308;; when we start trying to optimize this port. 309(define_insn "tsthi" 310 [(set (cc0) (match_operand:HI 0 "nonimmediate_operand" "da"))] 311 "" 312 "* return output_tst (operands[0], insn);" 313 [(set_attr "cc" "set_znv")]) 314 315(define_insn "tstpsi" 316 [(set (cc0) (match_operand:PSI 0 "nonimmediate_operand" "da"))] 317 "" 318 "* return output_tst (operands[0], insn);" 319 [(set_attr "cc" "set_znv")]) 320 321(define_insn "" 322 [(set (cc0) (zero_extend:HI (match_operand:QI 0 "memory_operand" "d")))] 323 "" 324 "* return output_tst (operands[0], insn);" 325 [(set_attr "cc" "set_znv")]) 326 327(define_insn "" 328 [(set (cc0) (zero_extend:PSI (match_operand:QI 0 "memory_operand" "d")))] 329 "" 330 "* return output_tst (operands[0], insn);" 331 [(set_attr "cc" "set_znv")]) 332 333(define_insn "cmphi" 334 [(set (cc0) 335 (compare:HI (match_operand:HI 0 "nonimmediate_operand" "da") 336 (match_operand:HI 1 "general_operand" "dai")))] 337 "" 338 "cmp %1,%0" 339 [(set_attr "cc" "compare")]) 340 341(define_insn "cmppsi" 342 [(set (cc0) 343 (compare:PSI (match_operand:PSI 0 "nonimmediate_operand" "da") 344 (match_operand:PSI 1 "general_operand" "dai")))] 345 "" 346 "cmp %1,%0" 347 [(set_attr "cc" "compare")]) 348 349;; ---------------------------------------------------------------------- 350;; ADD INSTRUCTIONS 351;; ---------------------------------------------------------------------- 352 353(define_insn "addhi3" 354 [(set (match_operand:HI 0 "general_operand" "=d") 355 (plus:HI (match_operand:HI 1 "general_operand" "%0") 356 (match_operand:HI 2 "general_operand" "dai")))] 357 "" 358 "add %2,%0" 359 [(set_attr "cc" "set_zn")]) 360 361(define_insn "addpsi3" 362 [(set (match_operand:PSI 0 "general_operand" "=da") 363 (plus:PSI (match_operand:PSI 1 "general_operand" "%0") 364 (match_operand:PSI 2 "general_operand" "dai")))] 365 "" 366 "add %2,%0" 367 [(set_attr "cc" "set_zn")]) 368 369;; We want to avoid using explicit registers; reload won't tell us 370;; if it has to spill them and may generate incorrect code in such 371;; cases. 372;; 373;; So we call out to a library routine to perform 32bit add or 374;; subtract operations. 375;; 376;; operand2 must be nonmemory_operand so that we will accept CONST_INTs 377;; during initial code generation. 378(define_expand "addsi3" 379 [(set (match_operand:SI 0 "register_operand" "") 380 (plus:SI (match_operand:SI 1 "register_operand" "") 381 (match_operand:SI 2 "nonmemory_operand" "")))] 382 "" 383 " 384{ 385 /* If adding a CONST_INT, we are better off generating code ourselves. 386 387 During RTL generation we call out to library routines. 388 389 After RTL generation we can not call the library routines as 390 they need to push arguments via virtual_outgoing_args_rtx which 391 has already been instantiated. So, after RTL generation we just 392 FAIL and open code the operation. */ 393 if (GET_CODE (operands[2]) == CONST_INT) 394 { 395 if (!rtx_equal_p (operands[0], operands[1])) 396 emit_move_insn (operands[0], operands[1]); 397 emit_insn (gen_addsi3_const (operands[0], operands[0], operands[2])); 398 DONE; 399 } 400 else if (rtx_equal_function_value_matters) 401 { 402 rtx ret, insns; 403 404 start_sequence (); 405 ret = emit_library_call_value (gen_rtx_SYMBOL_REF (Pmode, \"__addsi3\"), 406 NULL_RTX, 1, SImode, 2, operands[1], 407 SImode, operands[2], SImode); 408 insns = get_insns (); 409 end_sequence (); 410 emit_libcall_block (insns, operands[0], ret, 411 gen_rtx_PLUS (SImode, operands[1], operands[2])); 412 DONE; 413 } 414 else 415 FAIL; 416}") 417 418(define_insn "addsi3_const" 419 [(set (match_operand:SI 0 "register_operand" "=d") 420 (plus:SI (match_operand:SI 1 "register_operand" "0") 421 (match_operand:SI 2 "const_int_operand" "i"))) 422 (clobber (match_scratch:SI 3 "=&d"))] 423 "" 424 "* 425{ 426 unsigned long value = INTVAL (operands[2]); 427 428 /* If only the high bits are set in the constant, then we only 429 need a single add operation. It might be better to catch this 430 at RTL expansion time. */ 431 if ((value & 0xffff) == 0) 432 return \"add %h2,%H0\"; 433 434 value >>= 16; 435 value &= 0xffff; 436 437 if (value == 0) 438 return \"sub %3,%3\;add %o2,%L0\;addc %3,%H0\"; 439 else 440 return \"mov %h2,%3\;add %o2,%L0\;addc %3,%H0\"; 441}" 442 [(set_attr "cc" "clobber")]) 443 444;; ---------------------------------------------------------------------- 445;; SUBTRACT INSTRUCTIONS 446;; ---------------------------------------------------------------------- 447 448(define_insn "subhi3" 449 [(set (match_operand:HI 0 "general_operand" "=d") 450 (minus:HI (match_operand:HI 1 "general_operand" "0") 451 (match_operand:HI 2 "general_operand" "dai")))] 452 "" 453 "sub %2,%0" 454 [(set_attr "cc" "set_zn")]) 455 456(define_insn "subpsi3" 457 [(set (match_operand:PSI 0 "general_operand" "=da") 458 (minus:PSI (match_operand:PSI 1 "general_operand" "0") 459 (match_operand:PSI 2 "general_operand" "dai")))] 460 "" 461 "sub %2,%0" 462 [(set_attr "cc" "set_zn")]) 463 464(define_expand "subsi3" 465 [(set (match_operand:SI 0 "register_operand" "") 466 (minus:SI (match_operand:SI 1 "register_operand" "") 467 (match_operand:SI 2 "register_operand" "")))] 468 "" 469 " 470{ 471 /* During RTL generation we call out to library routines. 472 473 After RTL generation we can not call the library routines as 474 they need to push arguments via virtual_outgoing_args_rtx which 475 has already been instantiated. So, after RTL generation we just 476 FAIL and open code the operation. */ 477 if (rtx_equal_function_value_matters) 478 { 479 rtx ret, insns; 480 481 start_sequence (); 482 ret = emit_library_call_value (gen_rtx_SYMBOL_REF (Pmode, \"__subsi3\"), 483 NULL_RTX, 1, SImode, 2, operands[1], 484 SImode, operands[2], SImode); 485 insns = get_insns (); 486 end_sequence (); 487 emit_libcall_block (insns, operands[0], ret, 488 gen_rtx_MINUS (SImode, operands[1], operands[2])); 489 DONE; 490 } 491 else 492 FAIL; 493}") 494 495;; There isn't a negate instruction, so we fake it. 496;; 497;; We used to expand this into patterns, but a single pattern 498;; actually generates better overall code. 499;; 500;; We could do HImode negations with a "not;add" sequence, but 501;; generally it's generated slightly worse code. 502;; 503;; The second alternative is not strictly necesasry, but helps 504;; when the register allocators start running short of registers. 505(define_insn "neghi2" 506 [(set (match_operand:HI 0 "general_operand" "=&d,d") 507 (neg:HI (match_operand:HI 1 "general_operand" "d,0")))] 508 "" 509 "@ 510 sub %0,%0\;sub %1,%0 511 not %0\;add 1,%0" 512 [(set_attr "cc" "set_zn")]) 513 514;; The not/and sequence won't work here. It's not clear if we'll 515;; ever need to provide an alternate sequence since this should 516;; be used much less frequently than neghi2. 517(define_insn "negpsi2" 518 [(set (match_operand:PSI 0 "general_operand" "=&d") 519 (neg:PSI (match_operand:PSI 1 "general_operand" "d")))] 520 "" 521 "sub %0,%0\;sub %1,%0" 522 [(set_attr "cc" "set_zn")]) 523 524;; Using a magic libcall that accepts its arguments in any 525;; data register pair has proven to be the most efficient 526;; and most compact way to represent negsi2. 527(define_insn "negsi2" 528 [(set (match_operand:SI 0 "register_operand" "=d") 529 (neg:SI (match_operand:SI 1 "register_operand" "0")))] 530 "" 531 "jsr ___negsi2_%0" 532 [(set_attr "cc" "clobber")]) 533 534;; ---------------------------------------------------------------------- 535;; MULTIPLY INSTRUCTIONS 536;; ---------------------------------------------------------------------- 537;; 538;; The mn10200 has HIxHI->SI widening multiply, but we get _severe_ 539;; code density regressions if we enable such a pattern. 540 541(define_insn "mulhi3" 542 [(set (match_operand:HI 0 "general_operand" "=d") 543 (mult:HI (match_operand:HI 1 "general_operand" "%0") 544 (match_operand:HI 2 "general_operand" "d")))] 545 "" 546 "mul %2,%0" 547 [(set_attr "cc" "set_zn")]) 548 549(define_insn "udivmodhi4" 550 [(set (match_operand:HI 0 "general_operand" "=d") 551 (udiv:HI (match_operand:HI 1 "general_operand" "0") 552 (match_operand:HI 2 "general_operand" "d"))) 553 (set (match_operand:HI 3 "general_operand" "=&d") 554 (umod:HI (match_dup 1) (match_dup 2)))] 555 "" 556 "* 557{ 558 if (zero_dreg) 559 output_asm_insn (\"mov %0,mdr\", &zero_dreg); 560 else 561 output_asm_insn (\"sub %3,%3\;mov %3,mdr\", operands); 562 563 if (find_reg_note (insn, REG_UNUSED, operands[3])) 564 return \"divu %2,%0\"; 565 else 566 return \"divu %2,%0\;mov mdr,%3\"; 567}" 568 [(set_attr "cc" "set_zn")]) 569 570 571;; ---------------------------------------------------------------------- 572;; AND INSTRUCTIONS 573;; ---------------------------------------------------------------------- 574 575(define_insn "andhi3" 576 [(set (match_operand:HI 0 "general_operand" "=d,d") 577 (and:HI (match_operand:HI 1 "general_operand" "%0,0") 578 (match_operand:HI 2 "general_operand" "M,di")))] 579 "" 580 "* 581{ 582 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xff) 583 return \"extxbu %0\"; 584 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x7fff) 585 return \"add %0,%0\;lsr %0\"; 586 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0xfffe) 587 return \"lsr %0\;add %0,%0\"; 588 return \"and %2,%0\"; 589}" 590 [(set_attr "cc" "none_0hit,set_znv")]) 591 592;; This expander + pattern exist only to allow trampolines to be aligned 593;; in the stack. 594(define_expand "andpsi3" 595 [(set (match_operand:PSI 0 "general_operand" "") 596 (and:PSI (match_operand:PSI 1 "general_operand" "") 597 (match_operand:PSI 2 "const_int_operand" "")))] 598 "" 599 " 600{ 601 if (GET_CODE (operands[2]) != CONST_INT 602 || (INTVAL (operands[2]) & 0xff0000) != 0xff0000) 603 FAIL; 604}") 605 606(define_insn "" 607 [(set (match_operand:PSI 0 "general_operand" "=d") 608 (and:PSI (match_operand:PSI 1 "general_operand" "%0") 609 (match_operand:PSI 2 "const_int_operand" "i")))] 610 "GET_CODE (operands[2]) == CONST_INT 611 && (INTVAL (operands[2]) & 0xff0000) == 0xff0000" 612 "and %2,%0" 613 [(set_attr "cc" "clobber")]) 614 615;; ---------------------------------------------------------------------- 616;; OR INSTRUCTIONS 617;; ---------------------------------------------------------------------- 618 619(define_insn "iorhi3" 620 [(set (match_operand:HI 0 "general_operand" "=d") 621 (ior:HI (match_operand:HI 1 "general_operand" "%0") 622 (match_operand:HI 2 "general_operand" "di")))] 623 "" 624 "or %2,%0" 625 [(set_attr "cc" "set_znv")]) 626 627;; ---------------------------------------------------------------------- 628;; XOR INSTRUCTIONS 629;; ---------------------------------------------------------------------- 630 631(define_insn "xorhi3" 632 [(set (match_operand:HI 0 "general_operand" "=d") 633 (xor:HI (match_operand:HI 1 "general_operand" "%0") 634 (match_operand:HI 2 "general_operand" "di")))] 635 "" 636 "xor %2,%0" 637 [(set_attr "cc" "set_znv")]) 638 639;; ---------------------------------------------------------------------- 640;; NOT INSTRUCTIONS 641;; ---------------------------------------------------------------------- 642 643(define_insn "one_cmplhi2" 644 [(set (match_operand:HI 0 "general_operand" "=d") 645 (not:HI (match_operand:HI 1 "general_operand" "0")))] 646 "" 647 "not %0" 648 [(set_attr "cc" "set_znv")]) 649 650 651;; ----------------------------------------------------------------- 652;; BIT INSTRUCTIONS 653;; ----------------------------------------------------------------- 654 655;; These clears a constant set of bits in memory or in a register. 656;; We must support register destinations to make reload happy. 657(define_insn "" 658 [(set (match_operand:QI 0 "general_operand" "+R,d") 659 (subreg:QI 660 (and:HI (subreg:HI (match_dup 0) 0) 661 (match_operand 1 "const_int_operand" "")) 0)) 662 (clobber (match_scratch:HI 2 "=&d,X"))] 663 "" 664 "@ 665 mov %N1,%2\;bclr %2,%0 666 and %1,%0" 667 [(set_attr "cc" "clobber")]) 668 669;; This clears a variable set of bits in memory or in a register. 670(define_insn "" 671 [(set (match_operand:QI 0 "general_operand" "+R,d") 672 (subreg:QI 673 (and:HI (subreg:HI (match_dup 0) 0) 674 (not:HI (match_operand:HI 1 "general_operand" "d,d"))) 0)) 675 (clobber (match_scratch:HI 2 "=X,&d"))] 676 "" 677 "@ 678 bclr %1,%0 679 mov %1,%2\;not %2\;and %2,%0" 680 [(set_attr "cc" "clobber")]) 681 682(define_insn "" 683 [(set (match_operand:QI 0 "general_operand" "+R,d") 684 (subreg:QI 685 (and:HI (not:HI (match_operand:HI 1 "general_operand" "d,d")) 686 (subreg:HI (match_dup 0) 0)) 0)) 687 (clobber (match_scratch:HI 2 "=X,&d"))] 688 "" 689 "@ 690 bclr %1,%0 691 mov %1,%2\;not %2\;and %2,%0" 692 [(set_attr "cc" "clobber")]) 693 694;; These set bits in memory. 695(define_insn "" 696 [(set (match_operand:QI 0 "general_operand" "+R,d") 697 (subreg:QI 698 (ior:HI (subreg:HI (match_dup 0) 0) 699 (match_operand:HI 1 "general_operand" "d,d")) 0))] 700 "" 701 "@ 702 bset %1,%0 703 or %1,%0" 704 [(set_attr "cc" "clobber")]) 705 706(define_insn "" 707 [(set (match_operand:QI 0 "general_operand" "+R,d") 708 (subreg:QI 709 (ior:HI (match_operand:HI 1 "general_operand" "d,d") 710 (subreg:HI (match_dup 0) 0)) 0))] 711 "" 712 "@ 713 bset %1,%0 714 or %1,%0" 715 [(set_attr "cc" "clobber")]) 716 717;; Not any shorter/faster than using cmp, but it might save a 718;; register if the result of the AND isn't ever used. 719 720(define_insn "" 721 [(set (cc0) 722 (zero_extract:HI (match_operand:HI 0 "general_operand" "d") 723 (match_operand 1 "const_int_operand" "") 724 (match_operand 2 "const_int_operand" "")))] 725 "" 726 "* 727{ 728 int len = INTVAL (operands[1]); 729 int bit = INTVAL (operands[2]); 730 int mask = 0; 731 rtx xoperands[2]; 732 733 while (len > 0) 734 { 735 mask |= (1 << bit); 736 bit++; 737 len--; 738 } 739 740 xoperands[0] = operands[0]; 741 xoperands[1] = GEN_INT (mask); 742 output_asm_insn (\"btst %1,%0\", xoperands); 743 return \"\"; 744}" 745 [(set_attr "cc" "clobber")]) 746 747(define_insn "" 748 [(set (cc0) (and:HI (match_operand:HI 0 "general_operand" "d") 749 (match_operand:HI 1 "const_int_operand" "i")))] 750 "" 751 "btst %1,%0" 752 [(set_attr "cc" "clobber")]) 753 754 755;; ---------------------------------------------------------------------- 756;; JUMP INSTRUCTIONS 757;; ---------------------------------------------------------------------- 758 759;; Conditional jump instructions 760 761(define_expand "ble" 762 [(set (pc) 763 (if_then_else (le (cc0) 764 (const_int 0)) 765 (label_ref (match_operand 0 "" "")) 766 (pc)))] 767 "" 768 "") 769 770(define_expand "bleu" 771 [(set (pc) 772 (if_then_else (leu (cc0) 773 (const_int 0)) 774 (label_ref (match_operand 0 "" "")) 775 (pc)))] 776 "" 777 "") 778 779(define_expand "bge" 780 [(set (pc) 781 (if_then_else (ge (cc0) 782 (const_int 0)) 783 (label_ref (match_operand 0 "" "")) 784 (pc)))] 785 "" 786 "") 787 788(define_expand "bgeu" 789 [(set (pc) 790 (if_then_else (geu (cc0) 791 (const_int 0)) 792 (label_ref (match_operand 0 "" "")) 793 (pc)))] 794 "" 795 "") 796 797(define_expand "blt" 798 [(set (pc) 799 (if_then_else (lt (cc0) 800 (const_int 0)) 801 (label_ref (match_operand 0 "" "")) 802 (pc)))] 803 "" 804 "") 805 806(define_expand "bltu" 807 [(set (pc) 808 (if_then_else (ltu (cc0) 809 (const_int 0)) 810 (label_ref (match_operand 0 "" "")) 811 (pc)))] 812 "" 813 "") 814 815(define_expand "bgt" 816 [(set (pc) 817 (if_then_else (gt (cc0) 818 (const_int 0)) 819 (label_ref (match_operand 0 "" "")) 820 (pc)))] 821 "" 822 "") 823 824(define_expand "bgtu" 825 [(set (pc) 826 (if_then_else (gtu (cc0) 827 (const_int 0)) 828 (label_ref (match_operand 0 "" "")) 829 (pc)))] 830 "" 831 "") 832 833(define_expand "beq" 834 [(set (pc) 835 (if_then_else (eq (cc0) 836 (const_int 0)) 837 (label_ref (match_operand 0 "" "")) 838 (pc)))] 839 "" 840 "") 841 842(define_expand "bne" 843 [(set (pc) 844 (if_then_else (ne (cc0) 845 (const_int 0)) 846 (label_ref (match_operand 0 "" "")) 847 (pc)))] 848 "" 849 "") 850 851(define_insn "" 852 [(set (pc) 853 (if_then_else (match_operator 1 "comparison_operator" 854 [(cc0) (const_int 0)]) 855 (label_ref (match_operand 0 "" "")) 856 (pc)))] 857 "" 858 "* 859{ 860 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0 861 && (GET_CODE (operands[1]) == GT 862 || GET_CODE (operands[1]) == GE 863 || GET_CODE (operands[1]) == LE 864 || GET_CODE (operands[1]) == LT)) 865 return 0; 866 867 if (GET_MODE (SET_SRC (PATTERN (PREV_INSN (insn)))) == PSImode) 868 return \"b%b1x %0\"; 869 else 870 return \"b%b1 %0\"; 871}" 872 [(set_attr "cc" "none")]) 873 874(define_insn "" 875 [(set (pc) 876 (if_then_else (match_operator 1 "comparison_operator" 877 [(cc0) (const_int 0)]) 878 (pc) 879 (label_ref (match_operand 0 "" ""))))] 880 "" 881 "* 882{ 883 if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0 884 && (GET_CODE (operands[1]) == GT 885 || GET_CODE (operands[1]) == GE 886 || GET_CODE (operands[1]) == LE 887 || GET_CODE (operands[1]) == LT)) 888 return 0; 889 890 if (GET_MODE (SET_SRC (PATTERN (PREV_INSN (insn)))) == PSImode) 891 return \"b%B1x %0\"; 892 else 893 return \"b%B1 %0\"; 894}" 895 [(set_attr "cc" "none")]) 896 897(define_insn "jump" 898 [(set (pc) 899 (label_ref (match_operand 0 "" "")))] 900 "" 901 "jmp %l0" 902 [(set_attr "cc" "none")]) 903 904(define_insn "indirect_jump" 905 [(set (pc) (match_operand:PSI 0 "register_operand" "a"))] 906 "" 907 "jmp (%0)" 908 [(set_attr "cc" "none")]) 909 910(define_insn "tablejump" 911 [(set (pc) (match_operand:PSI 0 "register_operand" "a")) 912 (use (label_ref (match_operand 1 "" "")))] 913 "" 914 "jmp (%0)" 915 [(set_attr "cc" "none")]) 916 917;; Call subroutine with no return value. 918 919(define_expand "call" 920 [(call (match_operand:QI 0 "general_operand" "") 921 (match_operand:HI 1 "general_operand" ""))] 922 "" 923 " 924{ 925 if (! call_address_operand (XEXP (operands[0], 0), VOIDmode)) 926 XEXP (operands[0], 0) = force_reg (PSImode, XEXP (operands[0], 0)); 927 emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1])); 928 DONE; 929}") 930 931(define_insn "call_internal" 932 [(call (mem:QI (match_operand:PSI 0 "call_address_operand" "aS")) 933 (match_operand:HI 1 "general_operand" "g"))] 934 "" 935 "jsr %C0" 936 [(set_attr "cc" "clobber")]) 937 938;; Call subroutine, returning value in operand 0 939;; (which must be a hard register). 940 941(define_expand "call_value" 942 [(set (match_operand 0 "" "") 943 (call (match_operand:QI 1 "general_operand" "") 944 (match_operand:HI 2 "general_operand" "")))] 945 "" 946 " 947{ 948 if (! call_address_operand (XEXP (operands[1], 0), VOIDmode)) 949 XEXP (operands[1], 0) = force_reg (PSImode, XEXP (operands[1], 0)); 950 emit_call_insn (gen_call_value_internal (operands[0], 951 XEXP (operands[1], 0), 952 operands[2])); 953 DONE; 954}") 955 956(define_insn "call_value_internal" 957 [(set (match_operand 0 "" "=da") 958 (call (mem:QI (match_operand:PSI 1 "call_address_operand" "aS")) 959 (match_operand:HI 2 "general_operand" "g")))] 960 "" 961 "jsr %C1" 962 [(set_attr "cc" "clobber")]) 963 964(define_expand "untyped_call" 965 [(parallel [(call (match_operand 0 "" "") 966 (const_int 0)) 967 (match_operand 1 "" "") 968 (match_operand 2 "" "")])] 969 "" 970 " 971{ 972 int i; 973 974 emit_call_insn (gen_call (operands[0], const0_rtx)); 975 976 for (i = 0; i < XVECLEN (operands[2], 0); i++) 977 { 978 rtx set = XVECEXP (operands[2], 0, i); 979 emit_move_insn (SET_DEST (set), SET_SRC (set)); 980 } 981 DONE; 982}") 983 984(define_insn "nop" 985 [(const_int 0)] 986 "" 987 "nop" 988 [(set_attr "cc" "none")]) 989 990;; ---------------------------------------------------------------------- 991;; EXTEND INSTRUCTIONS 992;; ---------------------------------------------------------------------- 993 994(define_insn "zero_extendqihi2" 995 [(set (match_operand:HI 0 "general_operand" "=d,d,d") 996 (zero_extend:HI 997 (match_operand:QI 1 "general_operand" "0,di,m")))] 998 "" 999 "@ 1000 extxbu %0 1001 mov %1,%0\;extxbu %0 1002 movbu %1,%0" 1003 [(set_attr "cc" "none_0hit")]) 1004 1005(define_insn "zero_extendqipsi2" 1006 [(set (match_operand:PSI 0 "general_operand" "=d,d,d") 1007 (zero_extend:PSI 1008 (match_operand:QI 1 "general_operand" "0,di,m")))] 1009 "" 1010 "@ 1011 extxbu %0 1012 mov %1,%0\;extxbu %0 1013 movbu %1,%0" 1014 [(set_attr "cc" "none_0hit")]) 1015 1016(define_insn "zero_extendqisi2" 1017 [(set (match_operand:SI 0 "general_operand" "=d,d,d") 1018 (zero_extend:SI 1019 (match_operand:QI 1 "general_operand" "0,di,m")))] 1020 "" 1021 "@ 1022 extxbu %L0\;sub %H0,%H0 1023 mov %1,%L0\;extxbu %L0\;sub %H0,%H0 1024 movbu %1,%L0\;sub %H0,%H0" 1025 [(set_attr "cc" "clobber")]) 1026 1027(define_insn "zero_extendhipsi2" 1028 [(set (match_operand:PSI 0 "general_operand" "=d,d,d") 1029 (zero_extend:PSI 1030 (match_operand:HI 1 "general_operand" "0,di,m")))] 1031 "" 1032 "@ 1033 extxu %0 1034 mov %1,%0\;extxu %0 1035 mov %1,%0\;extxu %0" 1036 [(set_attr "cc" "none_0hit")]) 1037 1038(define_insn "zero_extendhisi2" 1039 [(set (match_operand:SI 0 "general_operand" "=d,d") 1040 (zero_extend:SI 1041 (match_operand:HI 1 "general_operand" "0,dim")))] 1042 "" 1043 "@ 1044 sub %H0,%H0 1045 mov %1,%L0\;sub %H0,%H0" 1046 [(set_attr "cc" "clobber,clobber")]) 1047 1048;; The last alternative is necessary because the second operand might 1049;; have been the frame pointer. The frame pointer would get replaced 1050;; by (plus (stack_pointer) (const_int)). 1051;; 1052;; Reload would think that it only needed a PSImode register in 1053;; push_reload and at the start of allocate_reload_regs. However, 1054;; at the end of allocate_reload_reg it would realize that the 1055;; reload register must also be valid for SImode, and if it was 1056;; not valid reload would abort. 1057(define_insn "zero_extendpsisi2" 1058 [(set (match_operand:SI 0 "register_operand" "=d,?d,?*d,?*d") 1059 (zero_extend:SI (match_operand:PSI 1 "extendpsi_operand" 1060 "m,?0,?*dai,Q")))] 1061 "" 1062 "@ 1063 mov %L1,%L0\;movbu %H1,%H0 1064 jsr ___zero_extendpsisi2_%0 1065 mov %1,%L0\;jsr ___zero_extendpsisi2_%0 1066 mov a3,%L0\;add %Z1,%L0\;jsr ___zero_extendpsisi2_%0" 1067 [(set_attr "cc" "clobber")]) 1068 1069;;- sign extension instructions 1070 1071(define_insn "extendqihi2" 1072 [(set (match_operand:HI 0 "general_operand" "=d,d,d") 1073 (sign_extend:HI 1074 (match_operand:QI 1 "general_operand" "0,di,m")))] 1075 "" 1076 "* 1077{ 1078 if (which_alternative == 0) 1079 return \"extxb %0\"; 1080 else if (which_alternative == 1) 1081 return \"mov %1,%0\;extxb %0\"; 1082 else if (GET_CODE (XEXP (operands[1], 0)) == REG) 1083 return \"movbu %1,%0\;extxb %0\"; 1084 else 1085 return \"movb %1,%0\"; 1086}" 1087 [(set_attr "cc" "none_0hit")]) 1088 1089(define_insn "extendqipsi2" 1090 [(set (match_operand:PSI 0 "general_operand" "=d,d,d") 1091 (sign_extend:PSI 1092 (match_operand:QI 1 "general_operand" "0,di,m")))] 1093 "" 1094 "* 1095{ 1096 if (which_alternative == 0) 1097 return \"extxb %0\"; 1098 else if (which_alternative == 1) 1099 return \"mov %1,%0\;extxb %0\"; 1100 else if (GET_CODE (XEXP (operands[1], 0)) == REG) 1101 return \"movbu %1,%0\;extxb %0\"; 1102 else 1103 return \"movb %1,%0\"; 1104}" 1105 [(set_attr "cc" "none_0hit")]) 1106 1107(define_insn "extendqisi2" 1108 [(set (match_operand:SI 0 "general_operand" "=d,d,d") 1109 (sign_extend:SI 1110 (match_operand:QI 1 "general_operand" "0,di,m")))] 1111 "" 1112 "* 1113{ 1114 if (which_alternative == 0) 1115 return \"extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\"; 1116 else if (which_alternative == 1) 1117 return \"mov %1,%L0\;extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\"; 1118 else if (GET_CODE (XEXP (operands[1], 0)) == REG) 1119 return \"movbu %1,%L0\;extxb %L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\"; 1120 else 1121 return \"movb %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0\"; 1122}" 1123 [(set_attr "cc" "clobber")]) 1124 1125(define_insn "extendhipsi2" 1126 [(set (match_operand:PSI 0 "general_operand" "=d,d,d") 1127 (sign_extend:PSI 1128 (match_operand:HI 1 "general_operand" "0,di,m")))] 1129 "" 1130 "@ 1131 extx %0 1132 mov %1,%0\;extx %0 1133 mov %1,%0" 1134 [(set_attr "cc" "none_0hit")]) 1135 1136(define_insn "extendhisi2" 1137 [(set (match_operand:SI 0 "general_operand" "=d,d,d") 1138 (sign_extend:SI 1139 (match_operand:HI 1 "general_operand" "0,di,m")))] 1140 "" 1141 "@ 1142 mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0 1143 mov %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0 1144 mov %1,%L0\;mov %L0,%H0\;add %H0,%H0\;subc %H0,%H0" 1145 [(set_attr "cc" "clobber")]) 1146 1147;; The last alternative is necessary because the second operand might 1148;; have been the frame pointer. The frame pointer would get replaced 1149;; by (plus (stack_pointer) (const_int)). 1150;; 1151;; Reload would think that it only needed a PSImode register in 1152;; push_reload and at the start of allocate_reload_regs. However, 1153;; at the end of allocate_reload_reg it would realize that the 1154;; reload register must also be valid for SImode, and if it was 1155;; not valid reload would abort. 1156(define_insn "extendpsisi2" 1157 [(set (match_operand:SI 0 "general_operand" "=d,?d,?*d,?*d") 1158 (sign_extend:SI (match_operand:PSI 1 "extendpsi_operand" 1159 "m,?0,?*dai,Q")))] 1160 "" 1161 "@ 1162 mov %L1,%L0\;movb %H1,%H0 1163 jsr ___sign_extendpsisi2_%0 1164 mov %1,%L0\;jsr ___sign_extendpsisi2_%0 1165 mov a3,%L0\;add %Z1,%L0\;jsr ___sign_extendpsisi2_%0" 1166 [(set_attr "cc" "clobber")]) 1167 1168(define_insn "truncsipsi2" 1169 [(set (match_operand:PSI 0 "general_operand" "=a,?d,?*d,da") 1170 (truncate:PSI (match_operand:SI 1 "psimode_truncation_operand" "m,?m,?*d,i")))] 1171 "" 1172 "@ 1173 mov %1,%0 1174 movx %A1,%0 1175 jsr ___truncsipsi2_%1_%0 1176 mov %1,%0" 1177 [(set_attr "cc" "clobber")]) 1178 1179 1180;; Combine should be simplifying this stuff, but isn't. 1181;; 1182(define_insn "" 1183 [(set (match_operand:SI 0 "general_operand" "=d,d,d") 1184 (sign_extend:SI 1185 (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m"))))] 1186 "" 1187 "@ 1188 extxbu %L0\;sub %H0,%H0 1189 mov %1,%L0\;extxbu %L0\;sub %H0,%H0 1190 movbu %1,%L0\;sub %H0,%H0" 1191 [(set_attr "cc" "clobber")]) 1192 1193(define_insn "" 1194 [(set (match_operand:PSI 0 "general_operand" "=d,d,d") 1195 (truncate:PSI 1196 (sign_extend:SI (match_operand:QI 1 "general_operand" "0,di,m"))))] 1197 "" 1198 "* 1199{ 1200 if (which_alternative == 0) 1201 return \"extxb %0\"; 1202 else if (which_alternative == 1) 1203 return \"mov %1,%0\;extxb %0\"; 1204 else if (GET_CODE (XEXP (operands[1], 0)) == REG) 1205 return \"movbu %1,%0\;extxb %0\"; 1206 else 1207 return \"movb %1,%0\"; 1208}" 1209 [(set_attr "cc" "none_0hit")]) 1210 1211(define_insn "" 1212 [(set (match_operand:PSI 0 "general_operand" "=d,d,d") 1213 (truncate:PSI 1214 (sign_extend:SI (match_operand:HI 1 "general_operand" "0,di,m"))))] 1215 "" 1216 "@ 1217 extx %0 1218 mov %1,%0\;extx %0 1219 mov %1,%0" 1220 [(set_attr "cc" "none_0hit")]) 1221 1222(define_insn "" 1223 [(set (match_operand:PSI 0 "general_operand" "=d,d,d") 1224 (truncate:PSI 1225 (sign_extend:SI 1226 (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m")))))] 1227 "" 1228 "@ 1229 extxbu %0 1230 mov %1,%0\;extxbu %0 1231 movbu %1,%0" 1232 [(set_attr "cc" "none_0hit")]) 1233 1234(define_insn "" 1235 [(set (match_operand:PSI 0 "general_operand" "=d,d,d") 1236 (truncate:PSI 1237 (zero_extend:SI (match_operand:HI 1 "general_operand" "0,di,m"))))] 1238 "" 1239 "@ 1240 extxu %0 1241 mov %1,%0\;extxu %0 1242 mov %1,%0\;extxu %0" 1243 [(set_attr "cc" "none_0hit")]) 1244 1245(define_insn "" 1246 [(set (match_operand:PSI 0 "general_operand" "=d,d,d") 1247 (truncate:PSI 1248 (zero_extend:SI (match_operand:QI 1 "general_operand" "0,di,m"))))] 1249 "" 1250 "@ 1251 extxbu %0 1252 mov %1,%0\;extxbu %0 1253 movbu %1,%0" 1254 [(set_attr "cc" "none_0hit")]) 1255 1256;; ---------------------------------------------------------------------- 1257;; SHIFTS 1258;; ---------------------------------------------------------------------- 1259 1260;; If the shift count is small, we expand it into several single bit 1261;; shift insns. Otherwise we expand into a generic shift insn which 1262;; handles larger shift counts, shift by variable amounts, etc. 1263(define_expand "ashlhi3" 1264 [(set (match_operand:HI 0 "general_operand" "") 1265 (ashift:HI (match_operand:HI 1 "general_operand" "") 1266 (match_operand:HI 2 "general_operand" "")))] 1267 "" 1268 " 1269{ 1270 /* This is an experiment to see if exposing more of the underlying 1271 operations results in better code. */ 1272 if (GET_CODE (operands[2]) == CONST_INT 1273 && INTVAL (operands[2]) <= 4) 1274 { 1275 int count = INTVAL (operands[2]); 1276 emit_move_insn (operands[0], operands[1]); 1277 while (count > 0) 1278 { 1279 emit_insn (gen_rtx_SET (HImode, operands[0], 1280 gen_rtx_ASHIFT (HImode, 1281 operands[0], GEN_INT (1)))); 1282 count--; 1283 } 1284 DONE; 1285 } 1286 else 1287 { 1288 expand_a_shift (HImode, ASHIFT, operands); 1289 DONE; 1290 } 1291}") 1292 1293;; ASHIFT one bit. 1294(define_insn "" 1295 [(set (match_operand:HI 0 "general_operand" "=d") 1296 (ashift:HI (match_operand:HI 1 "general_operand" "0") 1297 (const_int 1)))] 1298 "" 1299 "add %0,%0" 1300 [(set_attr "cc" "set_zn")]) 1301 1302(define_expand "lshrhi3" 1303 [(set (match_operand:HI 0 "general_operand" "") 1304 (lshiftrt:HI (match_operand:HI 1 "general_operand" "") 1305 (match_operand:HI 2 "general_operand" "")))] 1306 "" 1307 " 1308{ 1309 /* This is an experiment to see if exposing more of the underlying 1310 operations results in better code. */ 1311 if (GET_CODE (operands[2]) == CONST_INT 1312 && INTVAL (operands[2]) <= 4) 1313 { 1314 int count = INTVAL (operands[2]); 1315 emit_move_insn (operands[0], operands[1]); 1316 while (count > 0) 1317 { 1318 emit_insn (gen_rtx_SET (HImode, operands[0], 1319 gen_rtx_LSHIFTRT (HImode, 1320 operands[0], 1321 GEN_INT (1)))); 1322 count--; 1323 } 1324 DONE; 1325 } 1326 else 1327 { 1328 expand_a_shift (HImode, LSHIFTRT, operands); 1329 DONE; 1330 } 1331}") 1332 1333;; LSHIFTRT one bit. 1334(define_insn "" 1335 [(set (match_operand:HI 0 "general_operand" "=d") 1336 (lshiftrt:HI (match_operand:HI 1 "general_operand" "0") 1337 (const_int 1)))] 1338 "" 1339 "lsr %0" 1340 [(set_attr "cc" "set_znv")]) 1341 1342(define_expand "ashrhi3" 1343 [(set (match_operand:HI 0 "general_operand" "") 1344 (ashiftrt:HI (match_operand:HI 1 "general_operand" "") 1345 (match_operand:HI 2 "general_operand" "")))] 1346 "" 1347 " 1348{ 1349 /* This is an experiment to see if exposing more of the underlying 1350 operations results in better code. */ 1351 if (GET_CODE (operands[2]) == CONST_INT 1352 && INTVAL (operands[2]) <= 4) 1353 { 1354 int count = INTVAL (operands[2]); 1355 emit_move_insn (operands[0], operands[1]); 1356 while (count > 0) 1357 { 1358 emit_insn (gen_rtx_SET (HImode, operands[0], 1359 gen_rtx_ASHIFTRT (HImode, operands[0], 1360 GEN_INT (1)))); 1361 count--; 1362 } 1363 DONE; 1364 } 1365 else 1366 { 1367 expand_a_shift (HImode, ASHIFTRT, operands); 1368 DONE; 1369 } 1370}") 1371 1372;; ASHIFTRT one bit. 1373(define_insn "" 1374 [(set (match_operand:HI 0 "general_operand" "=d") 1375 (ashiftrt:HI (match_operand:HI 1 "general_operand" "0") 1376 (const_int 1)))] 1377 "" 1378 "asr %0" 1379 [(set_attr "cc" "set_znv")]) 1380 1381;; And the general HImode shift pattern. Handles both shift by constants 1382;; and shift by variable counts. 1383(define_insn "" 1384 [(set (match_operand:HI 0 "general_operand" "=d,d") 1385 (match_operator:HI 3 "nshift_operator" 1386 [ (match_operand:HI 1 "general_operand" "0,0") 1387 (match_operand:HI 2 "general_operand" "KL,dan")])) 1388 (clobber (match_scratch:HI 4 "=X,&d"))] 1389 "" 1390 "* return emit_a_shift (insn, operands);" 1391 [(set_attr "cc" "clobber")]) 1392 1393;; We expect only ASHIFT with constant shift counts to be common for 1394;; PSImode, so we optimize just that case. For all other cases we 1395;; extend the value to SImode and perform the shift in SImode. 1396(define_expand "ashlpsi3" 1397 [(set (match_operand:PSI 0 "general_operand" "") 1398 (ashift:PSI (match_operand:PSI 1 "general_operand" "") 1399 (match_operand:HI 2 "general_operand" "")))] 1400 "" 1401 " 1402{ 1403 /* This is an experiment to see if exposing more of the underlying 1404 operations results in better code. */ 1405 if (GET_CODE (operands[2]) == CONST_INT 1406 && INTVAL (operands[2]) <= 7) 1407 { 1408 int count = INTVAL (operands[2]); 1409 emit_move_insn (operands[0], operands[1]); 1410 while (count > 0) 1411 { 1412 emit_insn (gen_rtx_SET (PSImode, operands[0], 1413 gen_rtx_ASHIFT (PSImode, 1414 operands[0], GEN_INT (1)))); 1415 count--; 1416 } 1417 DONE; 1418 } 1419 else 1420 { 1421 expand_a_shift (PSImode, ASHIFT, operands); 1422 DONE; 1423 } 1424}") 1425 1426;; ASHIFT one bit. 1427(define_insn "" 1428 [(set (match_operand:PSI 0 "general_operand" "=d") 1429 (ashift:PSI (match_operand:PSI 1 "general_operand" "0") 1430 (const_int 1)))] 1431 "" 1432 "add %0,%0" 1433 [(set_attr "cc" "set_zn")]) 1434 1435(define_expand "lshrpsi3" 1436 [(set (match_operand:PSI 0 "general_operand" "") 1437 (lshiftrt:PSI (match_operand:PSI 1 "general_operand" "") 1438 (match_operand:HI 2 "general_operand" "")))] 1439 "" 1440 " 1441{ 1442 rtx reg = gen_reg_rtx (SImode); 1443 1444 emit_insn (gen_zero_extendpsisi2 (reg, operands[1])); 1445 reg = expand_binop (SImode, lshr_optab, reg, 1446 operands[2], reg, 1, OPTAB_WIDEN); 1447 emit_insn (gen_truncsipsi2 (operands[0], reg)); 1448 DONE; 1449}") 1450 1451(define_expand "ashrpsi3" 1452 [(set (match_operand:PSI 0 "general_operand" "") 1453 (ashiftrt:PSI (match_operand:PSI 1 "general_operand" "") 1454 (match_operand:HI 2 "general_operand" "")))] 1455 "" 1456 " 1457{ 1458 rtx reg = gen_reg_rtx (SImode); 1459 1460 emit_insn (gen_extendpsisi2 (reg, operands[1])); 1461 reg = expand_binop (SImode, ashr_optab, reg, 1462 operands[2], reg, 0, OPTAB_WIDEN); 1463 emit_insn (gen_truncsipsi2 (operands[0], reg)); 1464 DONE; 1465}") 1466 1467(define_expand "ashlsi3" 1468 [(set (match_operand:SI 0 "register_operand" "") 1469 (ashift:SI (match_operand:SI 1 "nonmemory_operand" "") 1470 (match_operand:HI 2 "general_operand" "")))] 1471 "" 1472 " 1473{ 1474 /* For small shifts, just emit a series of single bit shifts inline. 1475 1476 For other constant shift counts smaller than a word or non-constant 1477 shift counts we call out to a library call during RTL generation time; 1478 after RTL generation time we allow optabs.c to open code the operation. 1479 See comments in addsi3/subsi3 expanders. 1480 1481 Otherwise we allow optabs.c to open code the operation. */ 1482 if (GET_CODE (operands[2]) == CONST_INT 1483 && (INTVAL (operands[2]) <= 3)) 1484 { 1485 int count = INTVAL (operands[2]); 1486 emit_move_insn (operands[0], operands[1]); 1487 while (count > 0) 1488 { 1489 emit_insn (gen_rtx_SET (SImode, operands[0], 1490 gen_rtx_ASHIFT (SImode, 1491 operands[0], GEN_INT (1)))); 1492 count--; 1493 } 1494 DONE; 1495 } 1496 else if (rtx_equal_function_value_matters 1497 && (GET_CODE (operands[2]) != CONST_INT 1498 || INTVAL (operands[2]) <= 15)) 1499 { 1500 rtx ret, insns; 1501 1502 start_sequence (); 1503 ret = emit_library_call_value (gen_rtx_SYMBOL_REF (Pmode, \"__ashlsi3\"), 1504 NULL_RTX, 1, SImode, 2, operands[1], 1505 SImode, operands[2], HImode); 1506 insns = get_insns (); 1507 end_sequence (); 1508 emit_libcall_block (insns, operands[0], ret, 1509 gen_rtx_ASHIFT (SImode, operands[1], operands[2])); 1510 DONE; 1511 } 1512 else 1513 FAIL; 1514}") 1515 1516;; ASHIFT one bit. 1517(define_insn "" 1518 [(set (match_operand:SI 0 "general_operand" "=d") 1519 (ashift:SI (match_operand:SI 1 "general_operand" "0") 1520 (const_int 1)))] 1521 "" 1522 "add %L0,%L0\;addc %H0,%H0" 1523 [(set_attr "cc" "clobber")]) 1524 1525(define_expand "lshrsi3" 1526 [(set (match_operand:SI 0 "register_operand" "") 1527 (lshiftrt:SI (match_operand:SI 1 "general_operand" "") 1528 (match_operand:HI 2 "general_operand" "")))] 1529 "" 1530 " 1531{ 1532 /* For small shifts, just emit a series of single bit shifts inline. 1533 1534 For other constant shift counts smaller than a word or non-constant 1535 shift counts we call out to a library call during RTL generation time; 1536 after RTL generation time we allow optabs.c to open code the operation. 1537 See comments in addsi3/subsi3 expanders. 1538 1539 Otherwise we allow optabs.c to open code the operation. */ 1540 if (GET_CODE (operands[2]) == CONST_INT 1541 && (INTVAL (operands[2]) <= 2)) 1542 { 1543 int count = INTVAL (operands[2]); 1544 emit_move_insn (operands[0], operands[1]); 1545 while (count > 0) 1546 { 1547 emit_insn (gen_rtx_SET (SImode, operands[0], 1548 gen_rtx_LSHIFTRT (SImode, operands[0], 1549 GEN_INT (1)))); 1550 count--; 1551 } 1552 DONE; 1553 } 1554 else if (rtx_equal_function_value_matters 1555 && (GET_CODE (operands[2]) != CONST_INT 1556 || INTVAL (operands[2]) <= 15)) 1557 { 1558 rtx ret, insns; 1559 1560 start_sequence (); 1561 ret = emit_library_call_value (gen_rtx_SYMBOL_REF (Pmode, \"__lshrsi3\"), 1562 NULL_RTX, 1, SImode, 2, operands[1], 1563 SImode, operands[2], HImode); 1564 insns = get_insns (); 1565 end_sequence (); 1566 emit_libcall_block (insns, operands[0], ret, 1567 gen_rtx_LSHIFTRT (SImode, operands[1], operands[2])); 1568 DONE; 1569 } 1570 else 1571 FAIL; 1572}") 1573 1574;; LSHIFTRT one bit. 1575(define_insn "" 1576 [(set (match_operand:SI 0 "general_operand" "=d") 1577 (lshiftrt:SI (match_operand:SI 1 "general_operand" "0") 1578 (const_int 1)))] 1579 "" 1580 "lsr %H0\;ror %L0" 1581 [(set_attr "cc" "clobber")]) 1582 1583(define_expand "ashrsi3" 1584 [(set (match_operand:SI 0 "register_operand" "") 1585 (ashiftrt:SI (match_operand:SI 1 "register_operand" "") 1586 (match_operand:HI 2 "general_operand" "")))] 1587 "" 1588 " 1589{ 1590 /* For small shifts, just emit a series of single bit shifts inline. 1591 1592 For other constant shift counts smaller than a word or non-constant 1593 shift counts we call out to a library call during RTL generation time; 1594 after RTL generation time we allow optabs.c to open code the operation. 1595 See comments in addsi3/subsi3 expanders. 1596 1597 Otherwise we allow optabs.c to open code the operation. */ 1598 if (GET_CODE (operands[2]) == CONST_INT 1599 && (INTVAL (operands[2]) <= 2)) 1600 { 1601 int count = INTVAL (operands[2]); 1602 emit_move_insn (operands[0], operands[1]); 1603 while (count > 0) 1604 { 1605 emit_insn (gen_rtx_SET (SImode, operands[0], 1606 gen_rtx_ASHIFTRT (SImode, operands[0], 1607 GEN_INT (1)))); 1608 count--; 1609 } 1610 DONE; 1611 } 1612 else if (rtx_equal_function_value_matters 1613 && (GET_CODE (operands[2]) != CONST_INT 1614 || INTVAL (operands[2]) <= 15)) 1615 { 1616 rtx ret, insns; 1617 1618 start_sequence (); 1619 ret = emit_library_call_value (gen_rtx_SYMBOL_REF (Pmode, \"__ashrsi3\"), 1620 NULL_RTX, 1, SImode, 2, operands[1], 1621 SImode, operands[2], HImode); 1622 insns = get_insns (); 1623 end_sequence (); 1624 emit_libcall_block (insns, operands[0], ret, 1625 gen_rtx_ASHIFTRT (SImode, operands[1], operands[2])); 1626 DONE; 1627 } 1628 else 1629 FAIL; 1630}") 1631 1632;; ASHIFTRT one bit. 1633(define_insn "" 1634 [(set (match_operand:SI 0 "general_operand" "=d") 1635 (ashiftrt:SI (match_operand:SI 1 "general_operand" "0") 1636 (const_int 1)))] 1637 "" 1638 "asr %H0\;ror %L0" 1639 [(set_attr "cc" "clobber")]) 1640 1641;; ---------------------------------------------------------------------- 1642;; FP INSTRUCTIONS 1643;; ---------------------------------------------------------------------- 1644;; 1645;; The mn102 series does not have floating point instructions, but since 1646;; FP values are held in integer regs, we can clear the high bit easily 1647;; which gives us an efficient inline floating point absolute value. 1648;; 1649;; Similarly for negation of a FP value. 1650;; 1651 1652(define_expand "abssf2" 1653 [(set (match_operand:SF 0 "register_operand" "") 1654 (abs:SF (match_operand:SF 1 "register_operand" "")))] 1655 "" 1656 " 1657{ 1658 rtx target, result, insns; 1659 1660 start_sequence (); 1661 target = operand_subword (operands[0], 1, 1, SFmode); 1662 result = expand_binop (HImode, and_optab, 1663 operand_subword_force (operands[1], 1, SFmode), 1664 GEN_INT(0x7fff), target, 0, OPTAB_WIDEN); 1665 1666 if (result == 0) 1667 abort (); 1668 1669 if (result != target) 1670 emit_move_insn (result, target); 1671 1672 emit_move_insn (operand_subword (operands[0], 0, 1, SFmode), 1673 operand_subword_force (operands[1], 0, SFmode)); 1674 1675 insns = get_insns (); 1676 end_sequence (); 1677 1678 emit_no_conflict_block (insns, operands[0], operands[1], 0, 0); 1679 DONE; 1680}") 1681 1682(define_expand "negsf2" 1683 [(set (match_operand:SF 0 "register_operand" "") 1684 (neg:SF (match_operand:SF 1 "register_operand" "")))] 1685 "" 1686 " 1687{ 1688 rtx target, result, insns; 1689 1690 start_sequence (); 1691 target = operand_subword (operands[0], 1, 1, SFmode); 1692 result = expand_binop (HImode, xor_optab, 1693 operand_subword_force (operands[1], 1, SFmode), 1694 GEN_INT(-0x8000), target, 0, OPTAB_WIDEN); 1695 1696 if (result == 0) 1697 abort (); 1698 1699 if (result != target) 1700 emit_move_insn (result, target); 1701 1702 emit_move_insn (operand_subword (operands[0], 0, 1, SFmode), 1703 operand_subword_force (operands[1], 0, SFmode)); 1704 1705 insns = get_insns (); 1706 end_sequence (); 1707 1708 emit_no_conflict_block (insns, operands[0], operands[1], 0, 0); 1709 DONE; 1710}") 1711 1712;; ---------------------------------------------------------------------- 1713;; PROLOGUE/EPILOGUE 1714;; ---------------------------------------------------------------------- 1715(define_expand "prologue" 1716 [(const_int 0)] 1717 "" 1718 "expand_prologue (); DONE;") 1719 1720(define_insn "outline_prologue_call" 1721 [(const_int 1)] 1722 "" 1723 "jsr ___prologue" 1724 [(set_attr "cc" "clobber")]) 1725 1726(define_expand "epilogue" 1727 [(return)] 1728 "" 1729 " 1730{ 1731 expand_epilogue (); 1732 DONE; 1733}") 1734 1735(define_insn "outline_epilogue_call_a0" 1736 [(const_int 2)] 1737 "" 1738 "jsr ___epilogue_a0" 1739 [(set_attr "cc" "clobber")]) 1740 1741(define_insn "outline_epilogue_call_d0" 1742 [(const_int 3)] 1743 "" 1744 "jsr ___epilogue_d0" 1745 [(set_attr "cc" "clobber")]) 1746 1747(define_insn "outline_epilogue_jump" 1748 [(const_int 4) 1749 (return)] 1750 "" 1751 "jmp ___epilogue_noreturn" 1752 [(set_attr "cc" "clobber")]) 1753 1754(define_insn "return" 1755 [(return)] 1756 "reload_completed && total_frame_size () == 0 1757 && !current_function_needs_context" 1758 "* 1759{ 1760 rtx next = next_active_insn (insn); 1761 1762 if (next 1763 && GET_CODE (next) == JUMP_INSN 1764 && GET_CODE (PATTERN (next)) == RETURN) 1765 return \"\"; 1766 return \"rts\"; 1767}" 1768 [(set_attr "cc" "clobber")]) 1769 1770(define_insn "return_internal" 1771 [(const_int 0) 1772 (return)] 1773 "" 1774 "rts" 1775 [(set_attr "cc" "clobber")]) 1776 1777;; These are special combiner patterns to improve array/pointer accesses. 1778;; 1779;; A typical sequence involves extending an integer/char, shifting it left 1780;; a few times, then truncating the value to PSImode. 1781;; 1782;; This first pattern combines the shifting & truncation operations, by 1783;; itself it is a win because the shifts end up occurring in PSImode instead 1784;; of SImode. However, it has the secondary effect of giving us the 1785;; opportunity to match patterns which allow us to remove the initial 1786;; extension completely, which is a big win. 1787(define_insn "" 1788 [(set (match_operand:PSI 0 "general_operand" "=d,d,a,da") 1789 (truncate:PSI 1790 (ashift:SI (match_operand:SI 1 "psimode_truncation_operand" "d,m,m,i") 1791 (match_operand:HI 2 "const_int_operand" "i,i,i,i"))))] 1792 "" 1793 "* 1794{ 1795 int count = INTVAL (operands[2]); 1796 if (which_alternative == 0) 1797 output_asm_insn (\"jsr ___truncsipsi2_%1_%0\", operands); 1798 else if (which_alternative == 1) 1799 output_asm_insn (\"movx %A1,%0\", operands); 1800 else 1801 output_asm_insn (\" mov %1,%0\", operands); 1802 1803 while (count) 1804 { 1805 output_asm_insn (\"add %0,%0\", operands); 1806 count--; 1807 } 1808 return \"\"; 1809}" 1810 [(set_attr "cc" "clobber")]) 1811 1812;; Similarly, except that we also have zero/sign extension of the 1813;; original operand. */ 1814(define_insn "" 1815 [(set (match_operand:PSI 0 "general_operand" "=d,d") 1816 (truncate:PSI 1817 (ashift:SI 1818 (zero_extend:SI (match_operand:HI 1 "general_operand" "0,dim")) 1819 (match_operand:HI 2 "const_int_operand" "i,i"))))] 1820 "" 1821 "* 1822{ 1823 int count = INTVAL (operands[2]); 1824 1825 /* First extend operand 1 to PSImode. */ 1826 if (which_alternative == 0) 1827 output_asm_insn (\"extxu %0\", operands); 1828 else 1829 output_asm_insn (\"mov %1,%0\;extxu %0\", operands); 1830 1831 /* Now do the shifting. */ 1832 while (count) 1833 { 1834 output_asm_insn (\"add %0,%0\", operands); 1835 count--; 1836 } 1837 return \"\"; 1838}" 1839 [(set_attr "cc" "clobber")]) 1840 1841(define_insn "" 1842 [(set (match_operand:PSI 0 "general_operand" "=d,d,d") 1843 (truncate:PSI 1844 (ashift:SI 1845 (sign_extend:SI (match_operand:HI 1 "general_operand" "0,di,m")) 1846 (match_operand:HI 2 "const_int_operand" "i,i,i"))))] 1847 "" 1848 "* 1849{ 1850 int count = INTVAL (operands[2]); 1851 1852 /* First extend operand 1 to PSImode. */ 1853 if (which_alternative == 0) 1854 output_asm_insn (\"extx %0\", operands); 1855 else if (which_alternative == 1) 1856 output_asm_insn (\"mov %1,%0\;extx %0\", operands); 1857 else 1858 output_asm_insn (\"mov %1,%0\", operands); 1859 1860 /* Now do the shifting. */ 1861 while (count) 1862 { 1863 output_asm_insn (\"add %0,%0\", operands); 1864 count--; 1865 } 1866 return \"\"; 1867}" 1868 [(set_attr "cc" "clobber")]) 1869 1870(define_insn "" 1871 [(set (match_operand:PSI 0 "general_operand" "=d,d,d") 1872 (truncate:PSI 1873 (ashift:SI 1874 (sign_extend:SI 1875 (zero_extend:HI (match_operand:QI 1 "general_operand" "0,di,m"))) 1876 (match_operand:HI 2 "const_int_operand" "i,i,i"))))] 1877 "" 1878 "* 1879{ 1880 int count = INTVAL (operands[2]); 1881 1882 /* First extend operand 1 to PSImode. */ 1883 if (which_alternative == 0) 1884 output_asm_insn (\"extxbu %0\", operands); 1885 else if (which_alternative == 1) 1886 output_asm_insn (\"mov %1,%0\;extxbu %0\", operands); 1887 else 1888 output_asm_insn (\"movbu %1,%0\", operands); 1889 1890 /* Now do the shifting. */ 1891 while (count) 1892 { 1893 output_asm_insn (\"add %0,%0\", operands); 1894 count--; 1895 } 1896 return \"\"; 1897}" 1898 [(set_attr "cc" "clobber")]) 1899 1900(define_insn "" 1901 [(set (match_operand:PSI 0 "general_operand" "=d,d,d") 1902 (truncate:PSI 1903 (ashift:SI 1904 (sign_extend:SI 1905 (match_operand:QI 1 "general_operand" "0,di,m")) 1906 (match_operand:HI 2 "const_int_operand" "i,i,i"))))] 1907 "" 1908 "* 1909{ 1910 int count = INTVAL (operands[2]); 1911 1912 /* First extend operand 1 to PSImode. */ 1913 if (which_alternative == 0) 1914 output_asm_insn (\"extxb %0\", operands); 1915 else if (which_alternative == 1) 1916 output_asm_insn (\"mov %1,%0\;extxb %0\", operands); 1917 else if (GET_CODE (XEXP (operands[1], 0)) == REG) 1918 output_asm_insn (\"movbu %1,%0\;extxb %0\", operands); 1919 else 1920 output_asm_insn (\"movb %1,%0\", operands); 1921 1922 /* Now do the shifting. */ 1923 while (count) 1924 { 1925 output_asm_insn (\"add %0,%0\", operands); 1926 count--; 1927 } 1928 return \"\"; 1929}" 1930 [(set_attr "cc" "clobber")]) 1931 1932;; Try to combine consecutive updates of the stack pointer (or any 1933;; other register for that matter). 1934(define_peephole 1935 [(set (match_operand:PSI 0 "register_operand" "=da") 1936 (plus:PSI (match_dup 0) 1937 (match_operand 1 "const_int_operand" ""))) 1938 (set (match_dup 0) 1939 (plus:PSI (match_dup 0) 1940 (match_operand 2 "const_int_operand" "")))] 1941 "" 1942 "* 1943{ 1944 operands[1] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[1])); 1945 return \"add %1,%0\"; 1946}" 1947 [(set_attr "cc" "clobber")]) 1948 1949;; 1950;; We had patterns to check eq/ne, but the they don't work because 1951;; 0x80000000 + 0x80000000 = 0x0 with a carry out. 1952;; 1953;; The Z flag and C flag would be set, and we have no way to 1954;; check for the Z flag set and C flag clear. 1955;; 1956;; This will work on the mn10200 because we can check the ZX flag 1957;; if the comparison is in HImode. 1958(define_peephole 1959 [(set (cc0) (match_operand:HI 0 "register_operand" "d")) 1960 (set (pc) (if_then_else (ge (cc0) (const_int 0)) 1961 (match_operand 1 "" "") 1962 (pc)))] 1963 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" 1964 "add %0,%0\;bcc %1" 1965 [(set_attr "cc" "clobber")]) 1966 1967(define_peephole 1968 [(set (cc0) (match_operand:HI 0 "register_operand" "d")) 1969 (set (pc) (if_then_else (lt (cc0) (const_int 0)) 1970 (match_operand 1 "" "") 1971 (pc)))] 1972 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" 1973 "add %0,%0\;bcs %1" 1974 [(set_attr "cc" "clobber")]) 1975 1976(define_peephole 1977 [(set (cc0) (match_operand:HI 0 "register_operand" "d")) 1978 (set (pc) (if_then_else (ge (cc0) (const_int 0)) 1979 (pc) 1980 (match_operand 1 "" "")))] 1981 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" 1982 "add %0,%0\;bcs %1" 1983 [(set_attr "cc" "clobber")]) 1984 1985(define_peephole 1986 [(set (cc0) (match_operand:HI 0 "register_operand" "d")) 1987 (set (pc) (if_then_else (lt (cc0) (const_int 0)) 1988 (pc) 1989 (match_operand 1 "" "")))] 1990 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" 1991 "add %0,%0\;bcc %1" 1992 [(set_attr "cc" "clobber")]) 1993 1994(define_peephole 1995 [(set (cc0) (match_operand:PSI 0 "register_operand" "d")) 1996 (set (pc) (if_then_else (ge (cc0) (const_int 0)) 1997 (match_operand 1 "" "") 1998 (pc)))] 1999 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" 2000 "add %0,%0\;bccx %1" 2001 [(set_attr "cc" "clobber")]) 2002 2003(define_peephole 2004 [(set (cc0) (match_operand:PSI 0 "register_operand" "d")) 2005 (set (pc) (if_then_else (lt (cc0) (const_int 0)) 2006 (match_operand 1 "" "") 2007 (pc)))] 2008 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" 2009 "add %0,%0\;bcsx %1" 2010 [(set_attr "cc" "clobber")]) 2011 2012(define_peephole 2013 [(set (cc0) (match_operand:PSI 0 "register_operand" "d")) 2014 (set (pc) (if_then_else (ge (cc0) (const_int 0)) 2015 (pc) 2016 (match_operand 1 "" "")))] 2017 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" 2018 "add %0,%0\;bcsx %1" 2019 [(set_attr "cc" "clobber")]) 2020 2021(define_peephole 2022 [(set (cc0) (match_operand:PSI 0 "register_operand" "d")) 2023 (set (pc) (if_then_else (lt (cc0) (const_int 0)) 2024 (pc) 2025 (match_operand 1 "" "")))] 2026 "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" 2027 "add %0,%0\;bccx %1" 2028 [(set_attr "cc" "clobber")]) 2029 2030;; We call out to library routines to perform 32bit addition and subtraction 2031;; operations (see addsi3/subsi3 expanders for why). These peepholes catch 2032;; the trivial case where the operation could be done with an add;addc or 2033;; sub;subc sequence. 2034(define_peephole 2035 [(set (mem:SI (reg:PSI 7)) (reg:SI 2)) 2036 (set (reg:SI 0) (call (match_operand:QI 1 "general_operand" "") 2037 (match_operand:HI 2 "general_operand" "")))] 2038 "GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF 2039 && strcmp (XSTR (XEXP (operands[1], 0), 0), \"__addsi3\") == 0" 2040 "add d2,d0\;addc d3,d1" 2041 [(set_attr "cc" "clobber")]) 2042 2043(define_peephole 2044 [(set (mem:SI (reg:PSI 7)) (reg:SI 2)) 2045 (set (reg:SI 0) (call (match_operand:QI 1 "general_operand" "") 2046 (match_operand:HI 2 "general_operand" "")))] 2047 "GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF 2048 && strcmp (XSTR (XEXP (operands[1], 0), 0), \"__subsi3\") == 0" 2049 "sub d2,d0\;subc d3,d1" 2050 [(set_attr "cc" "clobber")]) 2051