1;; FR30 machine description. 2;; Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc. 3;; Contributed by Cygnus Solutions. 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;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 23 24;;{{{ Attributes 25 26(define_attr "length" "" (const_int 2)) 27 28;; Used to distinguish between small memory model targets and big mode targets. 29 30(define_attr "size" "small,big" 31 (const (if_then_else (symbol_ref "TARGET_SMALL_MODEL") 32 (const_string "small") 33 (const_string "big")))) 34 35 36;; Define an attribute to be used by the delay slot code. 37;; An instruction by default is considered to be 'delyabable' 38;; that is, it can be placed into a delay slot, but it is not 39;; itself an delyaed branch type instruction. An instruction 40;; whoes type is 'delayed' is one which has a delay slot, and 41;; an instruction whoes delay_type is 'other' is one which does 42;; not have a delay slot, nor can it be placed into a delay slot. 43 44(define_attr "delay_type" "delayable,delayed,other" (const_string "delayable")) 45 46;;}}} 47;;{{{ Delay Slot Specifications 48 49(define_delay (eq_attr "delay_type" "delayed") 50 [(and (eq_attr "delay_type" "delayable") 51 (eq_attr "length" "2")) 52 (nil) 53 (nil)] 54) 55 56;;}}} 57;;{{{ Moves 58 59;;{{{ Comment 60 61;; Wrap moves in define_expand to prevent memory->memory moves from being 62;; generated at the RTL level, which generates better code for most machines 63;; which can't do mem->mem moves. 64 65;; If operand 0 is a `subreg' with mode M of a register whose own mode is wider 66;; than M, the effect of this instruction is to store the specified value in 67;; the part of the register that corresponds to mode M. The effect on the rest 68;; of the register is undefined. 69 70;; This class of patterns is special in several ways. First of all, each of 71;; these names *must* be defined, because there is no other way to copy a datum 72;; from one place to another. 73 74;; Second, these patterns are not used solely in the RTL generation pass. Even 75;; the reload pass can generate move insns to copy values from stack slots into 76;; temporary registers. When it does so, one of the operands is a hard 77;; register and the other is an operand that can need to be reloaded into a 78;; register. 79 80;; Therefore, when given such a pair of operands, the pattern must 81;; generate RTL which needs no reloading and needs no temporary 82;; registers--no registers other than the operands. For example, if 83;; you support the pattern with a `define_expand', then in such a 84;; case the `define_expand' mustn't call `force_reg' or any other such 85;; function which might generate new pseudo registers. 86 87;; This requirement exists even for subword modes on a RISC machine 88;; where fetching those modes from memory normally requires several 89;; insns and some temporary registers. Look in `spur.md' to see how 90;; the requirement can be satisfied. 91 92;; During reload a memory reference with an invalid address may be passed as an 93;; operand. Such an address will be replaced with a valid address later in the 94;; reload pass. In this case, nothing may be done with the address except to 95;; use it as it stands. If it is copied, it will not be replaced with a valid 96;; address. No attempt should be made to make such an address into a valid 97;; address and no routine (such as `change_address') that will do so may be 98;; called. Note that `general_operand' will fail when applied to such an 99;; address. 100;; 101;; The global variable `reload_in_progress' (which must be explicitly declared 102;; if required) can be used to determine whether such special handling is 103;; required. 104;; 105;; The variety of operands that have reloads depends on the rest of 106;; the machine description, but typically on a RISC machine these can 107;; only be pseudo registers that did not get hard registers, while on 108;; other machines explicit memory references will get optional 109;; reloads. 110;; 111;; If a scratch register is required to move an object to or from memory, it 112;; can be allocated using `gen_reg_rtx' prior to reload. But this is 113;; impossible during and after reload. If there are cases needing scratch 114;; registers after reload, you must define `SECONDARY_INPUT_RELOAD_CLASS' and 115;; perhaps also `SECONDARY_OUTPUT_RELOAD_CLASS' to detect them, and provide 116;; patterns `reload_inM' or `reload_outM' to handle them. 117 118;; The constraints on a `moveM' must permit moving any hard register to any 119;; other hard register provided that `HARD_REGNO_MODE_OK' permits mode M in 120;; both registers and `REGISTER_MOVE_COST' applied to their classes returns a 121;; value of 2. 122 123;; It is obligatory to support floating point `moveM' instructions 124;; into and out of any registers that can hold fixed point values, 125;; because unions and structures (which have modes `SImode' or 126;; `DImode') can be in those registers and they may have floating 127;; point members. 128 129;; There may also be a need to support fixed point `moveM' instructions in and 130;; out of floating point registers. Unfortunately, I have forgotten why this 131;; was so, and I don't know whether it is still true. If `HARD_REGNO_MODE_OK' 132;; rejects fixed point values in floating point registers, then the constraints 133;; of the fixed point `moveM' instructions must be designed to avoid ever 134;; trying to reload into a floating point register. 135 136;;}}} 137;;{{{ Push and Pop 138 139;; Push a register onto the stack 140(define_insn "movsi_push" 141 [(set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 142 (match_operand:SI 0 "register_operand" "a"))] 143 "" 144 "st %0, @-r15" 145) 146 147;; Pop a register off the stack 148(define_insn "movsi_pop" 149 [(set:SI (match_operand:SI 0 "register_operand" "=a") 150 (mem:SI (post_inc:SI (reg:SI 15))))] 151 "" 152 "ld @r15+, %0" 153) 154 155;;}}} 156;;{{{ 1 Byte Moves 157 158(define_expand "movqi" 159 [(set (match_operand:QI 0 "general_operand" "") 160 (match_operand:QI 1 "general_operand" ""))] 161 "" 162 " 163{ 164 if (!reload_in_progress 165 && !reload_completed 166 && GET_CODE (operands[0]) == MEM 167 && (GET_CODE (operands[1]) == MEM 168 || immediate_operand (operands[1], QImode))) 169 operands[1] = copy_to_mode_reg (QImode, operands[1]); 170}") 171 172(define_insn "movqi_unsigned_register_load" 173 [(set (match_operand:SI 0 "register_operand" "=r") 174 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))] 175 "" 176 "ldub %1, %0" 177) 178 179(define_expand "movqi_signed_register_load" 180 [(set (match_operand:SI 0 "register_operand" "") 181 (sign_extend:SI (match_operand:QI 1 "memory_operand" "")))] 182 "" 183 " 184 emit_insn (gen_movqi_unsigned_register_load (operands[0], operands[1])); 185 emit_insn (gen_extendqisi2 (operands[0], operands[0])); 186 DONE; 187 " 188) 189 190(define_insn "*movqi_internal" 191 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,red,m,r") 192 (match_operand:QI 1 "general_operand" "i,red,r,rm"))] 193 "" 194 "@ 195 ldi:8\\t#%A1, %0 196 mov \\t%1, %0 197 stb \\t%1, %0 198 ldub \\t%1, %0" 199) 200 201;;}}} 202;;{{{ 2 Byte Moves 203 204(define_expand "movhi" 205 [(set (match_operand:HI 0 "general_operand" "") 206 (match_operand:HI 1 "general_operand" ""))] 207 "" 208 " 209{ 210 if (!reload_in_progress 211 && !reload_completed 212 && GET_CODE (operands[0]) == MEM 213 && (GET_CODE (operands[1]) == MEM 214 || immediate_operand (operands[1], HImode))) 215 operands[1] = copy_to_mode_reg (HImode, operands[1]); 216}") 217 218(define_insn "movhi_unsigned_register_load" 219 [(set (match_operand:SI 0 "register_operand" "=r") 220 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] 221 "" 222 "lduh %1, %0" 223) 224 225(define_expand "movhi_signed_register_load" 226 [(set (match_operand:SI 0 "register_operand" "") 227 (sign_extend:SI (match_operand:HI 1 "memory_operand" "")))] 228 "" 229 " 230 emit_insn (gen_movhi_unsigned_register_load (operands[0], operands[1])); 231 emit_insn (gen_extendhisi2 (operands[0], operands[0])); 232 DONE; 233 " 234) 235 236(define_insn "*movhi_internal" 237 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,red,m,r") 238 (match_operand:HI 1 "general_operand" "L,M,n,red,r,rm"))] 239 "" 240 "@ 241 ldi:8 \\t#%1, %0 242 ldi:20\\t#%1, %0 243 ldi:32\\t#%1, %0 244 mov \\t%1, %0 245 sth \\t%1, %0 246 lduh \\t%1, %0" 247 [(set_attr "length" "*,4,6,*,*,*")] 248) 249 250;;}}} 251;;{{{ 4 Byte Moves 252 253;; If the destination is a MEM and the source is a 254;; MEM or an CONST_INT move the source into a register. 255(define_expand "movsi" 256 [(set (match_operand:SI 0 "nonimmediate_operand" "") 257 (match_operand:SI 1 "general_operand" ""))] 258 "" 259 "{ 260 if (!reload_in_progress 261 && !reload_completed 262 && GET_CODE(operands[0]) == MEM 263 && (GET_CODE (operands[1]) == MEM 264 || immediate_operand (operands[1], SImode))) 265 operands[1] = copy_to_mode_reg (SImode, operands[1]); 266 }" 267) 268 269;; We can do some clever tricks when loading certain immediate 270;; values. We implement these tricks as define_splits, rather 271;; than putting the code into the define_expand "movsi" above, 272;; because if we put them there, they will be evaluated at RTL 273;; generation time and then the combiner pass will come along 274;; and replace the multiple insns that have been generated with 275;; the original, slower, load insns. (The combiner pass only 276;; cares about reducing the number of instructions, it does not 277;; care about instruction lengths or speeds). Splits are 278;; evaluated after the combine pass and before the scheduling 279;; passes, so that they are the perfect place to put this 280;; intelligence. 281;; 282;; XXX we probably ought to implement these for QI and HI mode 283;; loads as well. 284 285;; If we are loading a small negative constant we can save space 286;; and time by loading the positive value and then sign extending it. 287(define_split 288 [(set (match_operand:SI 0 "register_operand" "") 289 (match_operand:SI 1 "const_int_operand" ""))] 290 "INTVAL (operands[1]) <= -1 && INTVAL (operands[1]) >= -128" 291 [(set:SI (match_dup 0) (match_dup 1)) 292 (set:SI (match_dup 0) (sign_extend:SI (match_dup 2)))] 293 "{ 294 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); 295 operands[2] = gen_lowpart (QImode, operands[0]); 296 }" 297) 298 299;; If we are loading a large negative constant, one which does 300;; not have any of its bottom 24 bit set, then we can save time 301;; and space by loading the byte value and shifting it into place. 302(define_split 303 [(set (match_operand:SI 0 "register_operand" "") 304 (match_operand:SI 1 "const_int_operand" ""))] 305 "(INTVAL (operands[1]) < 0) && ((INTVAL (operands[1]) & 0x00ffffff) == 0)" 306 [(set:SI (match_dup 0) (match_dup 2)) 307 (parallel [(set:SI (match_dup 0) (ashift:SI (match_dup 0) (const_int 24))) 308 (clobber (reg:CC 16))])] 309 "{ 310 HOST_WIDE_INT val = INTVAL (operands[1]); 311 operands[2] = GEN_INT (val >> 24); 312 }" 313) 314 315;; If we are loading a large positive constant, one which has bits 316;; in the top byte set, but whoes set bits all lie within an 8 bit 317;; range, then we can save time and space by loading the byte value 318;; and shifting it into place. 319(define_split 320 [(set (match_operand:SI 0 "register_operand" "") 321 (match_operand:SI 1 "const_int_operand" ""))] 322 "(INTVAL (operands[1]) > 0x00ffffff) 323 && ((INTVAL (operands[1]) >> exact_log2 (INTVAL (operands[1]) & (- INTVAL (operands[1])))) < 0x100)" 324 [(set:SI (match_dup 0) (match_dup 2)) 325 (parallel [(set:SI (match_dup 0) (ashift:SI (match_dup 0) (match_dup 3))) 326 (clobber (reg:CC 16))])] 327 "{ 328 HOST_WIDE_INT val = INTVAL (operands[1]); 329 int shift = exact_log2 (val & ( - val)); 330 operands[2] = GEN_INT (val >> shift); 331 operands[3] = GEN_INT (shift); 332 }" 333) 334 335;; When TARGET_SMALL_MODEL is defined we assume that all symbolic 336;; values are addresses which will fit in 20 bits. 337 338(define_insn "movsi_internal" 339 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,red,m,r") 340 (match_operand:SI 1 "general_operand" "L,M,n,i,rde,r,rm"))] 341 "" 342 "* 343 { 344 switch (which_alternative) 345 { 346 case 0: return \"ldi:8 \\t#%1, %0\"; 347 case 1: return \"ldi:20\\t#%1, %0\"; 348 case 2: return \"ldi:32\\t#%1, %0\"; 349 case 3: if (TARGET_SMALL_MODEL) 350 return \"ldi:20\\t%1, %0\"; 351 else 352 return \"ldi:32\\t%1, %0\"; 353 case 4: return \"mov \\t%1, %0\"; 354 case 5: return \"st \\t%1, %0\"; 355 case 6: return \"ld \\t%1, %0\"; 356 default: abort (); 357 } 358 }" 359 [(set (attr "length") (cond [(eq_attr "alternative" "1") (const_int 4) 360 (eq_attr "alternative" "2") (const_int 6) 361 (eq_attr "alternative" "3") 362 (if_then_else (eq_attr "size" "small") 363 (const_int 4) 364 (const_int 6))] 365 (const_int 2)))] 366) 367 368;;}}} 369;;{{{ 8 Byte Moves 370 371;; Note - the FR30 does not have an 8 byte load/store instruction 372;; but we have to support this pattern because some other patterns 373;; (eg muldisi2) can produce a DImode result. 374;; (This code is stolen from the M32R port.) 375 376(define_expand "movdi" 377 [(set (match_operand:DI 0 "general_operand" "") 378 (match_operand:DI 1 "general_operand" ""))] 379 "" 380 " 381 /* Everything except mem = const or mem = mem can be done easily. */ 382 383 if (GET_CODE (operands[0]) == MEM) 384 operands[1] = force_reg (DImode, operands[1]); 385 ") 386 387;; We use an insn and a split so that we can generate 388;; RTL rather than text from fr30_move_double(). 389 390(define_insn "*movdi_insn" 391 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,m,r") 392 (match_operand:DI 1 "di_operand" "r,m,r,nF"))] 393 "register_operand (operands[0], DImode) || register_operand (operands[1], DImode)" 394 "#" 395 [(set_attr "length" "4,8,12,12")] 396) 397 398(define_split 399 [(set (match_operand:DI 0 "nonimmediate_di_operand" "") 400 (match_operand:DI 1 "di_operand" ""))] 401 "reload_completed" 402 [(match_dup 2)] 403 "operands[2] = fr30_move_double (operands);") 404 405;;}}} 406;;{{{ Load & Store Multiple Registers 407 408;; The load multiple and store multiple patterns are implemented 409;; as peepholes because the only time they are expected to occur 410;; is during function prologues and epilogues. 411 412(define_peephole 413 [(set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 414 (match_operand:SI 0 "high_register_operand" "h")) 415 (set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 416 (match_operand:SI 1 "high_register_operand" "h")) 417 (set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 418 (match_operand:SI 2 "high_register_operand" "h")) 419 (set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 420 (match_operand:SI 3 "high_register_operand" "h"))] 421 "fr30_check_multiple_regs (operands, 4, 1)" 422 "stm1 (%0, %1, %2, %3)" 423 [(set_attr "delay_type" "other")] 424) 425 426(define_peephole 427 [(set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 428 (match_operand:SI 0 "high_register_operand" "h")) 429 (set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 430 (match_operand:SI 1 "high_register_operand" "h")) 431 (set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 432 (match_operand:SI 2 "high_register_operand" "h"))] 433 "fr30_check_multiple_regs (operands, 3, 1)" 434 "stm1 (%0, %1, %2)" 435 [(set_attr "delay_type" "other")] 436) 437 438(define_peephole 439 [(set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 440 (match_operand:SI 0 "high_register_operand" "h")) 441 (set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 442 (match_operand:SI 1 "high_register_operand" "h"))] 443 "fr30_check_multiple_regs (operands, 2, 1)" 444 "stm1 (%0, %1)" 445 [(set_attr "delay_type" "other")] 446) 447 448(define_peephole 449 [(set:SI (match_operand:SI 0 "high_register_operand" "h") 450 (mem:SI (post_inc:SI (reg:SI 15)))) 451 (set:SI (match_operand:SI 1 "high_register_operand" "h") 452 (mem:SI (post_inc:SI (reg:SI 15)))) 453 (set:SI (match_operand:SI 2 "high_register_operand" "h") 454 (mem:SI (post_inc:SI (reg:SI 15)))) 455 (set:SI (match_operand:SI 3 "high_register_operand" "h") 456 (mem:SI (post_inc:SI (reg:SI 15))))] 457 "fr30_check_multiple_regs (operands, 4, 0)" 458 "ldm1 (%0, %1, %2, %3)" 459 [(set_attr "delay_type" "other")] 460) 461 462(define_peephole 463 [(set:SI (match_operand:SI 0 "high_register_operand" "h") 464 (mem:SI (post_inc:SI (reg:SI 15)))) 465 (set:SI (match_operand:SI 1 "high_register_operand" "h") 466 (mem:SI (post_inc:SI (reg:SI 15)))) 467 (set:SI (match_operand:SI 2 "high_register_operand" "h") 468 (mem:SI (post_inc:SI (reg:SI 15))))] 469 "fr30_check_multiple_regs (operands, 3, 0)" 470 "ldm1 (%0, %1, %2)" 471 [(set_attr "delay_type" "other")] 472) 473 474(define_peephole 475 [(set:SI (match_operand:SI 0 "high_register_operand" "h") 476 (mem:SI (post_inc:SI (reg:SI 15)))) 477 (set:SI (match_operand:SI 1 "high_register_operand" "h") 478 (mem:SI (post_inc:SI (reg:SI 15))))] 479 "fr30_check_multiple_regs (operands, 2, 0)" 480 "ldm1 (%0, %1)" 481 [(set_attr "delay_type" "other")] 482) 483 484(define_peephole 485 [(set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 486 (match_operand:SI 0 "low_register_operand" "l")) 487 (set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 488 (match_operand:SI 1 "low_register_operand" "l")) 489 (set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 490 (match_operand:SI 2 "low_register_operand" "l")) 491 (set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 492 (match_operand:SI 3 "low_register_operand" "l"))] 493 "fr30_check_multiple_regs (operands, 4, 1)" 494 "stm0 (%0, %1, %2, %3)" 495 [(set_attr "delay_type" "other")] 496) 497 498(define_peephole 499 [(set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 500 (match_operand:SI 0 "low_register_operand" "l")) 501 (set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 502 (match_operand:SI 1 "low_register_operand" "l")) 503 (set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 504 (match_operand:SI 2 "low_register_operand" "l"))] 505 "fr30_check_multiple_regs (operands, 3, 1)" 506 "stm0 (%0, %1, %2)" 507 [(set_attr "delay_type" "other")] 508) 509 510(define_peephole 511 [(set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 512 (match_operand:SI 0 "low_register_operand" "l")) 513 (set:SI (mem:SI (pre_dec:SI (reg:SI 15))) 514 (match_operand:SI 1 "low_register_operand" "l"))] 515 "fr30_check_multiple_regs (operands, 2, 1)" 516 "stm0 (%0, %1)" 517 [(set_attr "delay_type" "other")] 518) 519 520;;}}} 521;;{{{ Floating Point Moves 522 523;; Note - Patterns for SF mode moves are compulsory, but 524;; patterns for DF are optional, as GCC can synthesize them. 525 526(define_expand "movsf" 527 [(set (match_operand:SF 0 "general_operand" "") 528 (match_operand:SF 1 "general_operand" ""))] 529 "" 530 "{ 531 if (!reload_in_progress && !reload_completed 532 && memory_operand (operands[0], SFmode) 533 && memory_operand (operands[1], SFmode)) 534 operands[1] = copy_to_mode_reg (SFmode, operands[1]); 535 }" 536) 537 538(define_insn "*movsf_internal" 539 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,red,m,r") 540 (match_operand:SF 1 "general_operand" "Fn,i,rde,r,rm"))] 541 "" 542 "* 543 { 544 switch (which_alternative) 545 { 546 case 0: return \"ldi:32\\t%1, %0\"; 547 case 1: if (TARGET_SMALL_MODEL) 548 return \"ldi:20\\t%1, %0\"; 549 else 550 return \"ldi:32\\t%1, %0\"; 551 case 2: return \"mov \\t%1, %0\"; 552 case 3: return \"st \\t%1, %0\"; 553 case 4: return \"ld \\t%1, %0\"; 554 default: abort (); 555 } 556 }" 557 [(set (attr "length") (cond [(eq_attr "alternative" "0") (const_int 6) 558 (eq_attr "alternative" "1") 559 (if_then_else (eq_attr "size" "small") 560 (const_int 4) 561 (const_int 6))] 562 (const_int 2)))] 563) 564 565(define_insn "*movsf_constant_store" 566 [(set (match_operand:SF 0 "memory_operand" "=m") 567 (match_operand:SF 1 "immediate_operand" "F"))] 568 "" 569 "* 570 { 571 const char * ldi_instr; 572 const char * tmp_reg; 573 static char buffer[100]; 574 575 ldi_instr = fr30_const_double_is_zero (operands[1]) 576 ? ldi_instr = \"ldi:8\" : \"ldi:32\"; 577 578 tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER]; 579 580 sprintf (buffer, \"%s\\t#%%1, %s\\t;\\n\\tst\\t%s, %%0\\t; Created by movsf_constant_store\", 581 ldi_instr, tmp_reg, tmp_reg); 582 583 return buffer; 584 }" 585 [(set_attr "length" "8")] 586) 587 588;;}}} 589 590;;}}} 591;;{{{ Conversions 592 593;; Signed conversions from a smaller integer to a larger integer 594 595(define_insn "extendqisi2" 596 [(set (match_operand:SI 0 "register_operand" "=r") 597 (sign_extend:SI (match_operand:QI 1 "register_operand" "0")))] 598 "" 599 "extsb %0" 600) 601 602(define_insn "extendhisi2" 603 [(set (match_operand:SI 0 "register_operand" "=r") 604 (sign_extend:SI (match_operand:HI 1 "register_operand" "0")))] 605 "" 606 "extsh %0" 607) 608 609;; Unsigned conversions from a smaller integer to a larger integer 610 611(define_insn "zero_extendqisi2" 612 [(set (match_operand:SI 0 "register_operand" "=r") 613 (zero_extend:SI (match_operand:QI 1 "register_operand" "0")))] 614 "" 615 "extub %0" 616) 617 618(define_insn "zero_extendhisi2" 619 [(set (match_operand:SI 0 "register_operand" "=r") 620 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))] 621 "" 622 "extuh %0" 623) 624 625;;}}} 626;;{{{ Arithmetic 627 628;;{{{ Addition 629 630;; This is a special pattern just for adjusting the stack size. 631(define_insn "add_to_stack" 632 [(set (reg:SI 15) 633 (plus:SI (reg:SI 15) 634 (match_operand:SI 0 "stack_add_operand" "i")))] 635 "" 636 "addsp %0" 637) 638 639;; We need some trickery to be able to handle the addition of 640;; large (ie outside +/- 16) constants. We need to be able to 641;; handle this because reload assumes that it can generate add 642;; instructions with arbitary sized constants. 643(define_expand "addsi3" 644 [(set (match_operand:SI 0 "register_operand" "") 645 (plus:SI (match_operand:SI 1 "register_operand" "") 646 (match_operand:SI 2 "nonmemory_operand" "")))] 647 "" 648 "{ 649 if ( GET_CODE (operands[2]) == REG 650 || GET_CODE (operands[2]) == SUBREG) 651 emit_insn (gen_addsi_regs (operands[0], operands[1], operands[2])); 652 else if (GET_CODE (operands[2]) != CONST_INT) 653 emit_insn (gen_addsi_big_int (operands[0], operands[1], operands[2])); 654 else if ( (REGNO (operands[1]) != FRAME_POINTER_REGNUM) 655 && (REGNO (operands[1]) != ARG_POINTER_REGNUM) 656 && (INTVAL (operands[2]) >= -16) 657 && (INTVAL (operands[2]) <= 15)) 658 emit_insn (gen_addsi_small_int (operands[0], operands[1], operands[2])); 659 else 660 emit_insn (gen_addsi_big_int (operands[0], operands[1], operands[2])); 661 DONE; 662 }" 663) 664 665(define_insn "addsi_regs" 666 [(set (match_operand:SI 0 "register_operand" "=r") 667 (plus:SI (match_operand:SI 1 "register_operand" "%0") 668 (match_operand:SI 2 "register_operand" "r")))] 669 "" 670 "addn %2, %0" 671) 672 673;; Do not allow an eliminable register in the source register. It 674;; might be eliminated in favor of the stack pointer, probably 675;; increasing the offset, and so rendering the instruction illegal. 676(define_insn "addsi_small_int" 677 [(set (match_operand:SI 0 "register_operand" "=r,r") 678 (plus:SI (match_operand:SI 1 "register_operand" "0,0") 679 (match_operand:SI 2 "add_immediate_operand" "I,J")))] 680 " (REGNO (operands[1]) != FRAME_POINTER_REGNUM) 681 && (REGNO (operands[1]) != ARG_POINTER_REGNUM)" 682 "@ 683 addn %2, %0 684 addn2 %2, %0" 685) 686 687(define_expand "addsi_big_int" 688 [(set (match_operand:SI 0 "register_operand" "") 689 (plus:SI (match_operand:SI 1 "register_operand" "") 690 (match_operand:SI 2 "immediate_operand" "")))] 691 "" 692 "{ 693 /* Cope with the possibility that ops 0 and 1 are the same register. */ 694 if (REGNO (operands[0]) == REGNO (operands[1])) 695 { 696 if (reload_in_progress || reload_completed) 697 { 698 rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/); 699 700 emit_insn (gen_movsi (reg, operands[2])); 701 emit_insn (gen_addsi_regs (operands[0], operands[0], reg)); 702 } 703 else 704 { 705 operands[2] = force_reg (SImode, operands[2]); 706 emit_insn (gen_addsi_regs (operands[0], operands[0], operands[2])); 707 } 708 } 709 else 710 { 711 emit_insn (gen_movsi (operands[0], operands[2])); 712 emit_insn (gen_addsi_regs (operands[0], operands[0], operands[1])); 713 } 714 DONE; 715 }" 716) 717 718(define_insn "*addsi_for_reload" 719 [(set (match_operand:SI 0 "register_operand" "=&r,r,r") 720 (plus:SI (match_operand:SI 1 "register_operand" "r,r,r") 721 (match_operand:SI 2 "immediate_operand" "L,M,n")))] 722 "reload_in_progress || reload_completed" 723 "@ 724 ldi:8\\t#%2, %0 \\n\\taddn\\t%1, %0 725 ldi:20\\t#%2, %0 \\n\\taddn\\t%1, %0 726 ldi:32\\t#%2, %0 \\n\\taddn\\t%1, %0" 727 [(set_attr "length" "4,6,8")] 728) 729 730;;}}} 731;;{{{ Subtraction 732 733(define_insn "subsi3" 734 [(set (match_operand:SI 0 "register_operand" "=r") 735 (minus:SI (match_operand:SI 1 "register_operand" "0") 736 (match_operand:SI 2 "register_operand" "r")))] 737 "" 738 "subn %2, %0" 739) 740 741;;}}} 742;;{{{ Multiplication 743 744;; Signed multiplication producing 64 bit results from 32 bit inputs 745(define_insn "mulsidi3" 746 [(set (match_operand:DI 0 "register_operand" "=r") 747 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r")) 748 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))) 749 (clobber (reg:CC 16))] 750 "" 751 "mul %2, %1\\n\\tmov\\tmdh, %0\\n\\tmov\\tmdl, %p0" 752 [(set_attr "length" "6")] 753) 754 755;; Unsigned multiplication producing 64 bit results from 32 bit inputs 756(define_insn "umulsidi3" 757 [(set (match_operand:DI 0 "register_operand" "=r") 758 (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r")) 759 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))) 760 (clobber (reg:CC 16))] 761 "" 762 "mulu %2, %1\\n\\tmov\\tmdh, %0\\n\\tmov\\tmdl, %p0" 763 [(set_attr "length" "6")] 764) 765 766;; Signed multiplication producing 32 bit result from 16 bit inputs 767(define_insn "mulhisi3" 768 [(set (match_operand:SI 0 "register_operand" "=r") 769 (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r")) 770 (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))) 771 (clobber (reg:CC 16))] 772 "" 773 "mulh %2, %1\\n\\tmov\\tmdl, %0" 774 [(set_attr "length" "4")] 775) 776 777;; Unsigned multiplication producing 32 bit result from 16 bit inputs 778(define_insn "umulhisi3" 779 [(set (match_operand:SI 0 "register_operand" "=r") 780 (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%r")) 781 (zero_extend:SI (match_operand:HI 2 "register_operand" "r")))) 782 (clobber (reg:CC 16))] 783 "" 784 "muluh %2, %1\\n\\tmov\\tmdl, %0" 785 [(set_attr "length" "4")] 786) 787 788;; Signed multiplication producing 32 bit result from 32 bit inputs 789(define_insn "mulsi3" 790 [(set (match_operand:SI 0 "register_operand" "=r") 791 (mult:SI (match_operand:SI 1 "register_operand" "%r") 792 (match_operand:SI 2 "register_operand" "r"))) 793 (clobber (reg:CC 16))] 794 "" 795 "mul %2, %1\\n\\tmov\\tmdl, %0" 796 [(set_attr "length" "4")] 797) 798 799;;}}} 800;;{{{ Negation 801 802(define_expand "negsi2" 803 [(set (match_operand:SI 0 "register_operand" "") 804 (neg:SI (match_operand:SI 1 "register_operand" "")))] 805 "" 806 "{ 807 if (REGNO (operands[0]) == REGNO (operands[1])) 808 { 809 if (reload_in_progress || reload_completed) 810 { 811 rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/); 812 813 emit_insn (gen_movsi (reg, GEN_INT (0))); 814 emit_insn (gen_subsi3 (reg, reg, operands[0])); 815 emit_insn (gen_movsi (operands[0], reg)); 816 } 817 else 818 { 819 rtx reg = gen_reg_rtx (SImode); 820 821 emit_insn (gen_movsi (reg, GEN_INT (0))); 822 emit_insn (gen_subsi3 (reg, reg, operands[0])); 823 emit_insn (gen_movsi (operands[0], reg)); 824 } 825 } 826 else 827 { 828 emit_insn (gen_movsi_internal (operands[0], GEN_INT (0))); 829 emit_insn (gen_subsi3 (operands[0], operands[0], operands[1])); 830 } 831 DONE; 832 }" 833) 834 835;;}}} 836 837;;}}} 838;;{{{ Shifts 839 840;; Arithmetic Shift Left 841(define_insn "ashlsi3" 842 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 843 (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0") 844 (match_operand:SI 2 "nonmemory_operand" "r,I,K"))) 845 (clobber (reg:CC 16))] 846 "" 847 "@ 848 lsl %2, %0 849 lsl %2, %0 850 lsl2 %x2, %0" 851) 852 853;; Arithmetic Shift Right 854(define_insn "ashrsi3" 855 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 856 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0") 857 (match_operand:SI 2 "nonmemory_operand" "r,I,K"))) 858 (clobber (reg:CC 16))] 859 "" 860 "@ 861 asr %2, %0 862 asr %2, %0 863 asr2 %x2, %0" 864) 865 866;; Logical Shift Right 867(define_insn "lshrsi3" 868 [(set (match_operand:SI 0 "register_operand" "=r,r,r") 869 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0") 870 (match_operand:SI 2 "nonmemory_operand" "r,I,K"))) 871 (clobber (reg:CC 16))] 872 "" 873 "@ 874 lsr %2, %0 875 lsr %2, %0 876 lsr2 %x2, %0" 877) 878 879;;}}} 880;;{{{ Logical Operations 881 882;; Logical AND, 32 bit integers 883(define_insn "andsi3" 884 [(set (match_operand:SI 0 "register_operand" "=r") 885 (and:SI (match_operand:SI 1 "register_operand" "%r") 886 (match_operand:SI 2 "register_operand" "0"))) 887 (clobber (reg:CC 16))] 888 "" 889 "and %1, %0" 890) 891 892;; Inclusive OR, 32 bit integers 893(define_insn "iorsi3" 894 [(set (match_operand:SI 0 "register_operand" "=r") 895 (ior:SI (match_operand:SI 1 "register_operand" "%r") 896 (match_operand:SI 2 "register_operand" "0"))) 897 (clobber (reg:CC 16))] 898 "" 899 "or %1, %0" 900) 901 902;; Exclusive OR, 32 bit integers 903(define_insn "xorsi3" 904 [(set (match_operand:SI 0 "register_operand" "=r") 905 (xor:SI (match_operand:SI 1 "register_operand" "%r") 906 (match_operand:SI 2 "register_operand" "0"))) 907 (clobber (reg:CC 16))] 908 "" 909 "eor %1, %0" 910) 911 912;; One's complement, 32 bit integers 913(define_expand "one_cmplsi2" 914 [(set (match_operand:SI 0 "register_operand" "") 915 (not:SI (match_operand:SI 1 "register_operand" "")))] 916 "" 917 "{ 918 if (REGNO (operands[0]) == REGNO (operands[1])) 919 { 920 if (reload_in_progress || reload_completed) 921 { 922 rtx reg = gen_rtx_REG (SImode, 0/*COMPILER_SCRATCH_REGISTER*/); 923 924 emit_insn (gen_movsi (reg, GEN_INT (-1))); 925 emit_insn (gen_xorsi3 (operands[0], operands[0], reg)); 926 } 927 else 928 { 929 rtx reg = gen_reg_rtx (SImode); 930 931 emit_insn (gen_movsi (reg, GEN_INT (-1))); 932 emit_insn (gen_xorsi3 (operands[0], operands[0], reg)); 933 } 934 } 935 else 936 { 937 emit_insn (gen_movsi_internal (operands[0], GEN_INT (-1))); 938 emit_insn (gen_xorsi3 (operands[0], operands[1], operands[0])); 939 } 940 DONE; 941 }" 942) 943 944;;}}} 945;;{{{ Comparisons 946 947;; Note, we store the operands in the comparison insns, and use them later 948;; when generating the branch or scc operation. 949 950;; First the routines called by the machine independent part of the compiler 951(define_expand "cmpsi" 952 [(set (reg:CC 16) 953 (compare:CC (match_operand:SI 0 "register_operand" "") 954 (match_operand:SI 1 "nonmemory_operand" "")))] 955 "" 956 "{ 957 fr30_compare_op0 = operands[0]; 958 fr30_compare_op1 = operands[1]; 959 DONE; 960 }" 961) 962 963;; Now, the actual comparisons, generated by the branch and/or scc operations 964 965(define_insn "*cmpsi_internal" 966 [(set (reg:CC 16) 967 (compare:CC (match_operand:SI 0 "register_operand" "r,r,r") 968 (match_operand:SI 1 "nonmemory_operand" "r,I,J")))] 969 "" 970 "@ 971 cmp %1, %0 972 cmp %1, %0 973 cmp2 %1, %0" 974) 975 976;;}}} 977;;{{{ Branches 978 979;; Define_expands called by the machine independent part of the compiler 980;; to allocate a new comparison register 981 982(define_expand "beq" 983 [(set (reg:CC 16) 984 (compare:CC (match_dup 1) 985 (match_dup 2))) 986 (set (pc) 987 (if_then_else (eq:CC (reg:CC 16) 988 (const_int 0)) 989 (label_ref (match_operand 0 "" "")) 990 (pc)))] 991 "" 992 "{ 993 operands[1] = fr30_compare_op0; 994 operands[2] = fr30_compare_op1; 995 }" 996) 997 998(define_expand "bne" 999 [(set (reg:CC 16) 1000 (compare:CC (match_dup 1) 1001 (match_dup 2))) 1002 (set (pc) 1003 (if_then_else (ne:CC (reg:CC 16) 1004 (const_int 0)) 1005 (label_ref (match_operand 0 "" "")) 1006 (pc)))] 1007 "" 1008 "{ 1009 operands[1] = fr30_compare_op0; 1010 operands[2] = fr30_compare_op1; 1011 }" 1012) 1013 1014(define_expand "blt" 1015 [(set (reg:CC 16) 1016 (compare:CC (match_dup 1) 1017 (match_dup 2))) 1018 (set (pc) 1019 (if_then_else (lt:CC (reg:CC 16) 1020 (const_int 0)) 1021 (label_ref (match_operand 0 "" "")) 1022 (pc)))] 1023 "" 1024 "{ 1025 operands[1] = fr30_compare_op0; 1026 operands[2] = fr30_compare_op1; 1027 }" 1028) 1029 1030(define_expand "ble" 1031 [(set (reg:CC 16) 1032 (compare:CC (match_dup 1) 1033 (match_dup 2))) 1034 (set (pc) 1035 (if_then_else (le:CC (reg:CC 16) 1036 (const_int 0)) 1037 (label_ref (match_operand 0 "" "")) 1038 (pc)))] 1039 "" 1040 "{ 1041 operands[1] = fr30_compare_op0; 1042 operands[2] = fr30_compare_op1; 1043 }" 1044) 1045 1046(define_expand "bgt" 1047 [(set (reg:CC 16) 1048 (compare:CC (match_dup 1) 1049 (match_dup 2))) 1050 (set (pc) 1051 (if_then_else (gt:CC (reg:CC 16) 1052 (const_int 0)) 1053 (label_ref (match_operand 0 "" "")) 1054 (pc)))] 1055 "" 1056 "{ 1057 operands[1] = fr30_compare_op0; 1058 operands[2] = fr30_compare_op1; 1059 }" 1060) 1061 1062(define_expand "bge" 1063 [(set (reg:CC 16) 1064 (compare:CC (match_dup 1) 1065 (match_dup 2))) 1066 (set (pc) 1067 (if_then_else (ge:CC (reg:CC 16) 1068 (const_int 0)) 1069 (label_ref (match_operand 0 "" "")) 1070 (pc)))] 1071 "" 1072 "{ 1073 operands[1] = fr30_compare_op0; 1074 operands[2] = fr30_compare_op1; 1075 }" 1076) 1077 1078(define_expand "bltu" 1079 [(set (reg:CC 16) 1080 (compare:CC (match_dup 1) 1081 (match_dup 2))) 1082 (set (pc) 1083 (if_then_else (ltu:CC (reg:CC 16) 1084 (const_int 0)) 1085 (label_ref (match_operand 0 "" "")) 1086 (pc)))] 1087 "" 1088 "{ 1089 operands[1] = fr30_compare_op0; 1090 operands[2] = fr30_compare_op1; 1091 }" 1092) 1093 1094(define_expand "bleu" 1095 [(set (reg:CC 16) 1096 (compare:CC (match_dup 1) 1097 (match_dup 2))) 1098 (set (pc) 1099 (if_then_else (leu:CC (reg:CC 16) 1100 (const_int 0)) 1101 (label_ref (match_operand 0 "" "")) 1102 (pc)))] 1103 "" 1104 "{ 1105 operands[1] = fr30_compare_op0; 1106 operands[2] = fr30_compare_op1; 1107 }" 1108) 1109 1110(define_expand "bgtu" 1111 [(set (reg:CC 16) 1112 (compare:CC (match_dup 1) 1113 (match_dup 2))) 1114 (set (pc) 1115 (if_then_else (gtu:CC (reg:CC 16) 1116 (const_int 0)) 1117 (label_ref (match_operand 0 "" "")) 1118 (pc)))] 1119 "" 1120 "{ 1121 operands[1] = fr30_compare_op0; 1122 operands[2] = fr30_compare_op1; 1123 }" 1124) 1125 1126(define_expand "bgeu" 1127 [(set (reg:CC 16) 1128 (compare:CC (match_dup 1) 1129 (match_dup 2))) 1130 (set (pc) 1131 (if_then_else (geu:CC (reg:CC 16) 1132 (const_int 0)) 1133 (label_ref (match_operand 0 "" "")) 1134 (pc)))] 1135 "" 1136 "{ 1137 operands[1] = fr30_compare_op0; 1138 operands[2] = fr30_compare_op1; 1139 }" 1140) 1141 1142;; Actual branches. We must allow for the (label_ref) and the (pc) to be 1143;; swapped. If they are swapped, it reverses the sense of the branch. 1144 1145;; This pattern matches the (branch-if-true) branches generated above. 1146;; It generates two different instruction sequences depending upon how 1147;; far away the destination is. 1148 1149;; The calculation for the instruction length is derived as follows: 1150;; The branch instruction has a 9 bit signed displacement so we have 1151;; this inequality for the displacement: 1152;; 1153;; -256 <= pc < 256 1154;; or 1155;; -256 + 256 <= pc + 256 < 256 + 256 1156;; ie 1157;; 0 <= pc + 256 < 512 1158;; 1159;; if we consider the displacement as an unsigned value, then negative 1160;; displacements become very large positive displacements, and the 1161;; inequality becomes: 1162;; 1163;; pc + 256 < 512 1164;; 1165;; In order to allow for the fact that the real branch instruction works 1166;; from pc + 2, we increase the offset to 258. 1167;; 1168;; Note - we do not have to worry about whether the branch is delayed or 1169;; not, as branch shortening happens after delay slot reorganisation. 1170 1171(define_insn "*branch_true" 1172 [(set (pc) 1173 (if_then_else (match_operator:CC 0 "comparison_operator" 1174 [(reg:CC 16) 1175 (const_int 0)]) 1176 (label_ref (match_operand 1 "" "")) 1177 (pc)))] 1178 "" 1179 "* 1180 { 1181 if (get_attr_length (insn) == 2) 1182 return \"b%b0%#\\t%l1\"; 1183 else 1184 { 1185 static char buffer [100]; 1186 const char * tmp_reg; 1187 const char * ldi_insn; 1188 1189 tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER]; 1190 1191 ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\"; 1192 1193 /* The code produced here is, for say the EQ case: 1194 1195 Bne 1f 1196 LDI <label>, r0 1197 JMP r0 1198 1: */ 1199 1200 sprintf (buffer, 1201 \"b%%B0\\t1f\\t;\\n\\t%s\\t%%l1, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\\n1:\", 1202 ldi_insn, tmp_reg, tmp_reg); 1203 1204 return buffer; 1205 } 1206 }" 1207 [(set (attr "length") (if_then_else 1208 (ltu 1209 (plus 1210 (minus 1211 (match_dup 1) 1212 (pc)) 1213 (const_int 254)) 1214 (const_int 506)) 1215 (const_int 2) 1216 (if_then_else (eq_attr "size" "small") 1217 (const_int 8) 1218 (const_int 10)))) 1219 (set_attr "delay_type" "delayed")] 1220) 1221 1222 1223;; This pattern is a duplicate of the previous one, except that the 1224;; branch occurs if the test is false, so the %B operator is used. 1225(define_insn "*branch_false" 1226 [(set (pc) 1227 (if_then_else (match_operator:CC 0 "comparison_operator" 1228 [(reg:CC 16) 1229 (const_int 0)]) 1230 (pc) 1231 (label_ref (match_operand 1 "" ""))))] 1232 "" 1233 "* 1234 { 1235 if (get_attr_length (insn) == 2) 1236 return \"b%B0%#\\t%l1 \"; 1237 else 1238 { 1239 static char buffer [100]; 1240 const char * tmp_reg; 1241 const char * ldi_insn; 1242 1243 tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER]; 1244 1245 ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\"; 1246 1247 sprintf (buffer, 1248 \"b%%b0\\t1f\\t;\\n\\t%s\\t%%l1, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\\n1:\", 1249 ldi_insn, tmp_reg, tmp_reg); 1250 1251 return buffer; 1252 } 1253 }" 1254 [(set (attr "length") (if_then_else (ltu (plus (minus (match_dup 1) (pc)) 1255 (const_int 254)) 1256 (const_int 506)) 1257 (const_int 2) 1258 (if_then_else (eq_attr "size" "small") 1259 (const_int 8) 1260 (const_int 10)))) 1261 (set_attr "delay_type" "delayed")] 1262) 1263 1264;;}}} 1265;;{{{ Calls & Jumps 1266 1267;; Subroutine call instruction returning no value. Operand 0 is the function 1268;; to call; operand 1 is the number of bytes of arguments pushed (in mode 1269;; `SImode', except it is normally a `const_int'); operand 2 is the number of 1270;; registers used as operands. 1271 1272(define_insn "call" 1273 [(call (match_operand 0 "call_operand" "Qm") 1274 (match_operand 1 "" "g")) 1275 (clobber (reg:SI 17))] 1276 "" 1277 "call%#\\t%0" 1278 [(set_attr "delay_type" "delayed")] 1279) 1280 1281;; Subroutine call instruction returning a value. Operand 0 is the hard 1282;; register in which the value is returned. There are three more operands, the 1283;; same as the three operands of the `call' instruction (but with numbers 1284;; increased by one). 1285 1286;; Subroutines that return `BLKmode' objects use the `call' insn. 1287 1288(define_insn "call_value" 1289 [(set (match_operand 0 "register_operand" "=r") 1290 (call (match_operand 1 "call_operand" "Qm") 1291 (match_operand 2 "" "g"))) 1292 (clobber (reg:SI 17))] 1293 "" 1294 "call%#\\t%1" 1295 [(set_attr "delay_type" "delayed")] 1296) 1297 1298;; Normal unconditional jump. 1299;; For a description of the computation of the length 1300;; attribute see the branch patterns above. 1301;; 1302;; Although this instruction really clobbers r0, flow 1303;; relies on jump being simplejump_p in several places 1304;; and as r0 is fixed, this doesn't change anything 1305(define_insn "jump" 1306 [(set (pc) (label_ref (match_operand 0 "" "")))] 1307 "" 1308 "* 1309 { 1310 if (get_attr_length (insn) == 2) 1311 return \"bra%#\\t%0\"; 1312 else 1313 { 1314 static char buffer [100]; 1315 const char * tmp_reg; 1316 const char * ldi_insn; 1317 1318 tmp_reg = reg_names [COMPILER_SCRATCH_REGISTER]; 1319 1320 ldi_insn = TARGET_SMALL_MODEL ? \"ldi:20\" : \"ldi:32\"; 1321 1322 sprintf (buffer, \"%s\\t%%0, %s\\t;\\n\\tjmp%%#\\t@%s\\t;\", 1323 ldi_insn, tmp_reg, tmp_reg); 1324 1325 return buffer; 1326 } 1327 }" 1328 [(set (attr "length") (if_then_else (ltu (plus (minus (match_dup 0) (pc)) 1329 (const_int 254)) 1330 (const_int 506)) 1331 (const_int 2) 1332 (if_then_else (eq_attr "size" "small") 1333 (const_int 6) 1334 (const_int 8)))) 1335 (set_attr "delay_type" "delayed")] 1336) 1337 1338;; Indirect jump through a register 1339(define_insn "indirect_jump" 1340 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "r"))] 1341 "GET_CODE (operands[0]) != MEM || GET_CODE (XEXP (operands[0], 0)) != PLUS" 1342 "jmp%#\\t@%0" 1343 [(set_attr "delay_type" "delayed")] 1344) 1345 1346(define_insn "tablejump" 1347 [(set (pc) (match_operand:SI 0 "register_operand" "r")) 1348 (use (label_ref (match_operand 1 "" "")))] 1349 "" 1350 "jmp%#\\t@%0" 1351 [(set_attr "delay_type" "delayed")] 1352) 1353 1354;;}}} 1355;;{{{ Function Prologues and Epilogues 1356 1357;; Called after register allocation to add any instructions needed for the 1358;; prologue. Using a prologue insn is favored compared to putting all of the 1359;; instructions in output_function_prologue(), since it allows the scheduler 1360;; to intermix instructions with the saves of the caller saved registers. In 1361;; some cases, it might be necessary to emit a barrier instruction as the last 1362;; insn to prevent such scheduling. 1363(define_expand "prologue" 1364 [(clobber (const_int 0))] 1365 "" 1366 "{ 1367 fr30_expand_prologue (); 1368 DONE; 1369 }" 1370) 1371 1372;; Called after register allocation to add any instructions needed for the 1373;; epilogue. Using an epilogue insn is favored compared to putting all of the 1374;; instructions in output_function_epilogue(), since it allows the scheduler 1375;; to intermix instructions with the restores of the caller saved registers. 1376;; In some cases, it might be necessary to emit a barrier instruction as the 1377;; first insn to prevent such scheduling. 1378(define_expand "epilogue" 1379 [(return)] 1380 "" 1381 "{ 1382 fr30_expand_epilogue (); 1383 DONE; 1384 }" 1385) 1386 1387(define_insn "return_from_func" 1388 [(return) 1389 (use (reg:SI 17))] 1390 "reload_completed" 1391 "ret%#" 1392 [(set_attr "delay_type" "delayed")] 1393) 1394 1395(define_insn "leave_func" 1396 [(set (reg:SI 15) (reg:SI 14)) 1397 (set (reg:SI 14) (mem:SI (post_inc:SI (reg:SI 15))))] 1398 "reload_completed" 1399 "leave" 1400) 1401 1402(define_insn "enter_func" 1403 [(set:SI (mem:SI (minus:SI (reg:SI 15) 1404 (const_int 4))) 1405 (reg:SI 14)) 1406 (set:SI (reg:SI 14) 1407 (minus:SI (reg:SI 15) 1408 (const_int 4))) 1409 (set:SI (reg:SI 15) 1410 (minus:SI (reg:SI 15) 1411 (match_operand 0 "immediate_operand" "i")))] 1412 "reload_completed" 1413 "enter #%0" 1414 [(set_attr "delay_type" "other")] 1415) 1416 1417;;}}} 1418;;{{{ Miscellaneous 1419 1420;; No operation, needed in case the user uses -g but not -O. 1421(define_insn "nop" 1422 [(const_int 0)] 1423 "" 1424 "nop" 1425) 1426 1427;; Pseudo instruction that prevents the scheduler from moving code above this 1428;; point. 1429(define_insn "blockage" 1430 [(unspec_volatile [(const_int 0)] 0)] 1431 "" 1432 "" 1433 [(set_attr "length" "0")] 1434) 1435;;}}} 1436 1437;; Local Variables: 1438;; mode: md 1439;; folded-file: t 1440;; End: 1441