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