|
|
1.1 root 1: ;;- Machine description for ROMP chip for GNU C compiler 1.1.1.4 ! root 2: ;; Copyright (C) 1988, 1991, 1993, 1994, 1995 Free Software Foundation, Inc. 1.1.1.3 root 3: ;; Contributed by Richard Kenner ([email protected]) 1.1 root 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 1.1.1.4 ! root 19: ;; the Free Software Foundation, 59 Temple Place - Suite 330, ! 20: ;; Boston, MA 02111-1307, USA. 1.1 root 21: 22: 23: ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 24: 25: ;; Define the attributes for the ROMP. 26: 27: ;; Insn type. Used to default other attribute values. 28: 29: (define_attr "type" 30: "branch,ibranch,return,fp,load,loadz,store,call,address,arith,compare,multi,misc" 31: (const_string "arith")) 32: 33: ;; Length in bytes. 34: 35: (define_attr "length" "" 36: (cond [(eq_attr "type" "branch") 37: (if_then_else (and (ge (minus (pc) (match_dup 0)) 38: (const_int -256)) 39: (le (minus (pc) (match_dup 0)) 40: (const_int 254))) 41: (const_int 2) 42: (const_int 4)) 43: (eq_attr "type" "return,ibranch") (const_int 2) 44: (eq_attr "type" "fp") (const_int 10) 45: (eq_attr "type" "call") (const_int 4) 46: (eq_attr "type" "load") 47: (cond [(match_operand 1 "short_memory_operand" "") (const_int 2) 48: (match_operand 1 "symbolic_memory_operand" "") (const_int 8)] 49: (const_int 4)) 50: (eq_attr "type" "loadz") 51: (cond [(match_operand 1 "zero_memory_operand" "") (const_int 2) 52: (match_operand 1 "symbolic_memory_operand" "") (const_int 8)] 53: (const_string "4")) 54: (eq_attr "type" "store") 55: (cond [(match_operand 0 "short_memory_operand" "") (const_int 2) 56: (match_operand 0 "symbolic_memory_operand" "") (const_int 8)] 57: (const_int 4))] 58: (const_int 4))) 59: 60: ;; Whether insn can be placed in a delay slot. 61: 62: (define_attr "in_delay_slot" "yes,no" 63: (cond [(eq_attr "length" "8,10,38") (const_string "no") 64: (eq_attr "type" "branch,ibranch,return,call,multi") 65: (const_string "no")] 66: (const_string "yes"))) 67: 68: ;; Whether insn needs a delay slot. We have to say that two-byte 69: ;; branches do not need a delay slot. Otherwise, branch shortening will 70: ;; try to do something with delay slot insns (we want it to on the PA). 71: ;; This is a kludge, which should be cleaned up at some point. 72: 73: (define_attr "needs_delay_slot" "yes,no" 74: (if_then_else (ior (and (eq_attr "type" "branch") 75: (eq_attr "length" "4")) 76: (eq_attr "type" "ibranch,return,call")) 77: (const_string "yes") (const_string "no"))) 78: 79: ;; What insn does to the condition code. 80: 81: (define_attr "cc" 82: "clobber,none,sets,change0,copy1to0,compare,tbit" 83: (cond [(eq_attr "type" "load,loadz") (const_string "change0") 84: (eq_attr "type" "store") (const_string "none") 85: (eq_attr "type" "fp,call") (const_string "clobber") 86: (eq_attr "type" "branch,ibranch,return") (const_string "none") 87: (eq_attr "type" "address") (const_string "change0") 88: (eq_attr "type" "compare") (const_string "compare") 89: (eq_attr "type" "arith") (const_string "sets")] 90: (const_string "clobber"))) 91: 92: ;; Define attributes for `asm' insns. 93: 94: (define_asm_attributes [(set_attr "type" "misc") 95: (set_attr "length" "8") 96: (set_attr "in_delay_slot" "no") 97: (set_attr "cc" "clobber")]) 98: 99: ;; Define the delay slot requirements for branches and calls. We don't have 100: ;; any annulled insns. 101: ;; 102: (define_delay (eq_attr "needs_delay_slot" "yes") 103: [(eq_attr "in_delay_slot" "yes") (nil) (nil)]) 104: 105: ;; We cannot give a floating-point comparison a delay slot, even though it 106: ;; could make use of it. This is because it would confuse next_cc0_user 107: ;; to do so. Other fp insns can't get a delay slow because they set their 108: ;; result and use their input after the delay slot insn is executed. This 109: ;; isn't what reorg.c expects. 110: 111: ;; Define load & store delays. These were obtained by measurements done by 112: ;; [email protected]. 113: ;; 114: ;; In general, the memory unit can support at most two simultaneous operations. 115: ;; 116: ;; Loads take 5 cycles to return the data and can be pipelined up to the 117: ;; limit of two simultaneous operations. 118: (define_function_unit "memory" 1 2 (eq_attr "type" "load,loadz") 5 0) 119: 120: ;; Stores do not return data, but tie up the memory unit for 2 cycles if the 121: ;; next insn is also a store. 122: (define_function_unit "memory" 1 2 (eq_attr "type" "store") 1 2 123: [(eq_attr "type" "store")]) 124: 125: ;; Move word instructions. 126: ;; 127: ;; If destination is memory but source is not register, force source to 128: ;; register. 129: ;; 130: ;; If source is a constant that is too large to load in a single insn, build 131: ;; it in two pieces. 132: ;; 133: ;; If destination is memory and source is a register, a temporary register 134: ;; will be needed. In that case, make a PARALLEL of the SET and a 135: ;; CLOBBER of a SCRATCH to allocate the required temporary. 136: ;; 137: ;; This temporary is ACTUALLY only needed when the destination is a 138: ;; relocatable expression. For generating RTL, however, we always 139: ;; place the CLOBBER. In insns where it is not needed, the SCRATCH will 140: ;; not be allocated to a register. 141: ;; 142: ;; Also, avoid creating pseudo-registers or SCRATCH rtx's during reload as 143: ;; they will not be correctly handled. We never need pseudos for that 144: ;; case anyway. 145: ;; 146: ;; We do not use DEFINE_SPLIT for loading constants because the number 147: ;; of cases in the resulting unsplit insn would be too high to deal 148: ;; with practically. 149: (define_expand "movsi" 150: [(set (match_operand:SI 0 "general_operand" "") 151: (match_operand:SI 1 "general_operand" ""))] 152: "" 153: " 154: { rtx op0 = operands[0]; 155: rtx op1 = operands[1]; 156: 157: if (GET_CODE (op1) == REG && REGNO (op1) == 16) 158: DONE; 159: 160: if (GET_CODE (op0) == REG && REGNO (op0) == 16) 161: DONE; 162: 163: if (GET_CODE (op0) == MEM && ! reload_in_progress) 164: { 165: emit_insn (gen_storesi (operands[0], force_reg (SImode, operands[1]))); 166: DONE; 167: } 168: else if (GET_CODE (op1) == CONST_INT) 169: { 170: int const_val = INTVAL (op1); 171: 172: /* Try a number of cases to see how to best load the constant. */ 173: if ((const_val & 0xffff) == 0 174: || (const_val & 0xffff0000) == 0 175: || (unsigned) (const_val + 0x8000) < 0x10000) 176: /* Can do this in one insn, so generate it. */ 177: ; 178: else if (((- const_val) & 0xffff) == 0 179: || ((- const_val) & 0xffff0000) == 0 180: || (unsigned) ((- const_val) + 0x8000) < 0x10000) 181: { 182: /* Can do this by loading the negative constant and then negating. */ 183: emit_move_insn (operands[0], 184: gen_rtx (CONST_INT, VOIDmode, - const_val)); 185: emit_insn (gen_negsi2 (operands[0], operands[0])); 186: DONE; 187: } 188: else 189: /* Do this the long way. */ 190: { 191: unsigned int high_part = const_val & 0xffff0000; 192: unsigned int low_part = const_val & 0xffff; 193: int i; 194: 195: if (low_part >= 0x10 && exact_log2 (low_part) >= 0) 196: i = high_part, high_part = low_part, low_part = i; 197: 198: emit_move_insn (operands[0], 199: gen_rtx (CONST_INT, VOIDmode, low_part)); 200: emit_insn (gen_iorsi3 (operands[0], operands[0], 201: gen_rtx (CONST_INT, VOIDmode, high_part))); 202: DONE; 203: } 204: } 205: }") 206: 207: ;; Move from a symbolic memory location to a register is special. In this 208: ;; case, we know in advance that the register cannot be r0, so we can improve 209: ;; register allocation by treating it separately. 210: 211: (define_insn "" 212: [(set (match_operand:SI 0 "register_operand" "=b") 213: (match_operand:SI 1 "symbolic_memory_operand" "m"))] 214: "" 215: "load %0,%1" 216: [(set_attr "type" "load")]) 217: 218: ;; Generic single-word move insn. We avoid the case where the destination is 219: ;; a symbolic address, as that needs a temporary register. 220: 221: (define_insn "" 222: [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,r,r,r,b,Q") 223: (match_operand:SI 1 "romp_operand" "rR,I,K,L,M,S,s,Q,m,r"))] 224: "register_operand (operands[0], SImode) 225: || register_operand (operands[1], SImode)" 226: "@ 227: cas %0,%1,r0 228: lis %0,%1 229: cal %0,%1(r0) 230: cal16 %0,%1(r0) 231: cau %0,%H1(r0) 232: ail %0,r14,%C1 233: get %0,$%1 234: l%M1 %0,%1 235: load %0,%1 236: st%M0 %1,%0" 237: [(set_attr "type" "address,address,address,address,address,arith,misc,load,load,store") 238: (set_attr "length" "2,2,4,4,4,4,8,*,*,*")]) 239: 240: (define_insn "storesi" 241: [(set (match_operand:SI 0 "memory_operand" "=Q,m") 242: (match_operand:SI 1 "register_operand" "r,r")) 243: (clobber (match_scratch:SI 2 "=X,&b"))] 244: "" 245: "@ 246: st%M0 %1,%0 247: store %1,%0,%2" 248: [(set_attr "type" "store")]) 249: 250: ;; This pattern is used by reload when we store into a symbolic address. It 251: ;; provides the temporary register required. This pattern is only used 252: ;; when SECONDARY_OUTPUT_RELOAD_CLASS returns something other than 253: ;; NO_REGS, so we need not have any predicates here. 254: 255: (define_expand "reload_outsi" 256: [(parallel [(set (match_operand:SI 0 "symbolic_memory_operand" "=m") 257: (match_operand:SI 1 "" "r")) 258: (clobber (match_operand:SI 2 "" "=&b"))])] 259: "" 260: "") 261: 262: ;; Now do the same for the QI move instructions. 263: (define_expand "movqi" 264: [(set (match_operand:QI 0 "general_operand" "") 265: (match_operand:QI 1 "general_operand" ""))] 266: "" 267: " 268: { rtx op0 = operands[0]; 269: 270: if (GET_CODE (op0) == MEM && ! reload_in_progress) 271: { 272: emit_insn (gen_storeqi (operands[0], force_reg (QImode, operands[1]))); 273: DONE; 274: } 275: }") 276: 277: (define_insn "" 278: [(set (match_operand:QI 0 "register_operand" "=b") 279: (match_operand:QI 1 "symbolic_memory_operand" "m"))] 280: "" 281: "loadc %0,%1" 282: [(set_attr "type" "load")]) 283: 284: (define_insn "" 285: [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,b,Q") 286: (match_operand:QI 1 "romp_operand" "r,I,n,s,Q,m,r"))] 287: "register_operand (operands[0], QImode) 288: || register_operand (operands[1], QImode)" 289: "@ 290: cas %0,%1,r0 291: lis %0,%1 292: cal %0,%L1(r0) 293: get %0,$%1 294: lc%M1 %0,%1 295: loadc %0,%1 296: stc%M0 %1,%0" 297: [(set_attr "type" "address,address,address,misc,load,load,store") 298: (set_attr "length" "2,2,4,8,*,*,*")]) 299: 300: (define_insn "storeqi" 301: [(set (match_operand:QI 0 "memory_operand" "=Q,m") 302: (match_operand:QI 1 "register_operand" "r,r")) 303: (clobber (match_scratch:SI 2 "=X,&b"))] 304: "" 305: "@ 306: stc%M0 %1,%0 307: storec %1,%0,%2" 308: [(set_attr "type" "store")]) 309: 310: (define_expand "reload_outqi" 311: [(parallel [(set (match_operand:QI 0 "symbolic_memory_operand" "=m") 312: (match_operand:QI 1 "" "r")) 313: (clobber (match_operand:SI 2 "" "=&b"))])] 314: "" 315: "") 316: 317: ;; Finally, the HI instructions. 318: (define_expand "movhi" 319: [(set (match_operand:HI 0 "general_operand" "") 320: (match_operand:HI 1 "general_operand" ""))] 321: "" 322: " 323: { rtx op0 = operands[0]; 324: 325: if (GET_CODE (op0) == MEM && ! reload_in_progress) 326: { 327: emit_insn (gen_storehi (operands[0], force_reg (HImode, operands[1]))); 328: DONE; 329: } 330: }") 331: 332: (define_insn "" 333: [(set (match_operand:HI 0 "register_operand" "=b") 334: (match_operand:HI 1 "symbolic_memory_operand" "m"))] 335: "" 336: "loadha %0,%1" 337: [(set_attr "type" "load")]) 338: 1.1.1.2 root 339: 340: ;; use cal16 instead of cal for constant source because combine requires 341: ;; the high bits of the register to be 0 after a HImode load of a constant 342: 1.1 root 343: (define_insn "" 344: [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,b,Q") 345: (match_operand:HI 1 "romp_operand" "r,I,n,s,Q,m,r"))] 346: "register_operand (operands[0], HImode) 347: || register_operand (operands[1], HImode)" 348: "@ 349: cas %0,%1,r0 350: lis %0,%1 1.1.1.2 root 351: cal16 %0,%L1(r0) 1.1 root 352: get %0,$%1 353: lh%N1 %0,%1 354: loadh %0,%1 355: sth%M0 %1,%0" 356: [(set_attr "type" "address,address,address,misc,loadz,loadz,store") 357: (set_attr "length" "2,2,4,8,*,*,*")]) 358: 359: (define_insn "storehi" 360: [(set (match_operand:HI 0 "memory_operand" "=Q,m") 361: (match_operand:HI 1 "register_operand" "r,r")) 362: (clobber (match_scratch:SI 2 "=X,&b"))] 363: "" 364: "@ 365: sth%M0 %1,%0 366: storeh %1,%0,%2" 367: [(set_attr "type" "store")]) 368: 369: (define_expand "reload_outhi" 370: [(parallel [(set (match_operand:HI 0 "symbolic_memory_operand" "=m") 371: (match_operand:HI 1 "" "r")) 372: (clobber (match_operand:SI 2 "" "=&b"))])] 373: "" 374: "") 375: 376: ;; For DI move, if we have a constant, break the operation apart into 377: ;; two SImode moves because the optimizer may be able to do a better job 378: ;; with the resulting code. 379: ;; 380: ;; For memory stores, make the required pseudo for a temporary in case we 381: ;; are storing into an absolute address. 382: ;; 383: ;; We need to be careful about the cases where the output is a register that is 384: ;; the second register of the input. 385: 386: (define_expand "movdi" 387: [(set (match_operand:DI 0 "general_operand" "") 388: (match_operand:DI 1 "general_operand" ""))] 389: "" 390: " 391: { rtx op0 = operands[0]; 392: rtx op1 = operands[1]; 393: 394: if (CONSTANT_P (op1)) 395: { 396: rtx insns; 397: 398: start_sequence (); 399: emit_move_insn (operand_subword (op0, 0, 1, DImode), 400: operand_subword (op1, 0, 1, DImode)); 401: emit_move_insn (operand_subword (op0, 1, 1, DImode), 402: operand_subword (op1, 1, 1, DImode)); 403: insns = get_insns (); 404: end_sequence (); 405: 406: emit_no_conflict_block (insns, op0, op1, 0, op1); 407: DONE; 408: } 409: 410: if (GET_CODE (op0) == MEM && ! reload_in_progress) 411: { 412: emit_insn (gen_storedi (operands[0], force_reg (DImode, operands[1]))); 413: DONE; 414: } 415: }") 416: 417: (define_insn "" 418: [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q") 419: (match_operand:DI 1 "reg_or_mem_operand" "r,Q,m,r"))] 420: "register_operand (operands[0], DImode) 421: || register_operand (operands[1], DImode)" 422: "* 423: { 424: switch (which_alternative) 425: { 426: case 0: 427: if (REGNO (operands[0]) == REGNO (operands[1]) + 1) 428: return \"cas %O0,%O1,r0\;cas %0,%1,r0\"; 429: else 430: return \"cas %0,%1,r0\;cas %O0,%O1,r0\"; 431: case 1: 432: /* Here we must see which word to load first. We default to the 433: low-order word unless it occurs in the address. */ 434: if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, 435: operands[1], 0)) 436: return \"l%M1 %O0,%O1\;l%M1 %0,%1\"; 437: else 438: return \"l%M1 %0,%1\;l%M1 %O0,%O1\"; 439: case 2: 440: return \"get %O0,$%1\;ls %0,0(%O0)\;ls %O0,4(%O0)\"; 441: case 3: 442: return \"st%M0 %1,%0\;st%M0 %O1,%O0\"; 443: } 444: }" 445: [(set_attr "type" "multi") 446: (set_attr "cc" "change0,change0,change0,none") 447: (set_attr "length" "4,12,8,8")]) 448: 449: (define_insn "storedi" 450: [(set (match_operand:DI 0 "memory_operand" "=Q,m") 451: (match_operand:DI 1 "register_operand" "r,r")) 452: (clobber (match_scratch:SI 2 "=X,&b"))] 453: "" 454: "@ 455: st%M0 %1,%0\;st%M0 %O1,%O0 456: get %2,$%0\;sts %1,0(%2)\;sts %O1,4(%2)" 457: [(set_attr "type" "multi,multi") 458: (set_attr "cc" "none,none") 459: (set_attr "length" "8,12")]) 460: 461: (define_expand "reload_outdi" 462: [(parallel [(set (match_operand:DI 0 "symbolic_memory_operand" "=m") 463: (match_operand:DI 1 "" "r")) 464: (clobber (match_operand:SI 2 "" "=&b"))])] 465: "" 466: "") 467: 468: ;; Split symbolic memory operands differently. We first load the address 469: ;; into a register and then do the two loads or stores. We can only do 470: ;; this if operand_subword won't produce a SUBREG, which is only when 471: ;; operands[0] is a hard register. Thus, these won't be used during the 472: ;; first insn scheduling pass. 473: (define_split 474: [(set (match_operand:DI 0 "register_operand" "") 475: (match_operand:DI 1 "symbolic_memory_operand" ""))] 476: "GET_CODE (operands[0]) == REG 477: && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER" 478: [(set (match_dup 2) (match_dup 3)) 479: (set (match_dup 4) (match_dup 5)) 480: (set (match_dup 6) (match_dup 7))] 481: " 482: { operands[2] = operand_subword (operands[0], 1, 0, DImode); 483: operands[3] = XEXP (operands[1], 0); 484: operands[4] = operand_subword (operands[0], 0, 0, DImode); 485: operands[5] = gen_rtx (MEM, SImode, operands[2]); 486: operands[6] = operands[2]; 487: operands[7] = gen_rtx (MEM, SImode, 488: gen_rtx (PLUS, SImode, operands[2], 489: gen_rtx (CONST_INT, VOIDmode, 4))); 490: 491: if (operands[2] == 0 || operands[4] == 0) 492: FAIL; 493: }") 494: 495: (define_split 496: [(set (match_operand:DI 0 "symbolic_memory_operand" "") 497: (match_operand:DI 1 "register_operand" "")) 498: (clobber (match_operand:SI 2 "register_operand" ""))] 499: "GET_CODE (operands[0]) == REG 500: && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER" 501: [(set (match_dup 2) (match_dup 3)) 502: (set (match_dup 4) (match_dup 5)) 503: (set (match_dup 6) (match_dup 7))] 504: " 505: { operands[3] = XEXP (operands[0], 0); 506: operands[4] = gen_rtx (MEM, SImode, operands[2]); 507: operands[5] = operand_subword (operands[1], 0, 0, DImode); 508: operands[6] = gen_rtx (MEM, SImode, 509: gen_rtx (PLUS, SImode, operands[2], 510: gen_rtx (CONST_INT, VOIDmode, 4))); 511: operands[7] = operand_subword (operands[1], 1, 0, DImode); 512: 513: if (operands[5] == 0 || operands[7] == 0) 514: FAIL; 515: }") 516: 517: ;; If the output is a register and the input is memory, we have to be careful 518: ;; and see which word needs to be loaded first. 519: ;; 520: ;; Note that this case doesn't have a CLOBBER. Therefore, we must either 521: ;; be after reload or operand[0] must not be a MEM. So we don't need a 522: ;; CLOBBER on the new insns either. 523: ;; 524: ;; Due to a bug in sched.c, we do not want to split this insn if both 525: ;; operands are registers and they overlap unless reload has completed. 526: (define_split 527: [(set (match_operand:DI 0 "general_operand" "") 528: (match_operand:DI 1 "general_operand" ""))] 529: "! symbolic_memory_operand (operands[0], DImode) 530: && ! symbolic_memory_operand (operands[1], DImode) 531: && ! (GET_CODE (operands[0]) == REG 532: && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER) 533: && ! (GET_CODE (operands[1]) == REG 534: && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER) 535: && ! (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG 536: && ! reload_completed 537: && reg_overlap_mentioned_p (operands[0], operands[1]))" 538: [(set (match_dup 2) (match_dup 3)) 539: (set (match_dup 4) (match_dup 5))] 540: " 541: { if (GET_CODE (operands[0]) != REG 542: || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, 543: operands[1], 0)) 544: { 545: operands[2] = operand_subword (operands[0], 0, 0, DImode); 546: operands[3] = operand_subword (operands[1], 0, 0, DImode); 547: operands[4] = operand_subword (operands[0], 1, 0, DImode); 548: operands[5] = operand_subword (operands[1], 1, 0, DImode); 549: } 550: else 551: { 552: operands[2] = operand_subword (operands[0], 1, 0, DImode); 553: operands[3] = operand_subword (operands[1], 1, 0, DImode); 554: operands[4] = operand_subword (operands[0], 0, 0, DImode); 555: operands[5] = operand_subword (operands[1], 0, 0, DImode); 556: } 557: 558: if (operands[2] == 0 || operands[3] == 0 559: || operands[4] == 0 || operands[5] == 0) 560: FAIL; 561: }") 562: 563: (define_split 564: [(set (match_operand:DI 0 "general_operand" "") 565: (match_operand:DI 1 "general_operand" "")) 566: (clobber (match_operand:SI 6 "register_operand" ""))] 567: "! symbolic_memory_operand (operands[0], DImode) 568: && ! symbolic_memory_operand (operands[1], DImode) 569: && ! (GET_CODE (operands[0]) == REG 570: && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER) 571: && ! (GET_CODE (operands[1]) == REG 572: && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER) 573: && ! (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG 574: && ! reload_completed 575: && reg_overlap_mentioned_p (operands[0], operands[1]))" 576: [(parallel [(set (match_dup 2) (match_dup 3)) 577: (clobber (match_dup 7))]) 578: (parallel [(set (match_dup 4) (match_dup 5)) 579: (clobber (match_dup 8))])] 580: " 581: { if (GET_CODE (operands[0]) != REG 582: || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, 583: operands[1], 0)) 584: { 585: operands[2] = operand_subword (operands[0], 0, 0, DImode); 586: operands[3] = operand_subword (operands[1], 0, 0, DImode); 587: operands[4] = operand_subword (operands[0], 1, 0, DImode); 588: operands[5] = operand_subword (operands[1], 1, 0, DImode); 589: } 590: else 591: { 592: operands[2] = operand_subword (operands[0], 1, 0, DImode); 593: operands[3] = operand_subword (operands[1], 1, 0, DImode); 594: operands[4] = operand_subword (operands[0], 0, 0, DImode); 595: operands[5] = operand_subword (operands[1], 0, 0, DImode); 596: } 597: 598: if (operands[2] == 0 || operands[3] == 0 599: || operands[4] == 0 || operands[5] == 0) 600: FAIL; 601: 602: /* We must be sure to make two different SCRATCH operands, since they 603: are not allowed to be shared. After reload, however, we only have 604: a SCRATCH if we won't use the operand, so it is allowed to share it 605: then. */ 606: if (reload_completed || GET_CODE (operands[6]) != SCRATCH) 607: operands[7] = operands[8] = operands[6]; 608: else 609: { 610: operands[7] = gen_rtx (SCRATCH, SImode); 611: operands[8] = gen_rtx (SCRATCH, SImode); 612: } 613: }") 614: 615: ;; Define move insns for SF, and DF. 616: ;; 617: ;; For register-register copies or a copy of something to itself, emit a 618: ;; single SET insn since it will likely be optimized away. 619: ;; 620: ;; Otherwise, emit a floating-point move operation unless both input and 621: ;; output are either constant, memory, or a non-floating-point hard register. 622: (define_expand "movdf" 623: [(parallel [(set (match_operand:DF 0 "general_operand" "") 624: (match_operand:DF 1 "general_operand" "")) 625: (clobber (reg:SI 0)) 626: (clobber (reg:SI 15))])] 627: "" 628: " 629: { rtx op0 = operands[0]; 630: rtx op1 = operands[1]; 631: 632: if (op0 == op1) 633: { 634: emit_insn (gen_rtx (SET, VOIDmode, op0, op1)); 635: DONE; 636: } 637: 638: if ((GET_CODE (op0) == MEM 639: || (GET_CODE (op0) == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER 640: && ! FP_REGNO_P (REGNO (op0)))) 641: && (GET_CODE (op1) == MEM 642: || GET_CODE (op1) == CONST_DOUBLE 643: || (GET_CODE (op1) == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER 644: && ! FP_REGNO_P (REGNO (op1)) && ! rtx_equal_p (op0, op1)))) 645: { 646: rtx insns; 647: 648: if (GET_CODE (op1) == CONST_DOUBLE) 649: op1 = force_const_mem (DFmode, op1); 650: 651: start_sequence (); 652: if (GET_CODE (operands[0]) != REG 653: || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, 654: operands[1]), 0) 655: { 656: emit_move_insn (operand_subword (op0, 0, 1, DFmode), 657: operand_subword_force (op1, 0, DFmode)); 658: emit_move_insn (operand_subword (op0, 1, 1, DFmode), 659: operand_subword_force (op1, 1, DFmode)); 660: } 661: else 662: { 663: emit_move_insn (operand_subword (op0, 1, 1, DFmode), 664: operand_subword_force (op1, 1, DFmode)); 665: emit_move_insn (operand_subword (op0, 0, 1, DFmode), 666: operand_subword_force (op1, 0, DFmode)); 667: } 668: 669: insns = get_insns (); 670: end_sequence (); 671: 672: emit_no_conflict_block (insns, op0, op1, 0, op1); 673: DONE; 674: } 675: }") 676: 677: (define_expand "movsf" 678: [(parallel [(set (match_operand:SF 0 "general_operand" "") 679: (match_operand:SF 1 "general_operand" "")) 680: (clobber (reg:SI 0)) 681: (clobber (reg:SI 15))])] 682: "" 683: " 684: { rtx op0 = operands[0]; 685: rtx op1 = operands[1]; 686: 687: if (op0 == op1) 688: { 689: emit_insn (gen_rtx (SET, VOIDmode, op0, op1)); 690: DONE; 691: } 692: 693: if ((GET_CODE (op0) == MEM 694: || (GET_CODE (op0) == REG && REGNO (op0) < FIRST_PSEUDO_REGISTER 695: && ! FP_REGNO_P (REGNO (op0)))) 696: && (GET_CODE (op1) == MEM 697: || GET_CODE (op1) == CONST_DOUBLE 698: || (GET_CODE (op1) == REG && REGNO (op1) < FIRST_PSEUDO_REGISTER 699: && ! FP_REGNO_P (REGNO (op1))))) 700: { 701: rtx last; 702: 703: if (GET_CODE (op1) == CONST_DOUBLE) 704: op1 = force_const_mem (SFmode, op1); 705: 706: last = emit_move_insn (operand_subword (op0, 0, 1, SFmode), 707: operand_subword_force (op1, 0, SFmode)); 708: 709: REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, op1, REG_NOTES (last)); 710: DONE; 711: } 712: }") 713: 714: ;; Define the move insns for SF and DF. Check for all general regs 715: ;; in the FP insns and make them non-FP if so. Do the same if the input and 716: ;; output are the same (the insn will be deleted in this case and we don't 717: ;; want to think there are FP insns when there might not be). 718: (define_insn "" 719: [(set (match_operand:SF 0 "general_operand" "=*frg") 720: (match_dup 0))] 721: "" 722: "nopr r0" 723: [(set_attr "type" "address") 724: (set_attr "length" "2")]) 725: 726: (define_insn "" 727: [(set (match_operand:SF 0 "general_operand" "=r,*fr,r,r,Q,m,frg") 728: (match_operand:SF 1 "general_operand" "r,0,Q,m,r,r,frg")) 729: (clobber (match_operand:SI 2 "reg_0_operand" "=&z,z,z,z,z,z,z")) 730: (clobber (match_operand:SI 3 "reg_15_operand" "=&t,t,t,t,t,t,t"))] 731: "" 732: "* 733: { switch (which_alternative) 734: { 735: case 0: 736: return \"cas %0,%1,r0\"; 737: case 1: 738: return \"nopr r0\"; 739: case 2: 740: return \"l%M1 %0,%1\"; 741: case 3: 742: return \"load %0,%1\"; 743: case 4: 744: return \"st%M0 %1,%0\"; 745: case 5: 746: return \"store %1,%0,%3\"; 747: default: 748: return output_fpop (SET, operands[0], operands[1], 0, insn); 749: } 750: }" 751: [(set_attr "type" "address,address,load,load,store,store,fp") 752: (set_attr "length" "2,2,*,*,*,*,*")]) 753: 754: (define_insn "" 755: [(set (match_operand:DF 0 "general_operand" "=*frg") 756: (match_dup 0))] 757: "" 758: "nopr r0" 759: [(set_attr "type" "address") 760: (set_attr "length" "2")]) 761: 762: (define_insn "" 763: [(set (match_operand:DF 0 "general_operand" "=r,*fr,r,r,Q,m,frg") 764: (match_operand:DF 1 "general_operand" "r,0,Q,m,r,r,*frg")) 765: (clobber (match_operand:SI 2 "reg_0_operand" "=&z,z,z,z,z,z,z")) 766: (clobber (match_operand:SI 3 "reg_15_operand" "=&t,t,t,t,t,t,t"))] 767: "" 768: "* 769: { switch (which_alternative) 770: { 771: case 0: 772: if (REGNO (operands[0]) == REGNO (operands[1]) + 1) 773: return \"cas %O0,%O1,r0\;cas %0,%1,r0\"; 774: else 775: return \"cas %0,%1,r0\;cas %O0,%O1,r0\"; 776: case 1: 777: return \"nopr r0\"; 778: case 2: 779: /* Here we must see which word to load first. We default to the 780: low-order word unless it occurs in the address. */ 781: if (refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, 782: operands[1], 0)) 783: return \"l%M1 %O0,%O1\;l%M1 %0,%1\"; 784: else 785: return \"l%M1 %0,%1\;l%M1 %O0,%O1\"; 786: case 3: 787: return \"get %3,$%1\;ls %0,0(%3)\;ls %O0,4(%3)\"; 788: case 4: 789: return \"st%M0 %1,%0\;st%M0 %O1,%O0\"; 790: case 5: 791: return \"get %3,$%0\;sts %1,0(%3)\;sts %O1,4(%3)\"; 792: default: 793: return output_fpop (SET, operands[0], operands[1], 0, insn); 794: } 795: }" 796: [(set_attr "type" "address,multi,multi,multi,multi,multi,fp") 797: (set_attr "length" "2,4,*,*,*,*,*")]) 798: 799: ;; Split all the above cases that involve multiple insns and no floating-point 800: ;; data block. If before reload, we can make a SCRATCH. Otherwise, use 801: ;; register 15. 802: 803: (define_split 804: [(set (match_operand:DF 0 "register_operand" "") 805: (match_operand:DF 1 "symbolic_memory_operand" "")) 806: (clobber (reg:SI 0)) 807: (clobber (reg:SI 15))] 808: "GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 16" 809: [(set (reg:SI 15) (match_dup 2)) 810: (set (match_dup 3) (match_dup 4)) 811: (set (match_dup 5) (match_dup 6))] 812: " 813: { operands[2] = XEXP (operands[1], 0); 814: operands[3] = operand_subword (operands[0], 0, 0, DFmode); 815: operands[4] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 15)); 816: operands[5] = operand_subword (operands[0], 1, 0, DFmode); 817: operands[6] = gen_rtx (MEM, SImode, 818: gen_rtx (PLUS, SImode, gen_rtx (REG, SImode, 15), 819: gen_rtx (CONST_INT, VOIDmode, 4))); 820: 821: if (operands[3] == 0 || operands[5] == 0) 822: FAIL; 823: }") 824: 825: (define_split 826: [(set (match_operand:DF 0 "symbolic_memory_operand" "") 827: (match_operand:DF 1 "register_operand" "")) 828: (clobber (reg:SI 0)) 829: (clobber (reg:SI 15))] 830: "GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 16" 831: [(set (reg:SI 15) (match_dup 2)) 832: (set (match_dup 3) (match_dup 4)) 833: (set (match_dup 5) (match_dup 6))] 834: " 835: { operands[2] = XEXP (operands[0], 0); 836: operands[3] = gen_rtx (MEM, SImode, gen_rtx (REG, SImode, 15)); 837: operands[4] = operand_subword (operands[1], 0, 0, DFmode); 838: operands[5] = gen_rtx (MEM, SImode, 839: gen_rtx (PLUS, SImode, gen_rtx (REG, SImode, 15), 840: gen_rtx (CONST_INT, VOIDmode, 4))); 841: operands[6] = operand_subword (operands[1], 1, 0, DFmode); 842: 843: if (operands[4] == 0 || operands[6] == 0) 844: FAIL; 845: }") 846: 847: ;; If the output is a register and the input is memory, we have to be careful 848: ;; and see which word needs to be loaded first. We also cannot to the 849: ;; split if the input is a constant because it would result in invalid 850: ;; insns. When the output is a MEM, we must put a CLOBBER on each of the 851: ;; resulting insn, when it is not a MEM, we must not. 852: (define_split 853: [(set (match_operand:DF 0 "memory_operand" "") 854: (match_operand:DF 1 "register_operand" "")) 855: (clobber (reg:SI 0)) 856: (clobber (reg:SI 15))] 857: "GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 15" 858: [(parallel [(set (match_dup 2) (match_dup 3)) 859: (clobber (match_dup 6))]) 860: (parallel [(set (match_dup 4) (match_dup 5)) 861: (clobber (match_dup 7))])] 862: " 863: { operands[2] = operand_subword (operands[0], 0, 0, DFmode); 864: operands[3] = operand_subword (operands[1], 0, 0, DFmode); 865: operands[4] = operand_subword (operands[0], 1, 0, DFmode); 866: operands[5] = operand_subword (operands[1], 1, 0, DFmode); 867: 868: if (operands[2] == 0 || operands[3] == 0 869: || operands[4] == 0 || operands[5] == 0) 870: FAIL; 871: 872: if (reload_completed) 873: operands[6] = operands[7] = gen_rtx (REG, SImode, 15); 874: else 875: { 876: operands[6] = gen_rtx (SCRATCH, SImode); 877: operands[7] = gen_rtx (SCRATCH, SImode); 878: } 879: }") 880: 881: (define_split 882: [(set (match_operand:DF 0 "nonmemory_operand" "") 883: (match_operand:DF 1 "general_operand" "")) 884: (clobber (reg:SI 0)) 885: (clobber (reg:SI 15))] 886: "! symbolic_memory_operand (operands[1], DFmode) 887: && GET_CODE (operands[1]) != CONST_DOUBLE 888: && (GET_CODE (operands[0]) != REG || REGNO (operands[0]) < 15) 889: && (GET_CODE (operands[1]) != REG || REGNO (operands[1]) < 15) 890: && (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG) 891: && ! (GET_CODE (operands[0]) == REG && GET_CODE (operands[1]) == REG 892: && ! reload_completed 893: && reg_overlap_mentioned_p (operands[0], operands[1]))" 894: [(set (match_dup 2) (match_dup 3)) 895: (set (match_dup 4) (match_dup 5))] 896: " 897: { if (GET_CODE (operands[0]) != REG 898: || ! refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1, 899: operands[1], 0)) 900: { 901: operands[2] = operand_subword (operands[0], 0, 0, DFmode); 902: operands[3] = operand_subword (operands[1], 0, 0, DFmode); 903: operands[4] = operand_subword (operands[0], 1, 0, DFmode); 904: operands[5] = operand_subword (operands[1], 1, 0, DFmode); 905: } 906: else 907: { 908: operands[2] = operand_subword (operands[0], 1, 0, DFmode); 909: operands[3] = operand_subword (operands[1], 1, 0, DFmode); 910: operands[4] = operand_subword (operands[0], 0, 0, DFmode); 911: operands[5] = operand_subword (operands[1], 0, 0, DFmode); 912: } 913: 914: if (operands[2] == 0 || operands[3] == 0 915: || operands[4] == 0 || operands[5] == 0) 916: FAIL; 917: }") 918: 919: ;; Conversions from one integer mode to another. 920: ;; It is possible sometimes to sign- or zero-extend while fetching from memory. 921: ;; 922: ;; First, sign-extensions: 923: (define_expand "extendhisi2" 924: [(set (match_operand:SI 0 "register_operand" "") 925: (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] 926: "" 927: "") 928: 929: (define_insn "" 930: [(set (match_operand:SI 0 "register_operand" "=b") 931: (sign_extend:SI (match_operand:HI 1 "symbolic_memory_operand" "m")))] 932: "" 933: "loadha %0,%1" 934: [(set_attr "type" "load")]) 935: 936: (define_insn "" 937: [(set (match_operand:SI 0 "register_operand" "=r,r,b") 938: (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Q,m")))] 939: "" 940: "@ 941: exts %0,%1 942: lha%M1 %0,%1 943: loadha %0,%1" 944: [(set_attr "type" "arith,load,load") 945: (set_attr "length" "2,*,*")]) 946: 947: (define_expand "extendqisi2" 948: [(set (match_dup 2) 949: (ashift:SI (match_operand:QI 1 "register_operand" "") 950: (const_int 24))) 951: (set (match_operand:SI 0 "register_operand" "") 952: (ashiftrt:SI (match_dup 2) 953: (const_int 24)))] 954: "" 955: " 956: { operands[1] = gen_lowpart (SImode, operands[1]); 957: operands[2] = gen_reg_rtx (SImode); }") 958: 959: (define_expand "extendqihi2" 960: [(set (match_dup 2) 961: (ashift:SI (match_operand:QI 1 "register_operand" "") 962: (const_int 24))) 963: (set (match_operand:HI 0 "register_operand" "") 964: (ashiftrt:SI (match_dup 2) 965: (const_int 24)))] 966: "" 967: " 968: { operands[0] = gen_lowpart (SImode, operands[0]); 969: operands[1] = gen_lowpart (SImode, operands[1]); 970: operands[2] = gen_reg_rtx (SImode); }") 971: 972: ;; Define peepholes to eliminate an instruction when we are doing a sign 973: ;; extension but cannot clobber the input. 974: ;; 975: ;; In this case we will shift left 24 bits, but need a copy first. The shift 976: ;; can be replaced by a "mc03" instruction, but this can only be done if 977: ;; followed by the right shift of 24 or more bits. 978: (define_peephole 979: [(set (match_operand:SI 0 "register_operand" "") 980: (subreg:SI (match_operand:QI 1 "register_operand" "") 0)) 981: (set (match_dup 0) 982: (ashift:SI (match_dup 0) 983: (const_int 24))) 984: (set (match_dup 0) 985: (ashiftrt:SI (match_dup 0) 986: (match_operand:SI 2 "const_int_operand" "")))] 987: "INTVAL (operands[2]) >= 24" 988: "mc03 %0,%1\;sari16 %0,%S2" 989: [(set_attr "type" "multi") 990: (set_attr "length" "4") 991: (set_attr "cc" "sets")]) 992: 993: ;; Now zero extensions: 994: (define_expand "zero_extendhisi2" 995: [(set (match_operand:SI 0 "register_operand" "") 996: (zero_extend:SI (match_operand:HI 1 "register_operand" "")))] 997: "" 998: "") 999: 1000: (define_insn "" 1001: [(set (match_operand:SI 0 "register_operand" "=b") 1002: (zero_extend:SI (match_operand:HI 1 "symbolic_memory_operand" "m")))] 1003: "" 1004: "loadh %0,%1" 1005: [(set_attr "type" "load")]) 1006: 1007: (define_insn "" 1008: [(set (match_operand:SI 0 "register_operand" "=r,r,b") 1009: (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Q,m")))] 1010: "" 1011: "@ 1012: nilz %0,%1,65535 1013: lh%N1 %0,%1 1014: loadh %0,%1" 1015: [(set_attr "type" "arith,loadz,load")]) 1016: 1017: (define_expand "zero_extendqisi2" 1018: [(set (match_operand:SI 0 "register_operand" "") 1019: (zero_extend:SI (match_operand:QI 1 "register_operand" "")))] 1020: "" 1021: "") 1022: 1023: (define_insn "" 1024: [(set (match_operand:SI 0 "register_operand" "=b") 1025: (zero_extend:SI (match_operand:QI 1 "symbolic_memory_operand" "m")))] 1026: "" 1027: "loadc %0,%1" 1028: [(set_attr "type" "load")]) 1029: 1030: (define_insn "" 1031: [(set (match_operand:SI 0 "register_operand" "=r,r,b") 1032: (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Q,m")))] 1033: "" 1034: "@ 1035: nilz %0,%1,255 1036: lc%M1 %0,%1 1037: loadc %0,%1" 1038: [(set_attr "type" "arith,load,load")]) 1039: 1040: (define_expand "zero_extendqihi2" 1041: [(set (match_operand:HI 0 "register_operand" "") 1042: (zero_extend:HI (match_operand:QI 1 "register_operand" "")))] 1043: "" 1044: "") 1045: 1046: (define_insn "" 1047: [(set (match_operand:HI 0 "register_operand" "=b") 1048: (zero_extend:HI (match_operand:QI 1 "symbolic_memory_operand" "m")))] 1049: "" 1050: "loadc %0,%1" 1051: [(set_attr "type" "load")]) 1052: 1053: (define_insn "" 1054: [(set (match_operand:HI 0 "register_operand" "=r,r,b") 1055: (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,Q,m")))] 1056: "" 1057: "@ 1058: nilz %0,%1,255 1059: lc%M1 %0,%1 1060: loadc %0,%1" 1061: [(set_attr "type" "arith,load,load")]) 1062: 1063: ;; Various extract and insertion operations. 1064: (define_expand "extzv" 1065: [(set (match_operand:SI 0 "register_operand" "") 1066: (zero_extract:SI (match_operand:SI 1 "register_operand" "") 1067: (match_operand:SI 2 "const_int_operand" "") 1068: (match_operand:SI 3 "const_int_operand" "")))] 1069: "" 1070: " 1071: { 1072: if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 8) 1073: FAIL; 1074: 1075: if (GET_CODE (operands[3]) != CONST_INT) 1076: FAIL; 1077: 1078: if (INTVAL (operands[3]) != 0 && INTVAL (operands[3]) != 8 1079: && INTVAL (operands[3]) != 16 && INTVAL (operands[3]) != 24) 1080: FAIL; 1081: }") 1082: 1083: (define_insn "" 1084: [(set (match_operand:SI 0 "register_operand" "=&r") 1085: (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 1086: (const_int 8) 1087: (match_operand:SI 2 "const_int_operand" "n")))] 1088: "(INTVAL (operands[2]) & 7) == 0" 1089: "lis %0,0\;mc3%B2 %0,%1" 1090: [(set_attr "type" "multi") 1091: (set_attr "cc" "change0")]) 1092: 1093: (define_split 1094: [(set (match_operand:SI 0 "register_operand" "=&r") 1095: (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 1096: (const_int 8) 1097: (match_operand:SI 2 "const_int_operand" "n")))] 1098: "(INTVAL (operands[2]) & 7) == 0" 1099: [(set (match_dup 0) (const_int 0)) 1100: (set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 24)) 1101: (zero_extract:SI (match_dup 1) (const_int 8) (match_dup 2)))] 1102: "") 1103: 1104: (define_insn "" 1105: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") 1106: (const_int 8) 1107: (const_int 24)) 1108: (zero_extract:SI (match_operand:SI 1 "register_operand" "r") 1109: (const_int 8) 1110: (match_operand:SI 2 "const_int_operand" "n")))] 1111: "(INTVAL (operands[2]) & 7) == 0" 1112: "mc3%B2 %0,%1" 1113: [(set_attr "type" "address") 1114: (set_attr "length" "2")]) 1115: 1116: (define_expand "insv" 1117: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "") 1118: (match_operand:SI 1 "const_int_operand" "") 1119: (match_operand:SI 2 "const_int_operand" "")) 1120: (match_operand:SI 3 "register_operand" ""))] 1121: "" 1122: " 1123: { 1124: if (GET_CODE (operands[2]) != CONST_INT) 1125: FAIL; 1126: 1127: if (GET_CODE (operands[1]) != CONST_INT) 1128: FAIL; 1129: 1130: if (INTVAL (operands[1]) == 1) 1131: { 1132: emit_insn (gen_bit_insv (operands[0], operands[1], operands[2], 1133: operands[3])); 1134: DONE; 1135: } 1136: else if (INTVAL (operands[1]) == 8 1137: && (INTVAL (operands[2]) % 8 == 0)) 1138: ; /* Accept aligned byte-wide field. */ 1139: else 1140: FAIL; 1141: }") 1142: 1143: ;; For a single-bit insert, it is better to explicitly generate references 1144: ;; to the T bit. We will call the T bit "CC0" because it can be clobbered 1145: ;; by some CC0 sets (single-bit tests). 1146: 1147: (define_expand "bit_insv" 1148: [(set (cc0) 1149: (zero_extract:SI (match_operand:SI 3 "register_operand" "") 1150: (const_int 1) 1151: (const_int 31))) 1152: (parallel [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "") 1153: (match_operand:SI 1 "const_int_operand" "") 1154: (match_operand:SI 2 "const_int_operand" "")) 1155: (ne (cc0) (const_int 0))) 1156: (clobber (match_scratch:SI 4 ""))])] 1157: "" 1158: "") 1159: 1160: (define_insn "" 1161: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r") 1162: (const_int 8) 1163: (match_operand:SI 1 "const_int_operand" "n")) 1164: (match_operand:SI 2 "register_operand" "r"))] 1165: "(INTVAL (operands[1]) & 7) == 0" 1166: "mc%B1%.3 %0,%2" 1167: [(set_attr "type" "address") 1168: (set_attr "length" "2")]) 1169: 1170: ;; This pattern cannot have any input reloads since if references CC0. 1171: ;; So we have to add code to support memory, which is the only other 1172: ;; thing that a "register_operand" can become. There is still a problem 1173: ;; if the address isn't valid and *it* needs a reload, but there is no 1174: ;; way to solve that problem, so let's hope it never happens. 1175: 1176: (define_insn "" 1177: [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,m") 1178: (const_int 1) 1179: (match_operand:SI 1 "const_int_operand" "n,m")) 1180: (ne (cc0) (const_int 0))) 1181: (clobber (match_scratch:SI 2 "=X,b"))] 1182: "" 1183: "@ 1184: mftbi%t1 %0,%S1 1185: l%M0 %2,%0\;mftb%t1 %2,%S1\;st%M0 %2,%0" 1186: [(set_attr "type" "*,multi") 1187: (set_attr "cc" "none,none") 1188: (set_attr "length" "2,10")]) 1189: 1190: ;; Arithmetic instructions. First, add and subtract. 1191: ;; 1192: ;; It may be that the second input is either large or small enough that 1193: ;; the operation cannot be done in a single insn. In that case, emit two. 1194: (define_expand "addsi3" 1195: [(set (match_operand:SI 0 "register_operand" "") 1196: (plus:SI (match_operand:SI 1 "register_operand" "") 1197: (match_operand:SI 2 "nonmemory_operand" "")))] 1198: "" 1199: " 1200: { 1201: if (GET_CODE (operands[2]) == CONST_INT 1202: && (unsigned) (INTVAL (operands[2]) + 0x8000) >= 0x10000 1203: && (INTVAL (operands[2]) & 0xffff) != 0) 1204: { 1205: int low = INTVAL (operands[2]) & 0xffff; 1206: int high = (unsigned) INTVAL (operands[2]) >> 16; 1207: 1208: if (low & 0x8000) 1209: high++, low |= 0xffff0000; 1210: 1211: emit_insn (gen_addsi3 (operands[0], operands[1], 1212: gen_rtx (CONST_INT, VOIDmode, high << 16))); 1213: operands[1] = operands[0]; 1214: operands[2] = gen_rtx (CONST_INT, VOIDmode, low); 1215: } 1216: }") 1217: 1218: ;; Put the insn to add a symbolic constant to a register separately to 1219: ;; improve register allocation since it has different register requirements. 1220: (define_insn "" 1221: [(set (match_operand:SI 0 "register_operand" "=b") 1222: (plus:SI (match_operand:SI 1 "register_operand" "%b") 1223: (match_operand:SI 2 "romp_symbolic_operand" "s")))] 1224: "" 1225: "get %0,$%2(%1)" 1226: [(set_attr "type" "address") 1227: (set_attr "length" "8")]) 1228: 1229: (define_insn "" 1230: [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,b") 1231: (plus:SI (match_operand:SI 1 "reg_or_add_operand" "%0,0,r,b,0,r,b") 1232: (match_operand:SI 2 "reg_or_add_operand" "I,J,K,M,r,b,s")))] 1233: "register_operand (operands[1], SImode) 1234: || register_operand (operands[2], SImode)" 1235: "@ 1236: ais %0,%2 1237: sis %0,%n2 1238: ail %0,%1,%2 1239: cau %0,%H2(%1) 1240: a %0,%2 1241: cas %0,%1,%2 1242: get %0,$%2(%1)" 1243: [(set_attr "type" "arith,arith,arith,address,arith,address,misc") 1244: (set_attr "length" "2,2,4,4,2,2,8")]) 1245: 1246: ;; Now subtract. 1247: ;; 1248: ;; 1. If third operand is constant integer, convert it to add of the negative 1249: ;; of that integer. 1250: ;; 2. If the second operand is not a valid constant integer, force it into a 1251: ;; register. 1252: (define_expand "subsi3" 1253: [(set (match_operand:SI 0 "register_operand" "") 1254: (minus:SI (match_operand:SI 1 "reg_or_any_cint_operand" "") 1255: (match_operand:SI 2 "reg_or_any_cint_operand" "")))] 1256: "" 1257: " 1258: { 1259: if (GET_CODE (operands [2]) == CONST_INT) 1260: { 1261: emit_insn (gen_addsi3 (operands[0], operands[1], 1262: gen_rtx (CONST_INT, 1263: VOIDmode, - INTVAL (operands[2])))); 1264: DONE; 1265: } 1266: else 1267: operands[2] = force_reg (SImode, operands[2]); 1268: 1269: if (GET_CODE (operands[1]) != CONST_INT 1270: || (unsigned) (INTVAL (operands[1]) + 0x8000) >= 0x10000) 1271: operands[1] = force_reg (SImode, operands[1]); 1272: }") 1273: 1274: (define_insn "" 1275: [(set (match_operand:SI 0 "register_operand" "=r,r,r") 1276: (minus:SI (match_operand:SI 1 "reg_or_D_operand" "K,0,r") 1277: (match_operand:SI 2 "register_operand" "r,r,0")))] 1278: "" 1279: "@ 1280: sfi %0,%2,%1 1281: s %0,%2 1282: sf %0,%1" 1283: [(set_attr "length" "4,2,2")]) 1284: 1285: ;; Multiply either calls a special RT routine or is done in-line, depending 1286: ;; on the value of a -m flag. 1287: ;; 1288: ;; First define the way we call the subroutine. 1289: (define_expand "mulsi3_subr" 1290: [(set (reg:SI 2) (match_operand:SI 1 "register_operand" "")) 1291: (set (reg:SI 3) (match_operand:SI 2 "register_operand" "")) 1292: (parallel [(set (reg:SI 2) (mult:SI (reg:SI 2) (reg:SI 3))) 1293: (clobber (reg:SI 0)) 1294: (clobber (reg:SI 15))]) 1295: (set (match_operand:SI 0 "register_operand" "") 1296: (reg:SI 2))] 1297: "" 1298: "") 1299: 1300: (define_expand "mulsi3" 1301: [(set (match_operand:SI 0 "register_operand" "") 1302: (mult:SI (match_operand:SI 1 "register_operand" "") 1303: (match_operand:SI 2 "register_operand" "")))] 1304: "" 1305: " 1306: { 1307: if (! TARGET_IN_LINE_MUL) 1308: { 1309: emit_insn (gen_mulsi3_subr (operands[0], operands[1], operands[2])); 1310: DONE; 1311: } 1312: }") 1313: 1314: ;; Define the patterns to match. 1315: ;; We would like to provide a delay slot for the insns that call internal 1316: ;; routines, but doing so is risky since reorg will think that the use of 1317: ;; r2 and r3 is completed in the insn needing the delay slot. Also, it 1318: ;; won't know that the cc will be clobbered. So take the safe approach 1319: ;; and don't give them delay slots. 1320: (define_insn "" 1321: [(set (reg:SI 2) 1322: (mult:SI (reg:SI 2) (reg:SI 3))) 1323: (clobber (reg:SI 0)) 1324: (clobber (reg:SI 15))] 1325: "! TARGET_IN_LINE_MUL" 1326: "bali%# r15,lmul$$" 1327: [(set_attr "type" "misc") 1328: (set_attr "in_delay_slot" "no")]) 1329: 1330: (define_insn "" 1331: [(set (match_operand:SI 0 "register_operand" "=&r") 1332: (mult:SI (match_operand:SI 1 "register_operand" "%r") 1333: (match_operand:SI 2 "register_operand" "r")))] 1334: "TARGET_IN_LINE_MUL" 1335: "* 1336: { return output_in_line_mul (); }" 1337: [(set_attr "length" "38") 1338: (set_attr "type" "multi")]) 1339: 1340: ;; Handle divide and modulus. The same function returns both values, 1341: ;; so use divmodsi4. This divides arg 1 by arg 2 with quotient to go 1342: ;; into arg 0 and remainder in arg 3. 1343: ;; 1344: ;; We want to put REG_EQUAL notes for the two outputs. So we need a 1345: ;; function to do everything else. 1346: (define_expand "divmodsi4_doit" 1347: [(set (reg:SI 2) 1348: (match_operand:SI 0 "register_operand" "")) 1349: (set (reg:SI 3) 1350: (match_operand:SI 1 "register_operand" "")) 1351: (parallel [(set (reg:SI 2) (div:SI (reg:SI 2) (reg:SI 3))) 1352: (set (reg:SI 3) (mod:SI (reg:SI 2) (reg:SI 3))) 1353: (clobber (reg:SI 0)) 1354: (clobber (reg:SI 15))])] 1355: "" 1356: "") 1357: 1358: (define_expand "divmodsi4" 1359: [(parallel [(set (match_operand:SI 0 "register_operand" "") 1360: (div:SI (match_operand:SI 1 "register_operand" "") 1361: (match_operand:SI 2 "register_operand" ""))) 1362: (set (match_operand:SI 3 "register_operand" "") 1363: (mod:SI (match_dup 1) (match_dup 2)))])] 1364: "" 1365: " 1366: { 1367: rtx insn; 1368: 1369: emit_insn (gen_divmodsi4_doit (operands[1], operands[2])); 1370: insn = emit_move_insn (operands[0], gen_rtx (REG, SImode, 2)); 1371: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, 1372: gen_rtx (DIV, SImode, operands[1], 1373: operands[2]), 1374: REG_NOTES (insn)); 1375: insn = emit_move_insn (operands[3], gen_rtx (REG, SImode, 3)); 1376: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, 1377: gen_rtx (MOD, SImode, operands[1], 1378: operands[2]), 1379: REG_NOTES (insn)); 1380: DONE; 1381: }") 1382: 1383: (define_insn "" 1384: [(set (reg:SI 2) 1385: (div:SI (reg:SI 2) (reg:SI 3))) 1386: (set (reg:SI 3) 1387: (mod:SI (reg:SI 2) (reg:SI 3))) 1388: (clobber (reg:SI 0)) 1389: (clobber (reg:SI 15))] 1390: "" 1391: "bali%# r15,ldiv$$" 1392: [(set_attr "type" "misc") 1393: (set_attr "in_delay_slot" "no")]) 1394: 1395: ;; Similarly for unsigned divide. 1396: (define_expand "udivmodsi4_doit" 1397: [(set (reg:SI 2) 1398: (match_operand:SI 0 "register_operand" "")) 1399: (set (reg:SI 3) 1400: (match_operand:SI 1 "register_operand" "")) 1401: (parallel [(set (reg:SI 2) (udiv:SI (reg:SI 2) (reg:SI 3))) 1402: (set (reg:SI 3) (umod:SI (reg:SI 2) (reg:SI 3))) 1403: (clobber (reg:SI 0)) 1404: (clobber (reg:SI 15))])] 1405: "" 1406: "") 1407: 1408: (define_expand "udivmodsi4" 1409: [(parallel [(set (match_operand:SI 0 "register_operand" "") 1410: (udiv:SI (match_operand:SI 1 "register_operand" "") 1411: (match_operand:SI 2 "register_operand" ""))) 1412: (set (match_operand:SI 3 "register_operand" "") 1413: (umod:SI (match_dup 1) (match_dup 2)))])] 1414: "" 1415: " 1416: { 1417: rtx insn; 1418: 1419: emit_insn (gen_udivmodsi4_doit (operands[1], operands[2])); 1420: insn = emit_move_insn (operands[0], gen_rtx (REG, SImode, 2)); 1421: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, 1422: gen_rtx (UDIV, SImode, operands[1], 1423: operands[2]), 1424: REG_NOTES (insn)); 1425: insn = emit_move_insn (operands[3], gen_rtx (REG, SImode, 3)); 1426: REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, 1427: gen_rtx (UMOD, SImode, operands[1], 1428: operands[2]), 1429: REG_NOTES (insn)); 1430: DONE; 1431: }") 1432: 1433: (define_insn "" 1434: [(set (reg:SI 2) 1435: (udiv:SI (reg:SI 2) (reg:SI 3))) 1436: (set (reg:SI 3) 1437: (umod:SI (reg:SI 2) (reg:SI 3))) 1438: (clobber (reg:SI 0)) 1439: (clobber (reg:SI 15))] 1440: "" 1441: "bali%# r15,uldiv$$" 1442: [(set_attr "type" "misc") 1443: (set_attr "in_delay_slot" "no")]) 1444: 1445: ;; Define DImode arithmetic operations. 1446: ;; 1447: ;; It is possible to do certain adds and subtracts with constants in a single 1448: ;; insn, but it doesn't seem worth the trouble. 1449: ;; 1450: ;; Don't use DEFINE_SPLIT on these because the dependency on CC can't be 1451: ;; easily tracked in that case! 1452: (define_insn "adddi3" 1453: [(set (match_operand:DI 0 "register_operand" "=r") 1454: (plus:DI (match_operand:DI 1 "register_operand" "%0") 1455: (match_operand:DI 2 "register_operand" "r")))] 1456: "" 1457: "a %O0,%O2\;ae %0,%2" 1458: [(set_attr "type" "multi")]) 1459: 1460: (define_insn "subdi3" 1461: [(set (match_operand:DI 0 "register_operand" "=r") 1462: (minus:DI (match_operand:DI 1 "register_operand" "0") 1463: (match_operand:DI 2 "register_operand" "r")))] 1464: "" 1465: "s %O0,%O2\;se %0,%2" 1466: [(set_attr "type" "multi")]) 1467: 1468: (define_insn "negdi2" 1469: [(set (match_operand:DI 0 "register_operand" "=r,&r") 1470: (neg:DI (match_operand:DI 1 "register_operand" "0,r")))] 1471: "" 1472: "twoc %O0,%O1\;onec %0,%1\;aei %0,%0,0" 1473: [(set_attr "type" "multi") 1474: (set_attr "length" "8")]) 1475: 1476: ;; Unary arithmetic operations. 1477: (define_insn "abssi2" 1478: [(set (match_operand:SI 0 "register_operand" "=r") 1479: (abs:SI (match_operand:SI 1 "register_operand" "r")))] 1480: "" 1481: "abs %0,%1" 1482: [(set_attr "length" "2")]) 1483: 1484: (define_insn "negsi2" 1485: [(set (match_operand:SI 0 "register_operand" "=r") 1486: (neg:SI (match_operand:SI 1 "register_operand" "r")))] 1487: "" 1488: "twoc %0,%1" 1489: [(set_attr "length" "2")]) 1490: 1491: (define_insn "one_cmplsi2" 1492: [(set (match_operand:SI 0 "register_operand" "=r") 1493: (not:SI (match_operand:SI 1 "register_operand" "r")))] 1494: "" 1495: "onec %0,%1" 1496: [(set_attr "length" "2")]) 1497: 1498: 1499: ;; Logical insns: AND, IOR, and XOR 1500: ;; 1501: ;; If the operation is being performed on a 32-bit constant such that 1502: ;; it cannot be done in one insn, do it in two. We may lose a bit on 1503: ;; CSE in pathological cases, but it seems better doing it this way. 1504: (define_expand "andsi3" 1505: [(set (match_operand:SI 0 "register_operand" "") 1506: (and:SI (match_operand:SI 1 "register_operand" "") 1507: (match_operand:SI 2 "reg_or_any_cint_operand" "")))] 1508: "" 1509: " 1510: { 1511: if (GET_CODE (operands[2]) == CONST_INT) 1512: { 1513: int top = (unsigned) INTVAL (operands[2]) >> 16; 1514: int bottom = INTVAL (operands[2]) & 0xffff; 1515: 1516: if (top != 0 && top != 0xffff && bottom != 0 && bottom != 0xffff) 1517: { 1518: emit_insn (gen_andsi3 (operands[0], operands[1], 1519: gen_rtx (CONST_INT, VOIDmode, 1520: (top << 16) | 0xffff))); 1521: operands[1] = operands[0]; 1522: operands[2] = gen_rtx (CONST_INT, VOIDmode, 0xffff0000 | bottom); 1523: } 1524: } 1525: }"); 1526: 1527: (define_insn "" 1528: [(set (match_operand:SI 0 "register_operand" "=r,r,r") 1529: (and:SI (match_operand:SI 1 "reg_or_and_operand" "%0,r,0") 1530: (match_operand:SI 2 "reg_or_and_operand" "P,LMO,r")))] 1531: "register_operand (operands[1], SImode) 1532: || register_operand (operands[2], SImode)" 1533: "@ 1534: clrb%k2 %0,%b2 1535: ni%z2 %0,%1,%Z2 1536: n %0,%2" 1537: [(set_attr "length" "2,4,2")]) 1538: 1539: ;; logical OR (IOR) 1540: (define_expand "iorsi3" 1541: [(set (match_operand:SI 0 "register_operand" "") 1542: (ior:SI (match_operand:SI 1 "register_operand" "") 1543: (match_operand:SI 2 "reg_or_any_cint_operand" "")))] 1544: "" 1545: " 1546: { 1547: if (GET_CODE (operands[2]) == CONST_INT) 1548: { 1549: int top = (unsigned) INTVAL (operands[2]) >> 16; 1550: int bottom = INTVAL (operands[2]) & 0xffff; 1551: 1552: if (top != 0 && bottom != 0) 1553: { 1554: emit_insn (gen_iorsi3 (operands[0], operands[1], 1555: gen_rtx (CONST_INT, VOIDmode, (top << 16)))); 1556: operands[1] = operands[0]; 1557: operands[2] = gen_rtx (CONST_INT, VOIDmode, bottom); 1558: } 1559: } 1560: }"); 1561: 1562: (define_insn "" 1563: [(set (match_operand:SI 0 "register_operand" "=r,r,r") 1564: (ior:SI (match_operand:SI 1 "reg_or_cint_operand" "%0,r,0") 1565: (match_operand:SI 2 "reg_or_cint_operand" "N,LM,r")))] 1566: "register_operand (operands[1], SImode) 1567: || register_operand (operands[2], SImode)" 1568: "@ 1569: setb%h2 %0,%b2 1570: oi%h2 %0,%1,%H2 1571: o %0,%2" 1572: [(set_attr "length" "2,4,2")]) 1573: 1574: ;; exclusive-or (XOR) 1575: (define_expand "xorsi3" 1576: [(set (match_operand:SI 0 "register_operand" "") 1577: (xor:SI (match_operand:SI 1 "register_operand" "") 1578: (match_operand:SI 2 "reg_or_any_cint_operand" "")))] 1579: "" 1580: " 1581: { 1582: if (GET_CODE (operands[2]) == CONST_INT) 1583: { 1584: int top = (unsigned) INTVAL (operands[2]) >> 16; 1585: int bottom = INTVAL (operands[2]) & 0xffff; 1586: 1587: if (top == 0xffff && bottom == 0xffff) 1588: { 1589: emit_insn (gen_one_cmplsi2 (operands[0], operands[1])); 1590: DONE; 1591: } 1592: else if (top != 0 && bottom != 0) 1593: { 1594: emit_insn (gen_xorsi3 (operands[0], operands[1], 1595: gen_rtx (CONST_INT, VOIDmode, (top << 16)))); 1596: operands[1] = operands[0]; 1597: operands[2] = gen_rtx (CONST_INT, VOIDmode, bottom); 1598: } 1599: } 1600: }"); 1601: 1602: (define_insn "" 1603: [(set (match_operand:SI 0 "register_operand" "=r,r") 1604: (xor:SI (match_operand:SI 1 "reg_or_cint_operand" "%r,0") 1605: (match_operand:SI 2 "reg_or_cint_operand" "LM,r")))] 1606: "register_operand (operands[1], SImode) 1607: || register_operand (operands[2], SImode)" 1608: "@ 1609: xi%h2 %0,%1,%H2 1610: x %0,%2" 1611: [(set_attr "length" "4,2")]) 1612: 1613: ;; Various shift insns 1614: (define_insn "ashrsi3" 1615: [(set (match_operand:SI 0 "register_operand" "=r,r") 1616: (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0") 1617: (match_operand:SI 2 "reg_or_cint_operand" "r,n")))] 1618: "" 1619: "@ 1620: sar %0,%2 1621: sari%s2 %0,%S2" 1622: [(set_attr "length" "2")]) 1623: 1624: (define_insn "lshrsi3" 1625: [(set (match_operand:SI 0 "register_operand" "=r,r") 1626: (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0") 1627: (match_operand:SI 2 "reg_or_cint_operand" "r,n")))] 1628: "" 1629: "@ 1630: sr %0,%2 1631: sri%s2 %0,%S2" 1632: [(set_attr "length" "2")]) 1633: 1634: (define_insn "" 1635: [(set (match_operand:SI 0 "register_operand" "=r") 1636: (ashift:SI (match_operand:SI 1 "register_operand" "b") 1637: (const_int 1)))] 1638: "" 1639: "cas %0,%1,%1" 1640: [(set_attr "length" "2") 1641: (set_attr "type" "address")]) 1642: 1643: (define_insn "ashlsi3" 1644: [(set (match_operand:SI 0 "register_operand" "=r,r") 1645: (ashift:SI (match_operand:SI 1 "register_operand" "0,0") 1646: (match_operand:SI 2 "reg_or_cint_operand" "r,n")))] 1647: "" 1648: "@ 1649: sl %0,%2 1650: sli%s2 %0,%S2" 1651: [(set_attr "length" "2")]) 1652: 1653: ;; Function call insns: 1654: ;; 1655: ;; On the ROMP, &fcn is actually a pointer to the data area, which is passed 1656: ;; to the function in r0. &.fcn is the actual starting address of the 1657: ;; function. Also, the word at &fcn contains &.fcn. 1658: ;; 1659: ;; For both functions that do and don't return values, there are two cases: 1660: ;; where the function's address is a constant, and where it isn't. 1661: ;; 1662: ;; Operand 1 (2 for `call_value') is the number of arguments and is not used. 1663: (define_expand "call" 1.1.1.4 ! root 1664: [(use (match_operand:SI 0 "address_operand" "")) ! 1665: (use (match_operand 1 "" ""))] 1.1 root 1666: "" 1667: " 1668: { 1.1.1.4 ! root 1669: rtx reg0 = gen_rtx (REG, SImode, 0); ! 1670: rtx call_insn; ! 1671: 1.1 root 1672: if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT) 1673: abort(); 1674: 1675: operands[0] = XEXP (operands[0], 0); 1676: if (GET_CODE (operands[0]) == SYMBOL_REF) 1677: { 1678: extern rtx get_symref (); 1679: char *real_fcnname = 1680: (char *) alloca (strlen (XSTR (operands[0], 0)) + 2); 1681: 1682: /* Copy the data area address to r0. */ 1.1.1.4 ! root 1683: emit_move_insn (reg0, force_reg (SImode, operands[0])); 1.1 root 1684: strcpy (real_fcnname, \".\"); 1685: strcat (real_fcnname, XSTR (operands[0], 0)); 1686: operands[0] = get_symref (real_fcnname); 1687: } 1688: else 1689: { 1690: rtx data_access; 1691: 1.1.1.4 ! root 1692: emit_move_insn (reg0, force_reg (SImode, operands[0])); 1.1 root 1693: data_access = gen_rtx (MEM, SImode, operands[0]); 1694: RTX_UNCHANGING_P (data_access) = 1; 1695: operands[0] = copy_to_reg (data_access); 1696: } 1.1.1.4 ! root 1697: ! 1698: call_insn = emit_call_insn (gen_call_internal (operands[0], operands[1])); ! 1699: use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), reg0); ! 1700: DONE; 1.1 root 1701: }") 1702: 1.1.1.4 ! root 1703: (define_insn "call_internal" 1.1 root 1704: [(call (mem:SI (match_operand:SI 0 "register_operand" "b")) 1705: (match_operand 1 "" "g")) 1706: (clobber (reg:SI 15))] 1707: "" 1708: "balr%# r15,%0" 1709: [(set_attr "type" "call") 1710: (set_attr "length" "2")]) 1711: 1712: (define_insn "" 1713: [(call (mem:SI (match_operand:SI 0 "romp_symbolic_operand" "i")) 1714: (match_operand 1 "" "g")) 1715: (clobber (reg:SI 15))] 1716: "GET_CODE (operands[0]) == SYMBOL_REF" 1717: "bali%# r15,%0" 1718: [(set_attr "type" "call")]) 1719: 1720: ;; Call a function and return a value. 1721: (define_expand "call_value" 1.1.1.4 ! root 1722: [(use (match_operand 0 "" "")) ! 1723: (use (match_operand:SI 1 "address_operand" "")) ! 1724: (use (match_operand 2 "" ""))] 1.1 root 1725: "" 1726: " 1727: { 1.1.1.4 ! root 1728: rtx reg0 = gen_rtx (REG, SImode, 0); ! 1729: rtx call_insn; ! 1730: 1.1 root 1731: if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT) 1732: abort(); 1733: 1734: operands[1] = XEXP (operands[1], 0); 1735: if (GET_CODE (operands[1]) == SYMBOL_REF) 1736: { 1737: extern rtx get_symref (); 1738: char *real_fcnname = 1739: (char *) alloca (strlen (XSTR (operands[1], 0)) + 2); 1740: 1741: /* Copy the data area address to r0. */ 1.1.1.4 ! root 1742: emit_move_insn (reg0,force_reg (SImode, operands[1])); 1.1 root 1743: strcpy (real_fcnname, \".\"); 1744: strcat (real_fcnname, XSTR (operands[1], 0)); 1745: operands[1] = get_symref (real_fcnname); 1746: } 1747: else 1748: { 1749: rtx data_access; 1750: 1.1.1.4 ! root 1751: emit_move_insn (reg0,force_reg (SImode, operands[1])); 1.1 root 1752: data_access = gen_rtx (MEM, SImode, operands[1]); 1753: RTX_UNCHANGING_P (data_access) = 1; 1754: operands[1] = copy_to_reg (data_access); 1755: } 1.1.1.4 ! root 1756: ! 1757: call_insn = emit_call_insn (gen_call_value_internal (operands[0], ! 1758: operands[1], ! 1759: operands[2])); ! 1760: use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), reg0); ! 1761: DONE; 1.1 root 1762: }") 1763: 1.1.1.4 ! root 1764: (define_insn "call_value_internal" 1.1 root 1765: [(set (match_operand 0 "" "=fg") 1766: (call (mem:SI (match_operand:SI 1 "register_operand" "b")) 1767: (match_operand 2 "" "g"))) 1768: (clobber (reg:SI 15))] 1769: "" 1770: "balr%# r15,%1" 1771: [(set_attr "length" "2") 1772: (set_attr "type" "call")]) 1773: 1774: (define_insn "" 1775: [(set (match_operand 0 "" "=fg") 1776: (call (mem:SI (match_operand:SI 1 "romp_symbolic_operand" "i")) 1777: (match_operand 2 "" "g"))) 1778: (clobber (reg:SI 15))] 1779: "GET_CODE (operands[1]) == SYMBOL_REF" 1780: "bali%# r15,%1" 1781: [(set_attr "type" "call")]) 1782: 1783: ;; Call subroutine returning any type. 1784: 1785: (define_expand "untyped_call" 1786: [(parallel [(call (match_operand 0 "" "") 1787: (const_int 0)) 1788: (match_operand 1 "" "") 1789: (match_operand 2 "" "")])] 1790: "" 1791: " 1792: { 1793: int i; 1794: 1795: emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); 1796: 1797: for (i = 0; i < XVECLEN (operands[2], 0); i++) 1798: { 1799: rtx set = XVECEXP (operands[2], 0, i); 1800: emit_move_insn (SET_DEST (set), SET_SRC (set)); 1801: } 1802: 1803: /* The optimizer does not know that the call sets the function value 1804: registers we stored in the result block. We avoid problems by 1805: claiming that all hard registers are used and clobbered at this 1806: point. */ 1807: emit_insn (gen_blockage ()); 1808: 1809: DONE; 1810: }") 1811: 1812: ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 1813: ;; all of memory. This blocks insns from being moved across this point. 1814: 1815: (define_insn "blockage" 1816: [(unspec_volatile [(const_int 0)] 0)] 1817: "" 1818: "") 1819: 1820: ;; No operation insn. 1821: (define_insn "nop" 1822: [(const_int 0)] 1823: "" 1824: "nopr r0" 1825: [(set_attr "type" "address") 1826: (set_attr "length" "2") 1827: (set_attr "cc" "none")]) 1828: 1829: ;; Here are the floating-point operations. 1830: ;; 1831: ;; Start by providing DEFINE_EXPAND for each operation. 1832: ;; The insns will be handled with MATCH_OPERATOR; the methodology will be 1833: ;; discussed below. 1834: 1835: ;; First the conversion operations. 1836: 1837: (define_expand "truncdfsf2" 1838: [(parallel [(set (match_operand:SF 0 "general_operand" "") 1839: (float_truncate:SF (match_operand:DF 1 "general_operand" ""))) 1840: (clobber (reg:SI 0)) 1841: (clobber (reg:SI 15))])] 1842: "" 1843: "") 1844: 1845: (define_expand "extendsfdf2" 1846: [(parallel [(set (match_operand:DF 0 "general_operand" "") 1847: (float_extend:DF (match_operand:SF 1 "general_operand" ""))) 1848: (clobber (reg:SI 0)) 1849: (clobber (reg:SI 15))])] 1850: "" 1851: "") 1852: 1853: (define_expand "floatsisf2" 1854: [(parallel [(set (match_operand:SF 0 "general_operand" "") 1855: (float:SF (match_operand:SI 1 "general_operand" ""))) 1856: (clobber (reg:SI 0)) 1857: (clobber (reg:SI 15))])] 1858: "" 1859: "") 1860: 1861: (define_expand "floatsidf2" 1862: [(parallel [(set (match_operand:DF 0 "general_operand" "") 1863: (float:DF (match_operand:SI 1 "general_operand" ""))) 1864: (clobber (reg:SI 0)) 1865: (clobber (reg:SI 15))])] 1866: "" 1867: "") 1868: 1869: (define_expand "fix_truncsfsi2" 1870: [(parallel [(set (match_operand:SI 0 "general_operand" "") 1871: (fix:SI (match_operand:SF 1 "general_operand" ""))) 1872: (clobber (reg:SI 0)) 1873: (clobber (reg:SI 15))])] 1874: "" 1875: "") 1876: 1877: (define_expand "fix_truncdfsi2" 1878: [(parallel [(set (match_operand:SI 0 "general_operand" "") 1879: (fix:SI (match_operand:DF 1 "general_operand" ""))) 1880: (clobber (reg:SI 0)) 1881: (clobber (reg:SI 15))])] 1882: "" 1883: "") 1884: 1885: ;; Now the binary operations. 1886: 1887: (define_expand "addsf3" 1888: [(parallel [(set (match_operand:SF 0 "general_operand" "") 1889: (plus:SF (match_operand:SF 1 "general_operand" "") 1890: (match_operand:SF 2 "general_operand" ""))) 1891: (clobber (reg:SI 0)) 1892: (clobber (reg:SI 15))])] 1893: "" 1894: "") 1895: 1896: (define_expand "adddf3" 1897: [(parallel [(set (match_operand:DF 0 "general_operand" "") 1898: (plus:DF (match_operand:DF 1 "general_operand" "") 1899: (match_operand:DF 2 "general_operand" ""))) 1900: (clobber (reg:SI 0)) 1901: (clobber (reg:SI 15))])] 1902: "" 1903: "") 1904: 1905: (define_expand "subsf3" 1906: [(parallel [(set (match_operand:SF 0 "general_operand" "") 1907: (minus:SF (match_operand:SF 1 "general_operand" "") 1908: (match_operand:SF 2 "general_operand" ""))) 1909: (clobber (reg:SI 0)) 1910: (clobber (reg:SI 15))])] 1911: "" 1912: "") 1913: 1914: (define_expand "subdf3" 1915: [(parallel [(set (match_operand:DF 0 "general_operand" "") 1916: (minus:DF (match_operand:DF 1 "general_operand" "") 1917: (match_operand:DF 2 "general_operand" ""))) 1918: (clobber (reg:SI 0)) 1919: (clobber (reg:SI 15))])] 1920: "" 1921: "") 1922: 1923: (define_expand "mulsf3" 1924: [(parallel [(set (match_operand:SF 0 "general_operand" "") 1925: (mult:SF (match_operand:SF 1 "general_operand" "") 1926: (match_operand:SF 2 "general_operand" ""))) 1927: (clobber (reg:SI 0)) 1928: (clobber (reg:SI 15))])] 1929: "" 1930: "") 1931: 1932: (define_expand "muldf3" 1933: [(parallel [(set (match_operand:DF 0 "general_operand" "") 1934: (mult:DF (match_operand:DF 1 "general_operand" "") 1935: (match_operand:DF 2 "general_operand" ""))) 1936: (clobber (reg:SI 0)) 1937: (clobber (reg:SI 15))])] 1938: "" 1939: "") 1940: 1941: (define_expand "divsf3" 1942: [(parallel [(set (match_operand:SF 0 "general_operand" "") 1943: (div:SF (match_operand:SF 1 "general_operand" "") 1944: (match_operand:SF 2 "general_operand" ""))) 1945: (clobber (reg:SI 0)) 1946: (clobber (reg:SI 15))])] 1947: "" 1948: "") 1949: 1950: (define_expand "divdf3" 1951: [(parallel [(set (match_operand:DF 0 "general_operand" "") 1952: (div:DF (match_operand:DF 1 "general_operand" "") 1953: (match_operand:DF 2 "general_operand" ""))) 1954: (clobber (reg:SI 0)) 1955: (clobber (reg:SI 15))])] 1956: "" 1957: "") 1958: 1959: ;; Unary floating-point operations. 1960: ;; 1961: ;; Negations can be done without floating-point, since this is IEEE. 1962: ;; But we cannot do this if an operand is a hard FP register, since 1963: ;; the SUBREG we create would not be valid. 1964: (define_expand "negsf2" 1965: [(set (match_operand:SF 0 "register_operand" "") 1966: (neg:SF (match_operand:SF 1 "register_operand" "")))] 1967: "" 1968: " 1969: { 1970: if (! (GET_CODE (operands[0]) == REG 1971: && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER 1972: && FP_REGNO_P (REGNO (operands[0]))) 1973: && ! (GET_CODE (operands[1]) == REG 1974: && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER 1975: && FP_REGNO_P (REGNO (operands[1])))) 1976: { 1977: rtx result; 1978: rtx target = operand_subword (operands[0], 0, 1, SFmode); 1979: 1980: result = expand_binop (SImode, xor_optab, 1981: operand_subword_force (operands[1], 0, SFmode), 1982: gen_rtx (CONST_INT, VOIDmode, 0x80000000), 1983: target, 0, OPTAB_WIDEN); 1984: if (result == 0) 1985: abort (); 1986: 1987: if (result != target) 1988: emit_move_insn (result, target); 1989: 1990: /* Make a place for REG_EQUAL. */ 1991: emit_move_insn (operands[0], operands[0]); 1992: DONE; 1993: } 1994: }") 1995: 1996: (define_expand "negdf2" 1997: [(set (match_operand:DF 0 "register_operand" "") 1998: (neg:DF (match_operand:DF 1 "register_operand" "")))] 1999: "" 2000: " 2001: { 2002: if (! (GET_CODE (operands[0]) == REG 2003: && REGNO (operands[0]) < FIRST_PSEUDO_REGISTER 2004: && FP_REGNO_P (REGNO (operands[0]))) 2005: && ! (GET_CODE (operands[1]) == REG 2006: && REGNO (operands[1]) < FIRST_PSEUDO_REGISTER 2007: && FP_REGNO_P (REGNO (operands[1])))) 2008: { 2009: rtx result; 2010: rtx target = operand_subword (operands[0], 0, 1, DFmode); 2011: rtx insns; 2012: 2013: start_sequence (); 2014: result = expand_binop (SImode, xor_optab, 2015: operand_subword_force (operands[1], 0, DFmode), 2016: gen_rtx (CONST_INT, VOIDmode, 0x80000000), 2017: target, 0, OPTAB_WIDEN); 2018: if (result == 0) 2019: abort (); 2020: 2021: if (result != target) 2022: emit_move_insn (result, target); 2023: 2024: emit_move_insn (operand_subword (operands[0], 1, 1, DFmode), 2025: operand_subword_force (operands[1], 1, DFmode)); 2026: 2027: insns = get_insns (); 2028: end_sequence (); 2029: 2030: emit_no_conflict_block (insns, operands[0], operands[1], 0, 0); 2031: DONE; 2032: } 2033: }") 2034: 2035: (define_expand "abssf2" 2036: [(parallel [(set (match_operand:SF 0 "general_operand" "") 2037: (abs:SF (match_operand:SF 1 "general_operand" ""))) 2038: (clobber (reg:SI 0)) 2039: (clobber (reg:SI 15))])] 2040: "" 2041: "") 2042: 2043: (define_expand "absdf2" 2044: [(parallel [(set (match_operand:DF 0 "general_operand" "") 2045: (abs:DF (match_operand:DF 1 "general_operand" ""))) 2046: (clobber (reg:SI 0)) 2047: (clobber (reg:SI 15))])] 2048: "" 2049: "") 2050: 2051: ;; Any floating-point operation can be either SFmode or DFmode, and each 2052: ;; operand (including the output) can be either a normal operand or a 2053: ;; conversion from a normal operand. 2054: ;; 2055: ;; We use MATCH_OPERATOR to match a floating-point binary or unary operator 2056: ;; and input and output conversions. So we need 2^N patterns for each type 2057: ;; of operation, where N is the number of operands, including the output. 2058: ;; There are thus a total of 14 patterns, 8 for binary operations, 4 for 2059: ;; unary operations and two for conversion/move operations (only one 2060: ;; operand can have a conversion for move operations). In addition, we have 2061: ;; to be careful that a floating-point reload register doesn't get allocated 2062: ;; for an integer. We take care of this for inputs with PREFERRED_RELOAD_CLASS 2063: ;; but need to have two different constraints for outputs. This means that 2064: ;; we have to duplicate each pattern where the output could be an integer. 2065: ;; This adds another 7 patterns, for a total of 21. 2066: 2067: ;; Start with conversion operations (moves are done above). 2068: 2069: (define_insn "" 2070: [(set (match_operand:SI 0 "general_operand" "=g") 2071: (match_operator 1 "float_conversion" 2072: [(match_operand 2 "general_operand" "frg")])) 2073: (clobber (match_operand:SI 3 "reg_0_operand" "=&z")) 2074: (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))] 2075: "" 2076: "* 2077: { return output_fpop (SET, operands[0], operands[2], 0, insn); 2078: }" 2079: [(set_attr "type" "fp")]) 2080: 2081: (define_insn "" 2082: [(set (match_operand 0 "general_operand" "=frg") 2083: (match_operator 1 "float_conversion" 2084: [(match_operand 2 "general_operand" "frg")])) 2085: (clobber (match_operand:SI 3 "reg_0_operand" "=&z")) 2086: (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))] 2087: "" 2088: "* 2089: { return output_fpop (SET, operands[0], operands[2], 0, insn); 2090: }" 2091: [(set_attr "type" "fp")]) 2092: 2093: ;; Next, binary floating-point operations. 2094: 2095: (define_insn "" 2096: [(set (match_operand 0 "general_operand" "=frg") 2097: (match_operator 1 "float_binary" 2098: [(match_operand 2 "general_operand" "frg") 2099: (match_operand 3 "general_operand" "frg")])) 2100: (clobber (match_operand:SI 4 "reg_0_operand" "=&z")) 2101: (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))] 2102: "check_precision (GET_MODE (operands[1]), operands[2], operands[3])" 2103: "* 2104: { return output_fpop (GET_CODE (operands[1]), operands[0], 2105: operands[2], operands[3], insn); 2106: }" 2107: [(set_attr "type" "fp")]) 2108: 2109: (define_insn "" 2110: [(set (match_operand 0 "general_operand" "=frg") 2111: (match_operator 1 "float_binary" 2112: [(match_operand 2 "general_operand" "frg") 2113: (match_operator 3 "float_conversion" 2114: [(match_operand 4 "general_operand" "frg")])])) 2115: (clobber (match_operand:SI 5 "reg_0_operand" "=&z")) 2116: (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))] 2117: "check_precision (GET_MODE (operands[1]), operands[2], operands[4])" 2118: "* 2119: { return output_fpop (GET_CODE (operands[1]), operands[0], 2120: operands[2], operands[4], insn); 2121: }" 2122: [(set_attr "type" "fp")]) 2123: 2124: (define_insn "" 2125: [(set (match_operand 0 "general_operand" "=frg") 2126: (match_operator 1 "float_binary" 2127: [(match_operator 2 "float_conversion" 2128: [(match_operand 3 "general_operand" "frg")]) 2129: (match_operand 4 "general_operand" "frg")])) 2130: (clobber (match_operand:SI 5 "reg_0_operand" "=&z")) 2131: (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))] 2132: "check_precision (GET_MODE (operands[1]), operands[3], operands[4])" 2133: "* 2134: { return output_fpop (GET_CODE (operands[1]), operands[0], 2135: operands[3], operands[4], insn); 2136: }" 2137: [(set_attr "type" "fp")]) 2138: 2139: (define_insn "" 2140: [(set (match_operand 0 "general_operand" "=frg") 2141: (match_operator 1 "float_binary" 2142: [(match_operator 2 "float_conversion" 2143: [(match_operand 3 "general_operand" "frg")]) 2144: (match_operator 4 "float_conversion" 2145: [(match_operand 5 "general_operand" "frg")])])) 2146: (clobber (match_operand:SI 6 "reg_0_operand" "=&z")) 2147: (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))] 2148: "check_precision (GET_MODE (operands[1]), operands[3], operands[5])" 2149: "* 2150: { return output_fpop (GET_CODE (operands[1]), operands[0], 2151: operands[3], operands[5], insn); 2152: }" 2153: [(set_attr "type" "fp")]) 2154: 2155: (define_insn "" 2156: [(set (match_operand:SI 0 "general_operand" "=g") 2157: (match_operator 1 "float_conversion" 2158: [(match_operator 2 "float_binary" 2159: [(match_operand 3 "general_operand" "frg") 2160: (match_operand 4 "general_operand" "frg")])])) 2161: (clobber (match_operand:SI 5 "reg_0_operand" "=&z")) 2162: (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))] 2163: "check_precision (GET_MODE (operands[2]), operands[3], operands[4])" 2164: "* 2165: { return output_fpop (GET_CODE (operands[2]), operands[0], 2166: operands[3], operands[4], insn); 2167: }" 2168: [(set_attr "type" "fp")]) 2169: 2170: (define_insn "" 2171: [(set (match_operand 0 "general_operand" "=frg") 2172: (match_operator 1 "float_conversion" 2173: [(match_operator 2 "float_binary" 2174: [(match_operand 3 "general_operand" "frg") 2175: (match_operand 4 "general_operand" "frg")])])) 2176: (clobber (match_operand:SI 5 "reg_0_operand" "=&z")) 2177: (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))] 2178: "check_precision (GET_MODE (operands[2]), operands[3], operands[4])" 2179: "* 2180: { return output_fpop (GET_CODE (operands[2]), operands[0], 2181: operands[3], operands[4], insn); 2182: }" 2183: [(set_attr "type" "fp")]) 2184: 2185: (define_insn "" 2186: [(set (match_operand:SI 0 "general_operand" "=g") 2187: (match_operator 1 "float_conversion" 2188: [(match_operator 2 "float_binary" 2189: [(match_operand 3 "general_operand" "frg") 2190: (match_operator 4 "float_conversion" 2191: [(match_operand 5 "general_operand" "frg")])])])) 2192: (clobber (match_operand:SI 6 "reg_0_operand" "=&z")) 2193: (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))] 2194: "check_precision (GET_MODE (operands[2]), operands[3], operands[4])" 2195: "* 2196: { return output_fpop (GET_CODE (operands[2]), operands[0], 2197: operands[3], operands[5], insn); 2198: }" 2199: [(set_attr "type" "fp")]) 2200: 2201: (define_insn "" 2202: [(set (match_operand 0 "general_operand" "=frg") 2203: (match_operator 1 "float_conversion" 2204: [(match_operator 2 "float_binary" 2205: [(match_operand 3 "general_operand" "frg") 2206: (match_operator 4 "float_conversion" 2207: [(match_operand 5 "general_operand" "frg")])])])) 2208: (clobber (match_operand:SI 6 "reg_0_operand" "=&z")) 2209: (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))] 2210: "check_precision (GET_MODE (operands[2]), operands[3], operands[4])" 2211: "* 2212: { return output_fpop (GET_CODE (operands[2]), operands[0], 2213: operands[3], operands[5], insn); 2214: }" 2215: [(set_attr "type" "fp")]) 2216: 2217: (define_insn "" 2218: [(set (match_operand:SI 0 "general_operand" "=g") 2219: (match_operator 1 "float_conversion" 2220: [(match_operator 2 "float_binary" 2221: [(match_operator 3 "float_conversion" 2222: [(match_operand 4 "general_operand" "frg")]) 2223: (match_operand 5 "general_operand" "frg")])])) 2224: (clobber (match_operand:SI 6 "reg_0_operand" "=&z")) 2225: (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))] 2226: "check_precision (GET_MODE (operands[2]), operands[4], operands[5])" 2227: "* 2228: { return output_fpop (GET_CODE (operands[2]), operands[0], 2229: operands[4], operands[5], insn); 2230: }" 2231: [(set_attr "type" "fp")]) 2232: 2233: (define_insn "" 2234: [(set (match_operand 0 "general_operand" "=frg") 2235: (match_operator 1 "float_conversion" 2236: [(match_operator 2 "float_binary" 2237: [(match_operator 3 "float_conversion" 2238: [(match_operand 4 "general_operand" "frg")]) 2239: (match_operand 5 "general_operand" "frg")])])) 2240: (clobber (match_operand:SI 6 "reg_0_operand" "=&z")) 2241: (clobber (match_operand:SI 7 "reg_15_operand" "=&t"))] 2242: "check_precision (GET_MODE (operands[2]), operands[4], operands[5])" 2243: "* 2244: { return output_fpop (GET_CODE (operands[2]), operands[0], 2245: operands[4], operands[5], insn); 2246: }" 2247: [(set_attr "type" "fp")]) 2248: 2249: (define_insn "" 2250: [(set (match_operand:SI 0 "general_operand" "=g") 2251: (match_operator 1 "float_conversion" 2252: [(match_operator 2 "float_binary" 2253: [(match_operator 3 "float_conversion" 2254: [(match_operand 4 "general_operand" "frg")]) 2255: (match_operator 5 "float_conversion" 2256: [(match_operand 6 "general_operand" "frg")])])])) 2257: (clobber (match_operand:SI 7 "reg_0_operand" "=&z")) 2258: (clobber (match_operand:SI 8 "reg_15_operand" "=&t"))] 2259: "check_precision (GET_MODE (operands[2]), operands[4], operands[6])" 2260: "* 2261: { return output_fpop (GET_CODE (operands[2]), operands[0], 2262: operands[4], operands[6], insn); 2263: }" 2264: [(set_attr "type" "fp")]) 2265: 2266: (define_insn "" 2267: [(set (match_operand 0 "general_operand" "=frg") 2268: (match_operator 1 "float_conversion" 2269: [(match_operator 2 "float_binary" 2270: [(match_operator 3 "float_conversion" 2271: [(match_operand 4 "general_operand" "frg")]) 2272: (match_operator 5 "float_conversion" 2273: [(match_operand 6 "general_operand" "frg")])])])) 2274: (clobber (match_operand:SI 7 "reg_0_operand" "=&z")) 2275: (clobber (match_operand:SI 8 "reg_15_operand" "=&t"))] 2276: "check_precision (GET_MODE (operands[2]), operands[4], operands[6])" 2277: "* 2278: { return output_fpop (GET_CODE (operands[2]), operands[0], 2279: operands[4], operands[6], insn); 2280: }" 2281: [(set_attr "type" "fp")]) 2282: 2283: ;; Unary floating-point operations. 2284: 2285: (define_insn "" 2286: [(set (match_operand 0 "general_operand" "=frg") 2287: (match_operator 1 "float_unary" 2288: [(match_operand 2 "general_operand" "frg")])) 2289: (clobber (match_operand:SI 3 "reg_0_operand" "=&z")) 2290: (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))] 2291: "check_precision (GET_MODE (operands[1]), operands[2], 0)" 2292: "* 2293: { return output_fpop (GET_CODE (operands[1]), operands[0], operands[2], 2294: 0, insn); 2295: }" 2296: [(set_attr "type" "fp")]) 2297: 2298: (define_insn "" 2299: [(set (match_operand 0 "general_operand" "=frg") 2300: (match_operator 1 "float_unary" 2301: [(match_operator 2 "float_conversion" 2302: [(match_operand 3 "general_operand" "frg")])])) 2303: (clobber (match_operand:SI 4 "reg_0_operand" "=&z")) 2304: (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))] 2305: "check_precision (GET_MODE (operands[1]), operands[3], 0)" 2306: "* 2307: { return output_fpop (GET_CODE (operands[1]), operands[0], operands[3], 2308: 0, insn); 2309: }" 2310: [(set_attr "type" "fp")]) 2311: 2312: (define_insn "" 2313: [(set (match_operand:SI 0 "general_operand" "=g") 2314: (match_operator 1 "float_conversion" 2315: [(match_operator 2 "float_unary" 2316: [(match_operand 3 "general_operand" "frg")])])) 2317: (clobber (match_operand:SI 4 "reg_0_operand" "=&z")) 2318: (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))] 2319: "check_precision (GET_MODE (operands[2]), operands[3], 0)" 2320: "* 2321: { return output_fpop (GET_CODE (operands[2]), operands[0], operands[3], 2322: 0, insn); 2323: }" 2324: [(set_attr "type" "fp")]) 2325: 2326: (define_insn "" 2327: [(set (match_operand 0 "general_operand" "=frg") 2328: (match_operator 1 "float_conversion" 2329: [(match_operator 2 "float_unary" 2330: [(match_operand 3 "general_operand" "frg")])])) 2331: (clobber (match_operand:SI 4 "reg_0_operand" "=&z")) 2332: (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))] 2333: "check_precision (GET_MODE (operands[2]), operands[3], 0)" 2334: "* 2335: { return output_fpop (GET_CODE (operands[2]), operands[0], operands[3], 2336: 0, insn); 2337: }" 2338: [(set_attr "type" "fp")]) 2339: 2340: (define_insn "" 2341: [(set (match_operand:SI 0 "general_operand" "=g") 2342: (match_operator 1 "float_conversion" 2343: [(match_operator 2 "float_unary" 2344: [(match_operator 3 "float_conversion" 2345: [(match_operand 4 "general_operand" "frg")])])])) 2346: (clobber (match_operand:SI 5 "reg_0_operand" "=&z")) 2347: (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))] 2348: "check_precision (GET_MODE (operands[2]), operands[4], 0)" 2349: "* 2350: { return output_fpop (GET_CODE (operands[2]), operands[0], operands[4], 2351: 0, insn); 2352: }" 2353: [(set_attr "type" "fp")]) 2354: 2355: (define_insn "" 2356: [(set (match_operand 0 "general_operand" "=frg") 2357: (match_operator 1 "float_conversion" 2358: [(match_operator 2 "float_unary" 2359: [(match_operator 3 "float_conversion" 2360: [(match_operand 4 "general_operand" "frg")])])])) 2361: (clobber (match_operand:SI 5 "reg_0_operand" "=&z")) 2362: (clobber (match_operand:SI 6 "reg_15_operand" "=&t"))] 2363: "check_precision (GET_MODE (operands[2]), operands[4], 0)" 2364: "* 2365: { return output_fpop (GET_CODE (operands[2]), operands[0], operands[4], 2366: 0, insn); 2367: }" 2368: [(set_attr "type" "fp")]) 2369: 2370: ;; Compare insns are next. Note that the ROMP has two types of compares, 2371: ;; signed & unsigned, and one type of branch. Use the routine 2372: ;; `next_insn_tests_no_unsigned' to see which type to use. 2373: (define_expand "tstsi" 2374: [(set (cc0) 2375: (match_operand:SI 0 "register_operand" "r"))] 2376: "" 2377: "") 2378: 2379: (define_expand "cmpsi" 2380: [(set (cc0) 2381: (compare (match_operand:SI 0 "register_operand" "") 2382: (match_operand:SI 1 "reg_or_cint_operand" "")))] 2383: "" 2384: "") 2385: 2386: ;; Signed compare, `test' first. 2387: 2388: (define_insn "" 2389: [(set (cc0) 2390: (match_operand:SI 0 "register_operand" "r"))] 2391: "next_insn_tests_no_unsigned (insn)" 2392: "cis %0,0" 2393: [(set_attr "length" "2") 2394: (set_attr "type" "compare")]) 2395: 2396: (define_insn "" 2397: [(set (cc0) (match_operand:SI 0 "register_operand" "r,r,r")) 2398: (set (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "=0,r,Q") 2399: (match_dup 0))] 2400: "next_insn_tests_no_unsigned (insn)" 2401: "@ 2402: cis %1,0 2403: nilo %1,%0,65535 2404: st%M1 %0,%1\;cis %0,0" 2405: [(set_attr "type" "compare,compare,store") 2406: (set_attr "length" "2,4,6") 2407: (set_attr "cc" "compare")]) 2408: 2409: (define_insn "" 2410: [(set (cc0) 2411: (compare (match_operand:SI 0 "register_operand" "r,r,r") 2412: (match_operand:SI 1 "reg_or_cint_operand" "I,K,r")))] 2413: "next_insn_tests_no_unsigned (insn)" 2414: "@ 2415: cis %0,%1 2416: cil %0,%1 2417: c %0,%1" 2418: [(set_attr "length" "2,4,2") 2419: (set_attr "type" "compare")]) 2420: 2421: ;; Unsigned comparisons, `test' first, again. 2422: (define_insn "" 2423: [(set (cc0) 2424: (match_operand:SI 0 "register_operand" "r"))] 2425: "! next_insn_tests_no_unsigned (insn)" 2426: "clil %0,0" 2427: [(set_attr "type" "compare")]) 2428: 2429: (define_insn "" 2430: [(set (cc0) 2431: (compare (match_operand:SI 0 "register_operand" "r,r") 2432: (match_operand:SI 1 "reg_or_cint_operand" "K,r")))] 2433: "! next_insn_tests_no_unsigned (insn)" 2434: "@ 2435: clil %0,%1 2436: cl %0,%1" 2437: [(set_attr "length" "4,2") 2438: (set_attr "type" "compare")]) 2439: 2440: ;; Bit test insn. Many cases are converted into this by combine. This 2441: ;; uses the ROMP test bit. 2442: 2443: (define_insn "" 2444: [(set (cc0) 2445: (zero_extract (match_operand:SI 0 "register_operand" "r,r") 2446: (const_int 1) 2447: (match_operand:SI 1 "reg_or_any_cint_operand" "r,n")))] 2448: "next_insn_tests_no_inequality (insn)" 2449: "@ 2450: mttb %0,%1 2451: mttbi%t1 %0,%S1" 2452: [(set_attr "length" "2") 2453: (set_attr "type" "compare") 2454: (set_attr "cc" "tbit")]) 2455: 2456: ;; Floating-point comparisons. There are two, equality and order. 2457: ;; The difference will be that a trap for NaN will be given on the orderr 2458: ;; comparisons only. 2459: 2460: (define_expand "cmpsf" 2461: [(parallel [(set (cc0) (compare (match_operand:SF 0 "general_operand" "") 2462: (match_operand:SF 1 "general_operand" ""))) 2463: (clobber (reg:SI 0)) 2464: (clobber (reg:SI 15))])] 2465: "" 2466: "") 2467: 2468: (define_expand "cmpdf" 2469: [(parallel [(set (cc0) (compare (match_operand:DF 0 "general_operand" "") 2470: (match_operand:DF 1 "general_operand" ""))) 2471: (clobber (reg:SI 0)) 2472: (clobber (reg:SI 15))])] 2473: "" 2474: "") 2475: 2476: (define_expand "tstsf" 2477: [(parallel [(set (cc0) (match_operand:SF 0 "general_operand" "")) 2478: (clobber (reg:SI 0)) 2479: (clobber (reg:SI 15))])] 2480: "" 2481: "") 2482: 2483: (define_expand "tstdf" 2484: [(parallel [(set (cc0) (match_operand:DF 0 "general_operand" "")) 2485: (clobber (reg:SI 0)) 2486: (clobber (reg:SI 15))])] 2487: "" 2488: "") 2489: 2490: ;; There are four cases for compare and two for test. These correspond 2491: ;; to each input having a floating-point conversion or not. 2492: 2493: (define_insn "" 2494: [(set (cc0) (compare (match_operand 0 "general_operand" "frg") 2495: (match_operand 1 "general_operand" "frg"))) 2496: (clobber (match_operand:SI 2 "reg_0_operand" "=&z")) 2497: (clobber (match_operand:SI 3 "reg_15_operand" "=&t"))] 2498: "GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode" 2499: "* 2500: { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE, 2501: operands[0], operands[1], 0, insn); 2502: }" 2503: [(set_attr "type" "fp") 2504: (set_attr "cc" "compare")]) 2505: 2506: (define_insn "" 2507: [(set (cc0) (compare (match_operand 0 "general_operand" "frg") 2508: (match_operator 1 "float_conversion" 2509: [(match_operand 2 "general_operand" "frg")]))) 2510: (clobber (match_operand:SI 3 "reg_0_operand" "=&z")) 2511: (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))] 2512: "" 2513: "* 2514: { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE, 2515: operands[0], operands[2], 0, insn); 2516: }" 2517: [(set_attr "type" "fp") 2518: (set_attr "cc" "compare")]) 2519: 2520: (define_insn "" 2521: [(set (cc0) (compare (match_operator 0 "float_conversion" 2522: [(match_operand 1 "general_operand" "frg")]) 2523: (match_operand 2 "general_operand" "frg"))) 2524: (clobber (match_operand:SI 3 "reg_0_operand" "=&z")) 2525: (clobber (match_operand:SI 4 "reg_15_operand" "=&t"))] 2526: "" 2527: "* 2528: { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE, 2529: operands[1], operands[2], 0, insn); 2530: }" 2531: [(set_attr "type" "fp") 2532: (set_attr "cc" "compare")]) 2533: 2534: (define_insn "" 2535: [(set (cc0) (compare (match_operator 0 "float_conversion" 2536: [(match_operand 1 "general_operand" "frg")]) 2537: (match_operator 2 "float_conversion" 2538: [(match_operand 3 "general_operand" "frg")]))) 2539: (clobber (match_operand:SI 4 "reg_0_operand" "=&z")) 2540: (clobber (match_operand:SI 5 "reg_15_operand" "=&t"))] 2541: "" 2542: "* 2543: { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE, 2544: operands[1], operands[3], 0, insn); 2545: }" 2546: [(set_attr "type" "fp") 2547: (set_attr "cc" "compare")]) 2548: 2549: (define_insn "" 2550: [(set (cc0) (match_operand 0 "general_operand" "frg")) 2551: (clobber (match_operand:SI 1 "reg_0_operand" "=&z")) 2552: (clobber (match_operand:SI 2 "reg_15_operand" "=&t"))] 2553: "GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode" 2554: "* 2555: { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE, 1.1.1.3 root 2556: operands[0], CONST0_RTX (GET_MODE (operands[0])), 1.1 root 2557: 0, insn); 2558: }" 2559: [(set_attr "type" "fp") 2560: (set_attr "cc" "compare")]) 2561: 2562: (define_insn "" 2563: [(set (cc0) (match_operator 0 "float_conversion" 2564: [(match_operand 1 "general_operand" "frg")])) 2565: (clobber (match_operand:SI 2 "reg_0_operand" "=&z")) 2566: (clobber (match_operand:SI 3 "reg_15_operand" "=&t"))] 2567: "" 2568: "* 2569: { return output_fpop (next_insn_tests_no_inequality (insn) ? EQ : GE, 1.1.1.3 root 2570: operands[1], CONST0_RTX (GET_MODE (operands[1])), 1.1 root 2571: 0, insn); 2572: }" 2573: [(set_attr "type" "fp") 2574: (set_attr "cc" "compare")]) 2575: 2576: ;; Branch insns. Unsigned vs. signed have already 2577: ;; been taken care of. The only insns that need to be concerned about the 2578: ;; test bit are beq and bne because the rest are either always true, 2579: ;; always false, or converted to EQ or NE. 2580: 2581: ;; For conditional branches, we use `define_expand' and just have two patterns 2582: ;; that match them. Operand printing does most of the work. 2583: 2584: (define_expand "beq" 2585: [(set (pc) 2586: (if_then_else (eq (cc0) 2587: (const_int 0)) 2588: (label_ref (match_operand 0 "" "")) 2589: (pc)))] 2590: "" 2591: "") 2592: 2593: (define_expand "bne" 2594: [(set (pc) 2595: (if_then_else (ne (cc0) 2596: (const_int 0)) 2597: (label_ref (match_operand 0 "" "")) 2598: (pc)))] 2599: "" 2600: "") 2601: 2602: (define_expand "bgt" 2603: [(set (pc) 2604: (if_then_else (gt (cc0) 2605: (const_int 0)) 2606: (label_ref (match_operand 0 "" "")) 2607: (pc)))] 2608: "" 2609: "") 2610: 2611: (define_expand "bgtu" 2612: [(set (pc) 2613: (if_then_else (gtu (cc0) 2614: (const_int 0)) 2615: (label_ref (match_operand 0 "" "")) 2616: (pc)))] 2617: "" 2618: "") 2619: 2620: (define_expand "blt" 2621: [(set (pc) 2622: (if_then_else (lt (cc0) 2623: (const_int 0)) 2624: (label_ref (match_operand 0 "" "")) 2625: (pc)))] 2626: "" 2627: "") 2628: 2629: (define_expand "bltu" 2630: [(set (pc) 2631: (if_then_else (ltu (cc0) 2632: (const_int 0)) 2633: (label_ref (match_operand 0 "" "")) 2634: (pc)))] 2635: "" 2636: "") 2637: 2638: (define_expand "bge" 2639: [(set (pc) 2640: (if_then_else (ge (cc0) 2641: (const_int 0)) 2642: (label_ref (match_operand 0 "" "")) 2643: (pc)))] 2644: "" 2645: "") 2646: 2647: (define_expand "bgeu" 2648: [(set (pc) 2649: (if_then_else (geu (cc0) 2650: (const_int 0)) 2651: (label_ref (match_operand 0 "" "")) 2652: (pc)))] 2653: "" 2654: "") 2655: 2656: (define_expand "ble" 2657: [(set (pc) 2658: (if_then_else (le (cc0) 2659: (const_int 0)) 2660: (label_ref (match_operand 0 "" "")) 2661: (pc)))] 2662: "" 2663: "") 2664: 2665: (define_expand "bleu" 2666: [(set (pc) 2667: (if_then_else (leu (cc0) 2668: (const_int 0)) 2669: (label_ref (match_operand 0 "" "")) 2670: (pc)))] 2671: "" 2672: "") 2673: 2674: ;; Define both directions of branch and return. 2675: 2676: (define_insn "" 2677: [(set (pc) 2678: (if_then_else (match_operator 1 "comparison_operator" 2679: [(cc0) (const_int 0)]) 2680: (label_ref (match_operand 0 "" "")) 2681: (pc)))] 2682: "" 2683: "* 2684: { 2685: if (restore_compare_p (operands[1])) 2686: return 0; 2687: else if (get_attr_length (insn) == 2) 2688: return \"j%j1 %l0\"; 2689: else 2690: return \"b%j1%# %l0\"; 2691: }" 2692: [(set_attr "type" "branch")]) 2693: 2694: (define_insn "" 2695: [(set (pc) 2696: (if_then_else (match_operator 0 "comparison_operator" 2697: [(cc0) (const_int 0)]) 2698: (return) 2699: (pc)))] 2700: "null_epilogue ()" 2701: "* 2702: { 2703: if (restore_compare_p (operands[0])) 2704: return 0; 2705: else 2706: return \"b%j0r%# r15\"; 2707: }" 2708: [(set_attr "type" "return")]) 2709: 2710: (define_insn "" 2711: [(set (pc) 2712: (if_then_else (match_operator 1 "comparison_operator" 2713: [(cc0) (const_int 0)]) 2714: (pc) 2715: (label_ref (match_operand 0 "" ""))))] 2716: "" 2717: "* 2718: { 2719: if (restore_compare_p (operands[1])) 2720: return 0; 2721: else if (get_attr_length (insn) == 2) 2722: return \"j%J1 %l0\"; 2723: else 2724: return \"b%J1%# %l0\"; 2725: }" 2726: [(set_attr "type" "branch")]) 2727: 2728: (define_insn "" 2729: [(set (pc) 2730: (if_then_else (match_operator 0 "comparison_operator" 2731: [(cc0) (const_int 0)]) 2732: (pc) 2733: (return)))] 2734: "null_epilogue ()" 2735: "* 2736: { 2737: if (restore_compare_p (operands[0])) 2738: return 0; 2739: else 2740: return \"b%J0r%# r15\"; 2741: }" 2742: [(set_attr "type" "return")]) 2743: 2744: ;; Unconditional branch and return. 2745: 2746: (define_insn "jump" 2747: [(set (pc) 2748: (label_ref (match_operand 0 "" "")))] 2749: "" 2750: "* 2751: { 2752: if (get_attr_length (insn) == 2) 2753: return \"j %l0\"; 2754: else 2755: return \"b%# %l0\"; 2756: }" 2757: [(set_attr "type" "branch")]) 2758: 2759: (define_insn "return" 2760: [(return)] 2761: "null_epilogue ()" 2762: "br%# r15" 2763: [(set_attr "type" "return")]) 2764: 2765: (define_insn "indirect_jump" 2766: [(set (pc) (match_operand:SI 0 "register_operand" "r"))] 2767: "" 2768: "br%# %0" 2769: [(set_attr "type" "ibranch")]) 2770: 2771: ;; Table jump for switch statements: 2772: (define_insn "tablejump" 2773: [(set (pc) 2774: (match_operand:SI 0 "register_operand" "r")) 2775: (use (label_ref (match_operand 1 "" "")))] 2776: "" 2777: "br%# %0" 2778: [(set_attr "type" "ibranch")])
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.