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