1;; Frv Machine Description 2;; Copyright (C) 1999-2019 Free Software Foundation, Inc. 3;; Contributed by Red Hat, Inc. 4 5;; This file is part of GCC. 6 7;; GCC is free software; you can redistribute it and/or modify 8;; it under the terms of the GNU General Public License as published by 9;; the Free Software Foundation; either version 3, or (at your option) 10;; any later version. 11 12;; GCC is distributed in the hope that it will be useful, 13;; but WITHOUT ANY WARRANTY; without even the implied warranty of 14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15;; GNU General Public License for more details. 16 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING3. If not see 19;; <http://www.gnu.org/licenses/>. 20 21;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 22 23 24;; :::::::::::::::::::: 25;; :: 26;; :: Unspec's used 27;; :: 28;; :::::::::::::::::::: 29 30;; GOT constants must go 12/HI/LO for the splitter to work 31 32(define_constants 33 [(UNSPEC_BLOCKAGE 0) 34 (UNSPEC_CC_TO_GPR 1) 35 (UNSPEC_GPR_TO_CC 2) 36 (UNSPEC_PIC_PROLOGUE 3) 37 (UNSPEC_CR_LOGIC 4) 38 (UNSPEC_STACK_ADJUST 5) 39 (UNSPEC_EH_RETURN_EPILOGUE 6) 40 (UNSPEC_GOT 7) 41 (UNSPEC_LDD 8) 42 (UNSPEC_OPTIONAL_MEMBAR 9) 43 44 (UNSPEC_GETTLSOFF 200) 45 (UNSPEC_TLS_LOAD_GOTTLSOFF12 201) 46 (UNSPEC_TLS_INDIRECT_CALL 202) 47 (UNSPEC_TLS_TLSDESC_LDD 203) 48 (UNSPEC_TLS_TLSDESC_LDD_AUX 204) 49 (UNSPEC_TLS_TLSOFF_LD 205) 50 (UNSPEC_TLS_LDDI 206) 51 (UNSPEC_TLSOFF_HILO 207) 52 53 (R_FRV_GOT12 11) 54 (R_FRV_GOTHI 12) 55 (R_FRV_GOTLO 13) 56 (R_FRV_FUNCDESC 14) 57 (R_FRV_FUNCDESC_GOT12 15) 58 (R_FRV_FUNCDESC_GOTHI 16) 59 (R_FRV_FUNCDESC_GOTLO 17) 60 (R_FRV_FUNCDESC_VALUE 18) 61 (R_FRV_FUNCDESC_GOTOFF12 19) 62 (R_FRV_FUNCDESC_GOTOFFHI 20) 63 (R_FRV_FUNCDESC_GOTOFFLO 21) 64 (R_FRV_GOTOFF12 22) 65 (R_FRV_GOTOFFHI 23) 66 (R_FRV_GOTOFFLO 24) 67 (R_FRV_GPREL12 25) 68 (R_FRV_GPRELHI 26) 69 (R_FRV_GPRELLO 27) 70 (R_FRV_GOTTLSOFF_HI 28) 71 (R_FRV_GOTTLSOFF_LO 29) 72 (R_FRV_TLSMOFFHI 30) 73 (R_FRV_TLSMOFFLO 31) 74 (R_FRV_TLSMOFF12 32) 75 (R_FRV_TLSDESCHI 33) 76 (R_FRV_TLSDESCLO 34) 77 (R_FRV_GOTTLSDESCHI 35) 78 (R_FRV_GOTTLSDESCLO 36) 79 80 (GR8_REG 8) 81 (GR9_REG 9) 82 (GR14_REG 14) 83 ;; LR_REG conflicts with definition in frv.h 84 (LRREG 169) 85 (FDPIC_REG 15) 86 ]) 87 88(define_mode_iterator IMODE [QI HI SI DI]) 89(define_mode_attr IMODEsuffix [(QI "b") (HI "h") (SI "") (DI "d")]) 90(define_mode_attr BREADsuffix [(QI "ub") (HI "uh") (SI "") (DI "d")]) 91 92(define_attr "length" "" (const_int 4)) 93 94;; Processor type -- this attribute must exactly match the processor_type 95;; enumeration in frv-protos.h. 96 97(define_attr "cpu" "generic,fr550,fr500,fr450,fr405,fr400,fr300,simple,tomcat" 98 (const (symbol_ref "(enum attr_cpu) frv_cpu_type"))) 99 100;; Attribute is "yes" for branches and jumps that span too great a distance 101;; to be implemented in the most natural way. Such instructions will use 102;; a call instruction in some way. 103 104(define_attr "far_jump" "yes,no" (const_string "no")) 105 106;; Instruction type 107;; "unknown" must come last. 108(define_attr "type" 109 "int,sethi,setlo,mul,div,gload,gstore,fload,fstore,movfg,movgf,macc,scan,cut,branch,jump,jumpl,call,spr,trap,fnop,fsconv,fsadd,fscmp,fsmul,fsmadd,fsdiv,sqrt_single,fdconv,fdadd,fdcmp,fdmul,fdmadd,fddiv,sqrt_double,mnop,mlogic,maveh,msath,maddh,mqaddh,mpackh,munpackh,mdpackh,mbhconv,mrot,mshift,mexpdhw,mexpdhd,mwcut,mmulh,mmulxh,mmach,mmrdh,mqmulh,mqmulxh,mqmach,mcpx,mqcpx,mcut,mclracc,mclracca,mdunpackh,mbhconve,mrdacc,mwtacc,maddacc,mdaddacc,mabsh,mdrot,mcpl,mdcut,mqsath,mqlimh,mqshift,mset,ccr,multi,load_or_call,unknown" 110 (const_string "unknown")) 111 112(define_attr "acc_group" "none,even,odd" 113 (symbol_ref "(enum attr_acc_group) frv_acc_group (insn)")) 114 115;; Scheduling and Packing Overview 116;; ------------------------------- 117;; 118;; FR-V instructions are divided into five groups: integer, floating-point, 119;; media, branch and control. Each group is associated with a separate set 120;; of processing units, the number and behavior of which depend on the target 121;; target processor. Integer units have names like I0 and I1, floating-point 122;; units have names like F0 and F1, and so on. 123;; 124;; Each member of the FR-V family has its own restrictions on which 125;; instructions can issue to which units. For example, some processors 126;; allow loads to issue to I0 or I1 while others only allow them to issue 127;; to I0. As well as these processor-specific restrictions, there is a 128;; general rule that an instruction can only issue to unit X + 1 if an 129;; instruction in the same packet issued to unit X. 130;; 131;; Sometimes the only way to honor these restrictions is by adding nops 132;; to a packet. For example, on the fr550, media instructions that access 133;; ACC4-7 can only issue to M1 or M3. It is therefore only possible to 134;; execute these instructions by packing them with something that issues 135;; to M0. When no useful M0 instruction exists, an "mnop" can be used 136;; instead. 137;; 138;; Having decided which instructions should issue to which units, the packet 139;; should be ordered according to the following template: 140;; 141;; I0 F0/M0 I1 F1/M1 .... B0 B1 ... 142;; 143;; Note that VLIW packets execute strictly in parallel. Every instruction 144;; in the packet will stall until all input operands are ready. These 145;; operands are then read simultaneously before any registers are modified. 146;; This means that it's OK to have write-after-read hazards between 147;; instructions in the same packet, even if the write is listed earlier 148;; than the read. 149;; 150;; Three gcc passes are involved in generating VLIW packets: 151;; 152;; (1) The scheduler. This pass uses the standard scheduling code and 153;; behaves in much the same way as it would for a superscalar RISC 154;; architecture. 155;; 156;; (2) frv_reorg. This pass inserts nops into packets in order to meet 157;; the processor's issue requirements. It also has code to optimize 158;; the type of padding used to align labels. 159;; 160;; (3) frv_pack_insns. The final packing phase, which puts the 161;; instructions into assembly language order according to the 162;; "I0 F0/M0 ..." template above. 163;; 164;; In the ideal case, these three passes will agree on which instructions 165;; should be packed together, but this won't always happen. In particular: 166;; 167;; (a) (2) might not pack predicated instructions in the same way as (1). 168;; The scheduler tries to schedule predicated instructions for the 169;; worst case, assuming the predicate is true. However, if we have 170;; something like a predicated load, it isn't always possible to 171;; fill the load delay with useful instructions. (2) should then 172;; pack the user of the loaded value as aggressively as possible, 173;; in order to optimize the case when the predicate is false. 174;; See frv_pack_insn_p for more details. 175;; 176;; (b) The final shorten_branches pass runs between (2) and (3). 177;; Since (2) inserts nops, it is possible that some branches 178;; that were thought to be in range during (2) turned out to 179;; out-of-range in (3). 180;; 181;; All three passes use DFAs to model issue restrictions. The main 182;; question that the DFAs are supposed to answer is simply: can these 183;; instructions be packed together? The DFAs are not responsible for 184;; assigning instructions to execution units; that's the job of 185;; frv_sort_insn_group, see below for details. 186;; 187;; To get the best results, the DFAs should try to allow packets to 188;; be built in every possible order. This gives the scheduler more 189;; flexibility, removing the need for things like multipass lookahead. 190;; It also means we can take more advantage of inter-packet dependencies. 191;; 192;; For example, suppose we're compiling for the fr400 and we have: 193;; 194;; addi gr4,#1,gr5 195;; ldi @(gr6,gr0),gr4 196;; 197;; We can pack these instructions together by assigning the load to I0 and 198;; the addition to I1. However, because of the anti dependence between the 199;; two instructions, the scheduler must schedule the addition first. 200;; We should generally get better schedules if the DFA allows both 201;; (ldi, addi) and (addi, ldi), leaving the final packing pass to 202;; reorder the packet where appropriate. 203;; 204;; Almost all integer instructions can issue to any unit in the range I0 205;; to Ix, where the value of "x" depends on the type of instruction and 206;; on the target processor. The rules for other instruction groups are 207;; usually similar. 208;; 209;; When the restrictions are as regular as this, we can get the desired 210;; behavior by claiming the DFA unit associated with the highest unused 211;; execution unit. For example, if an instruction can issue to I0 or I1, 212;; the DFA first tries to take the DFA unit associated with I1, and will 213;; only take I0's unit if I1 isn't free. (Note that, as mentioned above, 214;; the DFA does not assign instructions to units. An instruction that 215;; claims DFA unit I1 will not necessarily issue to I1 in the final packet.) 216;; 217;; There are some cases, such as the fr550 media restriction mentioned 218;; above, where the rule is not as simple as "any unit between 0 and X". 219;; Even so, allocating higher units first brings us close to the ideal. 220;; 221;; Having divided instructions into packets, passes (2) and (3) must 222;; assign instructions to specific execution units. They do this using 223;; the following algorithm: 224;; 225;; 1. Partition the instructions into groups (integer, float/media, etc.) 226;; 227;; 2. For each group of instructions: 228;; 229;; (a) Issue each instruction in the reset DFA state and use the 230;; DFA cpu_unit_query interface to find out which unit it picks 231;; first. 232;; 233;; (b) Sort the instructions into ascending order of picked units. 234;; Instructions that pick I1 first come after those that pick 235;; I0 first, and so on. Let S be the sorted sequence and S[i] 236;; be the ith element of it (counting from zero). 237;; 238;; (c) If this is the control or branch group, goto (i) 239;; 240;; (d) Find the largest L such that S[0]...S[L-1] can be issued 241;; consecutively from the reset state and such that the DFA 242;; claims unit X when S[X] is added. Let D be the DFA state 243;; after instructions S[0]...S[L-1] have been issued. 244;; 245;; (e) If L is the length of S, goto (i) 246;; 247;; (f) Let U be the number of units belonging to this group and #S be 248;; the length of S. Create a new sequence S' by concatenating 249;; S[L]...S[#S-1] and (U - #S) nops. 250;; 251;; (g) For each permutation S'' of S', try issuing S'' from last to 252;; first, starting with state D. See if the DFA claims unit 253;; X + L when each S''[X] is added. If so, set S to the 254;; concatenation of S[0]...S[L-1] and S'', then goto (i). 255;; 256;; (h) If (g) found no permutation, abort. 257;; 258;; (i) S is now the sorted sequence for this group, meaning that S[X] 259;; issues to unit X. Trim any unwanted nops from the end of S. 260;; 261;; The sequence calculated by (b) is trivially correct for control 262;; instructions since they can't be packed. It is also correct for branch 263;; instructions due to their simple issue requirements. For integer and 264;; floating-point/media instructions, the sequence calculated by (b) is 265;; often the correct answer; the rest of the algorithm is optimized for 266;; the case in which it is correct. 267;; 268;; If there were no irregularities in the issue restrictions then step 269;; (d) would not be needed. It is mainly there to cope with the fr550 270;; integer restrictions, where a store can issue to I1, but only if a store 271;; also issues to I0. (Note that if a packet has two stores, they will be 272;; at the beginning of the sequence calculated by (b).) It also copes 273;; with fr400 M-2 instructions, which must issue to M0, and which cannot 274;; be issued together with an mnop in M1. 275;; 276;; Step (g) is the main one for integer and float/media instructions. 277;; The first permutation it tries is S' itself (because, as noted above, 278;; the sequence calculated by (b) is often correct). If S' doesn't work, 279;; the implementation tries varying the beginning of the sequence first. 280;; Thus the nops towards the end of the sequence will only move to lower 281;; positions if absolutely necessary. 282;; 283;; The algorithm is theoretically exponential in the number of instructions 284;; in a group, although it's only O(n log(n)) if the sequence calculated by 285;; (b) is acceptable. In practice, the algorithm completes quickly even 286;; in the rare cases where (g) needs to try other permutations. 287(define_automaton "integer, float_media, branch, control, idiv, div") 288 289;; The main issue units. Note that not all units are available on 290;; all processors. 291(define_query_cpu_unit "i0,i1,i2,i3" "integer") 292(define_query_cpu_unit "f0,f1,f2,f3" "float_media") 293(define_query_cpu_unit "b0,b1" "branch") 294(define_query_cpu_unit "c" "control") 295 296;; Division units. 297(define_cpu_unit "idiv1,idiv2" "idiv") 298(define_cpu_unit "div1,div2,root" "div") 299 300;; Control instructions cannot be packed with others. 301(define_reservation "control" "i0+i1+i2+i3+f0+f1+f2+f3+b0+b1") 302 303;; Generic reservation for control insns 304(define_insn_reservation "control" 1 305 (eq_attr "type" "trap,spr,unknown,multi") 306 "c + control") 307 308;; Reservation for relaxable calls to gettlsoff. 309(define_insn_reservation "load_or_call" 3 310 (eq_attr "type" "load_or_call") 311 "c + control") 312 313;; :::::::::::::::::::: 314;; :: 315;; :: Generic/FR500 scheduler description 316;; :: 317;; :::::::::::::::::::: 318 319;; Integer insns 320;; Synthetic units used to describe issue restrictions. 321(define_automaton "fr500_integer") 322(define_cpu_unit "fr500_load0,fr500_load1,fr500_store0" "fr500_integer") 323(exclusion_set "fr500_load0,fr500_load1" "fr500_store0") 324 325(define_bypass 0 "fr500_i1_sethi" "fr500_i1_setlo") 326(define_insn_reservation "fr500_i1_sethi" 1 327 (and (eq_attr "cpu" "generic,fr500,tomcat") 328 (eq_attr "type" "sethi")) 329 "i1|i0") 330 331(define_insn_reservation "fr500_i1_setlo" 1 332 (and (eq_attr "cpu" "generic,fr500,tomcat") 333 (eq_attr "type" "setlo")) 334 "i1|i0") 335 336(define_insn_reservation "fr500_i1_int" 1 337 (and (eq_attr "cpu" "generic,fr500,tomcat") 338 (eq_attr "type" "int")) 339 "i1|i0") 340 341(define_insn_reservation "fr500_i1_mul" 3 342 (and (eq_attr "cpu" "generic,fr500,tomcat") 343 (eq_attr "type" "mul")) 344 "i1|i0") 345 346(define_insn_reservation "fr500_i1_div" 19 347 (and (eq_attr "cpu" "generic,fr500,tomcat") 348 (eq_attr "type" "div")) 349 "(i1|i0),(idiv1*18|idiv2*18)") 350 351(define_insn_reservation "fr500_i2" 4 352 (and (eq_attr "cpu" "generic,fr500,tomcat") 353 (eq_attr "type" "gload,fload")) 354 "(i1|i0) + (fr500_load0|fr500_load1)") 355 356(define_insn_reservation "fr500_i3" 0 357 (and (eq_attr "cpu" "generic,fr500,tomcat") 358 (eq_attr "type" "gstore,fstore")) 359 "i0 + fr500_store0") 360 361(define_insn_reservation "fr500_i4" 3 362 (and (eq_attr "cpu" "generic,fr500,tomcat") 363 (eq_attr "type" "movgf,movfg")) 364 "i0") 365 366(define_insn_reservation "fr500_i5" 0 367 (and (eq_attr "cpu" "generic,fr500,tomcat") 368 (eq_attr "type" "jumpl")) 369 "i0") 370 371;; 372;; Branch-instructions 373;; 374(define_insn_reservation "fr500_branch" 0 375 (and (eq_attr "cpu" "generic,fr500,tomcat") 376 (eq_attr "type" "jump,branch,ccr")) 377 "b1|b0") 378 379(define_insn_reservation "fr500_call" 0 380 (and (eq_attr "cpu" "generic,fr500,tomcat") 381 (eq_attr "type" "call")) 382 "b0") 383 384;; Floating point insns. The default latencies are for non-media 385;; instructions; media instructions incur an extra cycle. 386 387(define_bypass 4 "fr500_farith" "fr500_m1,fr500_m2,fr500_m3, 388 fr500_m4,fr500_m5,fr500_m6") 389(define_insn_reservation "fr500_farith" 3 390 (and (eq_attr "cpu" "generic,fr500,tomcat") 391 (eq_attr "type" "fnop,fsconv,fsadd,fsmul,fsmadd,fdconv,fdadd,fdmul,fdmadd")) 392 "(f1|f0)") 393 394(define_insn_reservation "fr500_fcmp" 4 395 (and (eq_attr "cpu" "generic,fr500,tomcat") 396 (eq_attr "type" "fscmp,fdcmp")) 397 "(f1|f0)") 398 399(define_bypass 11 "fr500_fdiv" "fr500_m1,fr500_m2,fr500_m3, 400 fr500_m4,fr500_m5,fr500_m6") 401(define_insn_reservation "fr500_fdiv" 10 402 (and (eq_attr "cpu" "generic,fr500,tomcat") 403 (eq_attr "type" "fsdiv,fddiv")) 404 "(f1|f0),(div1*9 | div2*9)") 405 406(define_bypass 16 "fr500_froot" "fr500_m1,fr500_m2,fr500_m3, 407 fr500_m4,fr500_m5,fr500_m6") 408(define_insn_reservation "fr500_froot" 15 409 (and (eq_attr "cpu" "generic,fr500,tomcat") 410 (eq_attr "type" "sqrt_single,sqrt_double")) 411 "(f1|f0) + root*15") 412 413;; Media insns. Conflict table is as follows: 414;; 415;; M1 M2 M3 M4 M5 M6 416;; M1 - - - - - - 417;; M2 - - - - X X 418;; M3 - - - - X X 419;; M4 - - - - - X 420;; M5 - X X - X X 421;; M6 - X X X X X 422;; 423;; where X indicates an invalid combination. 424;; 425;; Target registers are as follows: 426;; 427;; M1 : FPRs 428;; M2 : FPRs 429;; M3 : ACCs 430;; M4 : ACCs 431;; M5 : FPRs 432;; M6 : ACCs 433;; 434;; The default FPR latencies are for integer instructions. 435;; Floating-point instructions need one cycle more and media 436;; instructions need one cycle less. 437(define_automaton "fr500_media") 438(define_cpu_unit "fr500_m2_0,fr500_m2_1" "fr500_media") 439(define_cpu_unit "fr500_m3_0,fr500_m3_1" "fr500_media") 440(define_cpu_unit "fr500_m4_0,fr500_m4_1" "fr500_media") 441(define_cpu_unit "fr500_m5" "fr500_media") 442(define_cpu_unit "fr500_m6" "fr500_media") 443 444(exclusion_set "fr500_m5,fr500_m6" "fr500_m2_0,fr500_m2_1, 445 fr500_m3_0,fr500_m3_1") 446(exclusion_set "fr500_m6" "fr500_m4_0,fr500_m4_1,fr500_m5") 447 448(define_bypass 2 "fr500_m1" "fr500_m1,fr500_m2,fr500_m3, 449 fr500_m4,fr500_m5,fr500_m6") 450(define_bypass 4 "fr500_m1" "fr500_farith,fr500_fcmp,fr500_fdiv,fr500_froot") 451(define_insn_reservation "fr500_m1" 3 452 (and (eq_attr "cpu" "generic,fr500,tomcat") 453 (eq_attr "type" "mnop,mlogic,maveh,msath,maddh,mqaddh")) 454 "(f1|f0)") 455 456(define_bypass 2 "fr500_m2" "fr500_m1,fr500_m2,fr500_m3, 457 fr500_m4,fr500_m5,fr500_m6") 458(define_bypass 4 "fr500_m2" "fr500_farith,fr500_fcmp,fr500_fdiv,fr500_froot") 459(define_insn_reservation "fr500_m2" 3 460 (and (eq_attr "cpu" "generic,fr500,tomcat") 461 (eq_attr "type" "mrdacc,mpackh,munpackh,mbhconv,mrot,mshift,mexpdhw,mexpdhd,mwcut,mcut,mdunpackh,mbhconve")) 462 "(f1|f0) + (fr500_m2_0|fr500_m2_1)") 463 464(define_bypass 1 "fr500_m3" "fr500_m4") 465(define_insn_reservation "fr500_m3" 2 466 (and (eq_attr "cpu" "generic,fr500,tomcat") 467 (eq_attr "type" "mclracc,mwtacc")) 468 "(f1|f0) + (fr500_m3_0|fr500_m3_1)") 469 470(define_bypass 1 "fr500_m4" "fr500_m4") 471(define_insn_reservation "fr500_m4" 2 472 (and (eq_attr "cpu" "generic,fr500,tomcat") 473 (eq_attr "type" "mmulh,mmulxh,mmach,mmrdh,mqmulh,mqmulxh,mqmach,mcpx,mqcpx")) 474 "(f1|f0) + (fr500_m4_0|fr500_m4_1)") 475 476(define_bypass 2 "fr500_m5" "fr500_m1,fr500_m2,fr500_m3, 477 fr500_m4,fr500_m5,fr500_m6") 478(define_bypass 4 "fr500_m5" "fr500_farith,fr500_fcmp,fr500_fdiv,fr500_froot") 479(define_insn_reservation "fr500_m5" 3 480 (and (eq_attr "cpu" "generic,fr500,tomcat") 481 (eq_attr "type" "mdpackh")) 482 "(f1|f0) + fr500_m5") 483 484(define_bypass 1 "fr500_m6" "fr500_m4") 485(define_insn_reservation "fr500_m6" 2 486 (and (eq_attr "cpu" "generic,fr500,tomcat") 487 (eq_attr "type" "mclracca")) 488 "(f1|f0) + fr500_m6") 489 490;; :::::::::::::::::::: 491;; :: 492;; :: FR400 scheduler description 493;; :: 494;; :::::::::::::::::::: 495 496;; Category 2 media instructions use both media units, but can be packed 497;; with non-media instructions. Use fr400_m1unit to claim the M1 unit 498;; without claiming a slot. 499 500;; Name Class Units Latency 501;; ==== ===== ===== ======= 502;; int I1 I0/I1 1 503;; sethi I1 I0/I1 0 -- does not interfere with setlo 504;; setlo I1 I0/I1 1 505;; mul I1 I0 3 (*) 506;; div I1 I0 20 (*) 507;; gload I2 I0 4 (*) 508;; fload I2 I0 4 -- only 3 if read by a media insn 509;; gstore I3 I0 0 -- provides no result 510;; fstore I3 I0 0 -- provides no result 511;; movfg I4 I0 3 (*) 512;; movgf I4 I0 3 (*) 513;; jumpl I5 I0 0 -- provides no result 514;; 515;; (*) The results of these instructions can be read one cycle earlier 516;; than indicated. The penalty given is for instructions with write-after- 517;; write dependencies. 518 519;; The FR400 can only do loads and stores in I0, so we there's no danger 520;; of memory unit collision in the same packet. There's only one divide 521;; unit too. 522 523(define_automaton "fr400_integer") 524(define_cpu_unit "fr400_mul" "fr400_integer") 525 526(define_insn_reservation "fr400_i1_int" 1 527 (and (eq_attr "cpu" "fr400,fr405,fr450") 528 (eq_attr "type" "int")) 529 "i1|i0") 530 531(define_bypass 0 "fr400_i1_sethi" "fr400_i1_setlo") 532(define_insn_reservation "fr400_i1_sethi" 1 533 (and (eq_attr "cpu" "fr400,fr405,fr450") 534 (eq_attr "type" "sethi")) 535 "i1|i0") 536 537(define_insn_reservation "fr400_i1_setlo" 1 538 (and (eq_attr "cpu" "fr400,fr405,fr450") 539 (eq_attr "type" "setlo")) 540 "i1|i0") 541 542;; 3 is the worst case (write-after-write hazard). 543(define_insn_reservation "fr400_i1_mul" 3 544 (and (eq_attr "cpu" "fr400,fr405") 545 (eq_attr "type" "mul")) 546 "i0 + fr400_mul") 547 548(define_insn_reservation "fr450_i1_mul" 2 549 (and (eq_attr "cpu" "fr450") 550 (eq_attr "type" "mul")) 551 "i0 + fr400_mul") 552 553(define_bypass 1 "fr400_i1_macc" "fr400_i1_macc") 554(define_insn_reservation "fr400_i1_macc" 2 555 (and (eq_attr "cpu" "fr405,fr450") 556 (eq_attr "type" "macc")) 557 "(i0|i1) + fr400_mul") 558 559(define_insn_reservation "fr400_i1_scan" 1 560 (and (eq_attr "cpu" "fr400,fr405,fr450") 561 (eq_attr "type" "scan")) 562 "i0") 563 564(define_insn_reservation "fr400_i1_cut" 2 565 (and (eq_attr "cpu" "fr405,fr450") 566 (eq_attr "type" "cut")) 567 "i0 + fr400_mul") 568 569;; 20 is for a write-after-write hazard. 570(define_insn_reservation "fr400_i1_div" 20 571 (and (eq_attr "cpu" "fr400,fr405") 572 (eq_attr "type" "div")) 573 "i0 + idiv1*19") 574 575(define_insn_reservation "fr450_i1_div" 19 576 (and (eq_attr "cpu" "fr450") 577 (eq_attr "type" "div")) 578 "i0 + idiv1*19") 579 580;; 4 is for a write-after-write hazard. 581(define_insn_reservation "fr400_i2" 4 582 (and (eq_attr "cpu" "fr400,fr405") 583 (eq_attr "type" "gload,fload")) 584 "i0") 585 586(define_insn_reservation "fr450_i2_gload" 3 587 (and (eq_attr "cpu" "fr450") 588 (eq_attr "type" "gload")) 589 "i0") 590 591;; 4 is for a write-after-write hazard. 592(define_insn_reservation "fr450_i2_fload" 4 593 (and (eq_attr "cpu" "fr450") 594 (eq_attr "type" "fload")) 595 "i0") 596 597(define_insn_reservation "fr400_i3" 0 598 (and (eq_attr "cpu" "fr400,fr405,fr450") 599 (eq_attr "type" "gstore,fstore")) 600 "i0") 601 602;; 3 is for a write-after-write hazard. 603(define_insn_reservation "fr400_i4" 3 604 (and (eq_attr "cpu" "fr400,fr405") 605 (eq_attr "type" "movfg,movgf")) 606 "i0") 607 608(define_insn_reservation "fr450_i4_movfg" 2 609 (and (eq_attr "cpu" "fr450") 610 (eq_attr "type" "movfg")) 611 "i0") 612 613;; 3 is for a write-after-write hazard. 614(define_insn_reservation "fr450_i4_movgf" 3 615 (and (eq_attr "cpu" "fr450") 616 (eq_attr "type" "movgf")) 617 "i0") 618 619(define_insn_reservation "fr400_i5" 0 620 (and (eq_attr "cpu" "fr400,fr405,fr450") 621 (eq_attr "type" "jumpl")) 622 "i0") 623 624;; The bypass between FPR loads and media instructions, described above. 625 626(define_bypass 3 627 "fr400_i2" 628 "fr400_m1_1,fr400_m1_2,\ 629 fr400_m2_1,fr400_m2_2,\ 630 fr400_m3_1,fr400_m3_2,\ 631 fr400_m4_1,fr400_m4_2,\ 632 fr400_m5") 633 634;; The branch instructions all use the B unit and produce no result. 635 636(define_insn_reservation "fr400_b" 0 637 (and (eq_attr "cpu" "fr400,fr405,fr450") 638 (eq_attr "type" "jump,branch,ccr,call")) 639 "b0") 640 641;; FP->FP moves are marked as "fsconv" instructions in the define_insns 642;; below, but are implemented on the FR400 using "mlogic" instructions. 643;; It's easier to class "fsconv" as a "m1:1" instruction than provide 644;; separate define_insns for the FR400. 645 646;; M1 instructions store their results in FPRs. Any instruction can read 647;; the result in the following cycle, so no penalty occurs. 648 649(define_automaton "fr400_media") 650(define_cpu_unit "fr400_m1a,fr400_m1b,fr400_m2a" "fr400_media") 651(exclusion_set "fr400_m1a,fr400_m1b" "fr400_m2a") 652 653(define_reservation "fr400_m1" "(f1|f0) + (fr400_m1a|fr400_m1b)") 654(define_reservation "fr400_m2" "f0 + fr400_m2a") 655 656(define_insn_reservation "fr400_m1_1" 1 657 (and (eq_attr "cpu" "fr400,fr405") 658 (eq_attr "type" "fsconv,mnop,mlogic,maveh,msath,maddh,mabsh,mset")) 659 "fr400_m1") 660 661(define_insn_reservation "fr400_m1_2" 1 662 (and (eq_attr "cpu" "fr400,fr405") 663 (eq_attr "type" "mqaddh,mqsath,mqlimh,mqshift")) 664 "fr400_m2") 665 666;; M2 instructions store their results in accumulators, which are read 667;; by M2 or M4 media commands. M2 instructions can read the results in 668;; the following cycle, but M4 instructions must wait a cycle more. 669 670(define_bypass 1 671 "fr400_m2_1,fr400_m2_2" 672 "fr400_m2_1,fr400_m2_2") 673 674(define_insn_reservation "fr400_m2_1" 2 675 (and (eq_attr "cpu" "fr400,fr405") 676 (eq_attr "type" "mmulh,mmulxh,mmach,mmrdh,mcpx,maddacc")) 677 "fr400_m1") 678 679(define_insn_reservation "fr400_m2_2" 2 680 (and (eq_attr "cpu" "fr400,fr405") 681 (eq_attr "type" "mqmulh,mqmulxh,mqmach,mqcpx,mdaddacc")) 682 "fr400_m2") 683 684;; For our purposes, there seems to be little real difference between 685;; M1 and M3 instructions. Keep them separate anyway in case the distinction 686;; is needed later. 687 688(define_insn_reservation "fr400_m3_1" 1 689 (and (eq_attr "cpu" "fr400,fr405") 690 (eq_attr "type" "mpackh,mrot,mshift,mexpdhw")) 691 "fr400_m1") 692 693(define_insn_reservation "fr400_m3_2" 1 694 (and (eq_attr "cpu" "fr400,fr405") 695 (eq_attr "type" "munpackh,mdpackh,mbhconv,mexpdhd,mwcut,mdrot,mcpl")) 696 "fr400_m2") 697 698;; M4 instructions write to accumulators or FPRs. MOVFG and STF 699;; instructions can read an FPR result in the following cycle, but 700;; M-unit instructions must wait a cycle more for either kind of result. 701 702(define_bypass 1 "fr400_m4_1,fr400_m4_2" "fr400_i3,fr400_i4") 703 704(define_insn_reservation "fr400_m4_1" 2 705 (and (eq_attr "cpu" "fr400,fr405") 706 (eq_attr "type" "mrdacc,mcut,mclracc")) 707 "fr400_m1") 708 709(define_insn_reservation "fr400_m4_2" 2 710 (and (eq_attr "cpu" "fr400,fr405") 711 (eq_attr "type" "mclracca,mdcut")) 712 "fr400_m2") 713 714;; M5 instructions always incur a 1-cycle penalty. 715 716(define_insn_reservation "fr400_m5" 2 717 (and (eq_attr "cpu" "fr400,fr405") 718 (eq_attr "type" "mwtacc")) 719 "fr400_m2") 720 721;; :::::::::::::::::::: 722;; :: 723;; :: FR450 media scheduler description 724;; :: 725;; :::::::::::::::::::: 726 727;; The FR451 media restrictions are similar to the FR400's, but not as 728;; strict and not as regular. There are 6 categories with the following 729;; restrictions: 730;; 731;; M1 732;; M-1 M-2 M-3 M-4 M-5 M-6 733;; M-1: x x x 734;; M-2: x x x x x x 735;; M0 M-3: x x x 736;; M-4: x x x x 737;; M-5: x x x 738;; M-6: x x x x x x 739;; 740;; where "x" indicates a conflict. 741;; 742;; There is no difference between M-1 and M-3 as far as issue 743;; restrictions are concerned, so they are combined as "m13". 744 745;; Units for odd-numbered categories. There can be two of these 746;; in a packet. 747(define_cpu_unit "fr450_m13a,fr450_m13b" "float_media") 748(define_cpu_unit "fr450_m5a,fr450_m5b" "float_media") 749 750;; Units for even-numbered categories. There can only be one per packet. 751(define_cpu_unit "fr450_m2a,fr450_m4a,fr450_m6a" "float_media") 752 753;; Enforce the restriction matrix above. 754(exclusion_set "fr450_m2a,fr450_m4a,fr450_m6a" "fr450_m13a,fr450_m13b") 755(exclusion_set "fr450_m2a,fr450_m6a" "fr450_m5a,fr450_m5b") 756(exclusion_set "fr450_m4a,fr450_m6a" "fr450_m2a") 757 758(define_reservation "fr450_m13" "(f1|f0) + (fr450_m13a|fr450_m13b)") 759(define_reservation "fr450_m2" "f0 + fr450_m2a") 760(define_reservation "fr450_m4" "f0 + fr450_m4a") 761(define_reservation "fr450_m5" "(f1|f0) + (fr450_m5a|fr450_m5b)") 762(define_reservation "fr450_m6" "(f0|f1) + fr450_m6a") 763 764;; MD-1, MD-3 and MD-8 instructions, which are the same as far 765;; as scheduling is concerned. The inputs and outputs are FPRs. 766;; Instructions that have 32-bit inputs and outputs belong to M-1 while 767;; the rest belong to M-2. 768;; 769;; ??? Arithmetic shifts (MD-6) have an extra cycle latency, but we don't 770;; make the distinction between them and logical shifts. 771(define_insn_reservation "fr450_md138_1" 1 772 (and (eq_attr "cpu" "fr450") 773 (eq_attr "type" "fsconv,mnop,mlogic,maveh,msath,maddh,mabsh,mset, 774 mrot,mshift,mexpdhw,mpackh")) 775 "fr450_m13") 776 777(define_insn_reservation "fr450_md138_2" 1 778 (and (eq_attr "cpu" "fr450") 779 (eq_attr "type" "mqaddh,mqsath,mqlimh, 780 mdrot,mwcut,mqshift,mexpdhd, 781 munpackh,mdpackh,mbhconv,mcpl")) 782 "fr450_m2") 783 784;; MD-2 instructions. These take FPR or ACC inputs and produce an ACC output. 785;; Instructions that write to double ACCs belong to M-3 while those that write 786;; to quad ACCs belong to M-4. 787(define_insn_reservation "fr450_md2_3" 2 788 (and (eq_attr "cpu" "fr450") 789 (eq_attr "type" "mmulh,mmach,mcpx,mmulxh,mmrdh,maddacc")) 790 "fr450_m13") 791 792(define_insn_reservation "fr450_md2_4" 2 793 (and (eq_attr "cpu" "fr450") 794 (eq_attr "type" "mqmulh,mqmach,mqcpx,mqmulxh,mdaddacc")) 795 "fr450_m4") 796 797;; Another MD-2 instruction can use the result on the following cycle. 798(define_bypass 1 "fr450_md2_3,fr450_md2_4" "fr450_md2_3,fr450_md2_4") 799 800;; MD-4 instructions that write to ACCs. 801(define_insn_reservation "fr450_md4_3" 2 802 (and (eq_attr "cpu" "fr450") 803 (eq_attr "type" "mclracc")) 804 "fr450_m13") 805 806(define_insn_reservation "fr450_md4_4" 3 807 (and (eq_attr "cpu" "fr450") 808 (eq_attr "type" "mclracca")) 809 "fr450_m4") 810 811;; MD-4 instructions that write to FPRs. 812(define_insn_reservation "fr450_md4_1" 2 813 (and (eq_attr "cpu" "fr450") 814 (eq_attr "type" "mcut")) 815 "fr450_m13") 816 817(define_insn_reservation "fr450_md4_5" 2 818 (and (eq_attr "cpu" "fr450") 819 (eq_attr "type" "mrdacc")) 820 "fr450_m5") 821 822(define_insn_reservation "fr450_md4_6" 2 823 (and (eq_attr "cpu" "fr450") 824 (eq_attr "type" "mdcut")) 825 "fr450_m6") 826 827;; Integer instructions can read the FPR result of an MD-4 instruction on 828;; the following cycle. 829(define_bypass 1 "fr450_md4_1,fr450_md4_5,fr450_md4_6" 830 "fr400_i3,fr450_i4_movfg") 831 832;; MD-5 instructions, which belong to M-3. They take FPR inputs and 833;; write to ACCs. 834(define_insn_reservation "fr450_md5_3" 2 835 (and (eq_attr "cpu" "fr450") 836 (eq_attr "type" "mwtacc")) 837 "fr450_m13") 838 839;; :::::::::::::::::::: 840;; :: 841;; :: FR550 scheduler description 842;; :: 843;; :::::::::::::::::::: 844 845;; Prevent loads and stores from being issued in the same packet. 846;; These units must go into the generic "integer" reservation because 847;; of the constraints on fr550_store0 and fr550_store1. 848(define_cpu_unit "fr550_load0,fr550_load1" "integer") 849(define_cpu_unit "fr550_store0,fr550_store1" "integer") 850(exclusion_set "fr550_load0,fr550_load1" "fr550_store0,fr550_store1") 851 852;; A store can only issue to I1 if one has also been issued to I0. 853(presence_set "fr550_store1" "fr550_store0") 854 855(define_bypass 0 "fr550_sethi" "fr550_setlo") 856(define_insn_reservation "fr550_sethi" 1 857 (and (eq_attr "cpu" "fr550") 858 (eq_attr "type" "sethi")) 859 "i3|i2|i1|i0") 860 861(define_insn_reservation "fr550_setlo" 1 862 (and (eq_attr "cpu" "fr550") 863 (eq_attr "type" "setlo")) 864 "i3|i2|i1|i0") 865 866(define_insn_reservation "fr550_int" 1 867 (and (eq_attr "cpu" "fr550") 868 (eq_attr "type" "int")) 869 "i3|i2|i1|i0") 870 871(define_insn_reservation "fr550_mul" 2 872 (and (eq_attr "cpu" "fr550") 873 (eq_attr "type" "mul")) 874 "i1|i0") 875 876(define_insn_reservation "fr550_div" 19 877 (and (eq_attr "cpu" "fr550") 878 (eq_attr "type" "div")) 879 "(i1|i0),(idiv1*18 | idiv2*18)") 880 881(define_insn_reservation "fr550_load" 3 882 (and (eq_attr "cpu" "fr550") 883 (eq_attr "type" "gload,fload")) 884 "(i1|i0)+(fr550_load0|fr550_load1)") 885 886;; We can only issue a store to I1 if one was also issued to I0. 887;; This means that, as far as frv_reorder_packet is concerned, 888;; the instruction has the same priority as an I0-only instruction. 889(define_insn_reservation "fr550_store" 1 890 (and (eq_attr "cpu" "fr550") 891 (eq_attr "type" "gstore,fstore")) 892 "(i0+fr550_store0)|(i1+fr550_store1)") 893 894(define_insn_reservation "fr550_transfer" 2 895 (and (eq_attr "cpu" "fr550") 896 (eq_attr "type" "movgf,movfg")) 897 "i0") 898 899(define_insn_reservation "fr550_jumpl" 0 900 (and (eq_attr "cpu" "fr550") 901 (eq_attr "type" "jumpl")) 902 "i0") 903 904(define_cpu_unit "fr550_ccr0,fr550_ccr1" "float_media") 905 906(define_insn_reservation "fr550_branch" 0 907 (and (eq_attr "cpu" "fr550") 908 (eq_attr "type" "jump,branch")) 909 "b1|b0") 910 911(define_insn_reservation "fr550_ccr" 0 912 (and (eq_attr "cpu" "fr550") 913 (eq_attr "type" "ccr")) 914 "(b1|b0) + (fr550_ccr1|fr550_ccr0)") 915 916(define_insn_reservation "fr550_call" 0 917 (and (eq_attr "cpu" "fr550") 918 (eq_attr "type" "call")) 919 "b0") 920 921(define_automaton "fr550_float_media") 922(define_cpu_unit "fr550_add0,fr550_add1" "fr550_float_media") 923 924;; There are three possible combinations of floating-point/media instructions: 925;; 926;; - one media and one float 927;; - up to four float, no media 928;; - up to four media, no float 929(define_cpu_unit "fr550_f0,fr550_f1,fr550_f2,fr550_f3" "fr550_float_media") 930(define_cpu_unit "fr550_m0,fr550_m1,fr550_m2,fr550_m3" "fr550_float_media") 931(exclusion_set "fr550_f1,fr550_f2,fr550_f3" "fr550_m1,fr550_m2,fr550_m3") 932(exclusion_set "fr550_m0" "fr550_f1,fr550_f2,fr550_f3") 933;; FIXME: This next exclusion set should be defined as well, so that we do 934;; not get a packet containing multiple media instructions plus a single 935;; floating point instruction. At the moment we can get away with not 936;; defining it because gcc does not seem to generate such packets. 937;; 938;; If we do enable the exclusion however the insertion of fnop insns into 939;; a packet containing media instructions will stop working, because the 940;; fnop insn counts as a floating point instruction. The correct solution 941;; is to fix the reservation for the fnop insn so that it does not have the 942;; same restrictions as ordinary floating point insns. 943;;(exclusion_set "fr550_f0" "fr550_m1,fr550_m2,fr550_m3") 944 945(define_reservation "fr550_float" "fr550_f0|fr550_f1|fr550_f2|fr550_f3") 946(define_reservation "fr550_media" "fr550_m0|fr550_m1|fr550_m2|fr550_m3") 947 948(define_insn_reservation "fr550_f1" 0 949 (and (eq_attr "cpu" "fr550") 950 (eq_attr "type" "fnop")) 951 "(f3|f2|f1|f0) + fr550_float") 952 953(define_insn_reservation "fr550_f2" 3 954 (and (eq_attr "cpu" "fr550") 955 (eq_attr "type" "fsconv,fsadd,fscmp")) 956 "(f3|f2|f1|f0) + (fr550_add0|fr550_add1) + fr550_float") 957 958(define_insn_reservation "fr550_f3_mul" 3 959 (and (eq_attr "cpu" "fr550") 960 (eq_attr "type" "fsmul")) 961 "(f1|f0) + fr550_float") 962 963(define_insn_reservation "fr550_f3_div" 10 964 (and (eq_attr "cpu" "fr550") 965 (eq_attr "type" "fsdiv")) 966 "(f1|f0) + fr550_float") 967 968(define_insn_reservation "fr550_f3_sqrt" 15 969 (and (eq_attr "cpu" "fr550") 970 (eq_attr "type" "sqrt_single")) 971 "(f1|f0) + fr550_float") 972 973;; Synthetic units for enforcing media issue restrictions. Certain types 974;; of insn in M2 conflict with certain types in M0: 975;; 976;; M2 977;; MNOP MALU MSFT MMAC MSET 978;; MNOP - - x - - 979;; MALU - x x - - 980;; M0 MSFT - - x - x 981;; MMAC - - x x - 982;; MSET - - x - - 983;; 984;; where "x" indicates a conflict. The same restrictions apply to 985;; M3 and M1. 986;; 987;; In addition -- and this is the awkward bit! -- instructions that 988;; access ACC0-3 can only issue to M0 or M2. Those that access ACC4-7 989;; can only issue to M1 or M3. We refer to such instructions as "even" 990;; and "odd" respectively. 991(define_cpu_unit "fr550_malu0,fr550_malu1" "float_media") 992(define_cpu_unit "fr550_malu2,fr550_malu3" "float_media") 993(define_cpu_unit "fr550_msft0,fr550_msft1" "float_media") 994(define_cpu_unit "fr550_mmac0,fr550_mmac1" "float_media") 995(define_cpu_unit "fr550_mmac2,fr550_mmac3" "float_media") 996(define_cpu_unit "fr550_mset0,fr550_mset1" "float_media") 997(define_cpu_unit "fr550_mset2,fr550_mset3" "float_media") 998 999(exclusion_set "fr550_malu0" "fr550_malu2") 1000(exclusion_set "fr550_malu1" "fr550_malu3") 1001 1002(exclusion_set "fr550_msft0" "fr550_mset2") 1003(exclusion_set "fr550_msft1" "fr550_mset3") 1004 1005(exclusion_set "fr550_mmac0" "fr550_mmac2") 1006(exclusion_set "fr550_mmac1" "fr550_mmac3") 1007 1008;; If an MSFT or MMAC instruction issues to a unit other than M0, we may 1009;; need to insert some nops. In the worst case, the packet will end up 1010;; having 4 integer instructions and 4 media instructions, leaving no 1011;; room for any branch instructions that the DFA might have accepted. 1012;; 1013;; This doesn't matter for JUMP_INSNs and CALL_INSNs because they are 1014;; always the last instructions to be passed to the DFA, and could be 1015;; pushed out to a separate packet once the nops have been added. 1016;; However, it does cause problems for ccr instructions since they 1017;; can occur anywhere in the unordered packet. 1018(exclusion_set "fr550_msft1,fr550_mmac1,fr550_mmac2,fr550_mmac3" 1019 "fr550_ccr0,fr550_ccr1") 1020 1021(define_reservation "fr550_malu" 1022 "(f3 + fr550_malu3) | (f2 + fr550_malu2) 1023 | (f1 + fr550_malu1) | (f0 + fr550_malu0)") 1024 1025(define_reservation "fr550_msft_even" 1026 "f0 + fr550_msft0") 1027 1028(define_reservation "fr550_msft_odd" 1029 "f1 + fr550_msft1") 1030 1031(define_reservation "fr550_msft_either" 1032 "(f1 + fr550_msft1) | (f0 + fr550_msft0)") 1033 1034(define_reservation "fr550_mmac_even" 1035 "(f2 + fr550_mmac2) | (f0 + fr550_mmac0)") 1036 1037(define_reservation "fr550_mmac_odd" 1038 "(f3 + fr550_mmac3) | (f1 + fr550_mmac1)") 1039 1040(define_reservation "fr550_mset" 1041 "(f3 + fr550_mset3) | (f2 + fr550_mset2) 1042 | (f1 + fr550_mset1) | (f0 + fr550_mset0)") 1043 1044(define_insn_reservation "fr550_mnop" 0 1045 (and (eq_attr "cpu" "fr550") 1046 (eq_attr "type" "mnop")) 1047 "fr550_media + (f3|f2|f1|f0)") 1048 1049(define_insn_reservation "fr550_malu" 2 1050 (and (eq_attr "cpu" "fr550") 1051 (eq_attr "type" "mlogic,maveh,msath,mabsh,maddh,mqaddh,mqsath")) 1052 "fr550_media + fr550_malu") 1053 1054;; These insns only operate on FPRs and so don't need to be classified 1055;; as even/odd. 1056(define_insn_reservation "fr550_msft_1_either" 2 1057 (and (eq_attr "cpu" "fr550") 1058 (eq_attr "type" "mrot,mwcut,mshift,mexpdhw,mexpdhd,mpackh, 1059 munpackh,mdpackh,mbhconv,mdrot,mcpl")) 1060 "fr550_media + fr550_msft_either") 1061 1062;; These insns read from ACC0-3. 1063(define_insn_reservation "fr550_msft_1_even" 2 1064 (and (eq_attr "cpu" "fr550") 1065 (and (eq_attr "type" "mcut,mrdacc,mdcut") 1066 (eq_attr "acc_group" "even"))) 1067 "fr550_media + fr550_msft_even") 1068 1069;; These insns read from ACC4-7. 1070(define_insn_reservation "fr550_msft_1_odd" 2 1071 (and (eq_attr "cpu" "fr550") 1072 (and (eq_attr "type" "mcut,mrdacc,mdcut") 1073 (eq_attr "acc_group" "odd"))) 1074 "fr550_media + fr550_msft_odd") 1075 1076;; MCLRACC with A=1 can issue to either M0 or M1. 1077(define_insn_reservation "fr550_msft_2_either" 2 1078 (and (eq_attr "cpu" "fr550") 1079 (eq_attr "type" "mclracca")) 1080 "fr550_media + fr550_msft_either") 1081 1082;; These insns write to ACC0-3. 1083(define_insn_reservation "fr550_msft_2_even" 2 1084 (and (eq_attr "cpu" "fr550") 1085 (and (eq_attr "type" "mclracc,mwtacc") 1086 (eq_attr "acc_group" "even"))) 1087 "fr550_media + fr550_msft_even") 1088 1089;; These insns write to ACC4-7. 1090(define_insn_reservation "fr550_msft_2_odd" 2 1091 (and (eq_attr "cpu" "fr550") 1092 (and (eq_attr "type" "mclracc,mwtacc") 1093 (eq_attr "acc_group" "odd"))) 1094 "fr550_media + fr550_msft_odd") 1095 1096;; These insns read from and write to ACC0-3. 1097(define_insn_reservation "fr550_mmac_even" 2 1098 (and (eq_attr "cpu" "fr550") 1099 (and (eq_attr "type" "mmulh,mmulxh,mmach,mmrdh,mqmulh,mqmulxh,mqmach, 1100 maddacc,mdaddacc,mcpx,mqcpx") 1101 (eq_attr "acc_group" "even"))) 1102 "fr550_media + fr550_mmac_even") 1103 1104;; These insns read from and write to ACC4-7. 1105(define_insn_reservation "fr550_mmac_odd" 2 1106 (and (eq_attr "cpu" "fr550") 1107 (and (eq_attr "type" "mmulh,mmulxh,mmach,mmrdh,mqmulh,mqmulxh,mqmach, 1108 maddacc,mdaddacc,mcpx,mqcpx") 1109 (eq_attr "acc_group" "odd"))) 1110 "fr550_media + fr550_mmac_odd") 1111 1112(define_insn_reservation "fr550_mset" 1 1113 (and (eq_attr "cpu" "fr550") 1114 (eq_attr "type" "mset")) 1115 "fr550_media + fr550_mset") 1116 1117;; :::::::::::::::::::: 1118;; :: 1119;; :: Simple/FR300 scheduler description 1120;; :: 1121;; :::::::::::::::::::: 1122 1123;; Fr300 or simple processor. To describe it as 1 insn issue 1124;; processor, we use control unit. 1125 1126(define_insn_reservation "fr300_lat1" 1 1127 (and (eq_attr "cpu" "fr300,simple") 1128 (eq_attr "type" "!gload,fload,movfg,movgf")) 1129 "c + control") 1130 1131(define_insn_reservation "fr300_lat2" 2 1132 (and (eq_attr "cpu" "fr300,simple") 1133 (eq_attr "type" "gload,fload,movfg,movgf")) 1134 "c + control") 1135 1136 1137;; :::::::::::::::::::: 1138;; :: 1139;; :: Delay Slots 1140;; :: 1141;; :::::::::::::::::::: 1142 1143;; The insn attribute mechanism can be used to specify the requirements for 1144;; delay slots, if any, on a target machine. An instruction is said to require 1145;; a "delay slot" if some instructions that are physically after the 1146;; instruction are executed as if they were located before it. Classic 1147;; examples are branch and call instructions, which often execute the following 1148;; instruction before the branch or call is performed. 1149 1150;; On some machines, conditional branch instructions can optionally "annul" 1151;; instructions in the delay slot. This means that the instruction will not be 1152;; executed for certain branch outcomes. Both instructions that annul if the 1153;; branch is true and instructions that annul if the branch is false are 1154;; supported. 1155 1156;; Delay slot scheduling differs from instruction scheduling in that 1157;; determining whether an instruction needs a delay slot is dependent only 1158;; on the type of instruction being generated, not on data flow between the 1159;; instructions. See the next section for a discussion of data-dependent 1160;; instruction scheduling. 1161 1162;; The requirement of an insn needing one or more delay slots is indicated via 1163;; the `define_delay' expression. It has the following form: 1164;; 1165;; (define_delay TEST 1166;; [DELAY-1 ANNUL-TRUE-1 ANNUL-FALSE-1 1167;; DELAY-2 ANNUL-TRUE-2 ANNUL-FALSE-2 1168;; ...]) 1169 1170;; TEST is an attribute test that indicates whether this `define_delay' applies 1171;; to a particular insn. If so, the number of required delay slots is 1172;; determined by the length of the vector specified as the second argument. An 1173;; insn placed in delay slot N must satisfy attribute test DELAY-N. 1174;; ANNUL-TRUE-N is an attribute test that specifies which insns may be annulled 1175;; if the branch is true. Similarly, ANNUL-FALSE-N specifies which insns in 1176;; the delay slot may be annulled if the branch is false. If annulling is not 1177;; supported for that delay slot, `(nil)' should be coded. 1178 1179;; For example, in the common case where branch and call insns require a single 1180;; delay slot, which may contain any insn other than a branch or call, the 1181;; following would be placed in the `md' file: 1182 1183;; (define_delay (eq_attr "type" "branch,call") 1184;; [(eq_attr "type" "!branch,call") (nil) (nil)]) 1185 1186;; Multiple `define_delay' expressions may be specified. In this case, each 1187;; such expression specifies different delay slot requirements and there must 1188;; be no insn for which tests in two `define_delay' expressions are both true. 1189 1190;; For example, if we have a machine that requires one delay slot for branches 1191;; but two for calls, no delay slot can contain a branch or call insn, and any 1192;; valid insn in the delay slot for the branch can be annulled if the branch is 1193;; true, we might represent this as follows: 1194 1195;; (define_delay (eq_attr "type" "branch") 1196;; [(eq_attr "type" "!branch,call") 1197;; (eq_attr "type" "!branch,call") 1198;; (nil)]) 1199;; 1200;; (define_delay (eq_attr "type" "call") 1201;; [(eq_attr "type" "!branch,call") (nil) (nil) 1202;; (eq_attr "type" "!branch,call") (nil) (nil)]) 1203 1204;; Note - it is the backend's responsibility to fill any unfilled delay slots 1205;; at assembler generation time. This is usually done by adding a special print 1206;; operand to the delayed instruction, and then in the PRINT_OPERAND function 1207;; calling dbr_sequence_length() to determine how many delay slots were filled. 1208;; For example: 1209;; 1210;; --------------<machine>.md----------------- 1211;; (define_insn "call" 1212;; [(call (match_operand 0 "memory_operand" "m") 1213;; (match_operand 1 "" ""))] 1214;; "" 1215;; "call_delayed %0,%1,%2%#" 1216;; [(set_attr "length" "4") 1217;; (set_attr "type" "call")]) 1218;; 1219;; -------------<machine>.h------------------- 1220;; #define PRINT_OPERAND_PUNCT_VALID_P(CODE) (CODE == '#') 1221;; 1222;; ------------<machine>.c------------------ 1223;; void 1224;; machine_print_operand (file, x, code) 1225;; FILE * file; 1226;; rtx x; 1227;; int code; 1228;; { 1229;; switch (code) 1230;; { 1231;; case '#': 1232;; if (dbr_sequence_length () == 0) 1233;; fputs ("\n\tnop", file); 1234;; return; 1235 1236;; :::::::::::::::::::: 1237;; :: 1238;; :: Notes on Patterns 1239;; :: 1240;; :::::::::::::::::::: 1241 1242;; If you need to construct a sequence of assembler instructions in order 1243;; to implement a pattern be sure to escape any backslashes and double quotes 1244;; that you use, e.g.: 1245;; 1246;; (define_insn "an example" 1247;; [(some rtl)] 1248;; "" 1249;; "* 1250;; { static char buffer [100]; 1251;; sprintf (buffer, \"insn \\t %d\", REGNO (operands[1])); 1252;; return buffer; 1253;; }" 1254;; ) 1255;; 1256;; Also if there is more than one instruction, they can be separated by \\; 1257;; which is a space saving synonym for \\n\\t: 1258;; 1259;; (define_insn "another example" 1260;; [(some rtl)] 1261;; "" 1262;; "* 1263;; { static char buffer [100]; 1264;; sprintf (buffer, \"insn1 \\t %d\\;insn2 \\t %%1\", 1265;; REGNO (operands[1])); 1266;; return buffer; 1267;; }" 1268;; ) 1269;; 1270 1271(include "predicates.md") 1272(include "constraints.md") 1273 1274;; :::::::::::::::::::: 1275;; :: 1276;; :: Moves 1277;; :: 1278;; :::::::::::::::::::: 1279 1280;; Wrap moves in define_expand to prevent memory->memory moves from being 1281;; generated at the RTL level, which generates better code for most machines 1282;; which can't do mem->mem moves. 1283 1284;; If operand 0 is a `subreg' with mode M of a register whose own mode is wider 1285;; than M, the effect of this instruction is to store the specified value in 1286;; the part of the register that corresponds to mode M. The effect on the rest 1287;; of the register is undefined. 1288 1289;; This class of patterns is special in several ways. First of all, each of 1290;; these names *must* be defined, because there is no other way to copy a datum 1291;; from one place to another. 1292 1293;; Second, these patterns are not used solely in the RTL generation pass. Even 1294;; the reload pass can generate move insns to copy values from stack slots into 1295;; temporary registers. When it does so, one of the operands is a hard 1296;; register and the other is an operand that can need to be reloaded into a 1297;; register. 1298 1299;; Therefore, when given such a pair of operands, the pattern must 1300;; generate RTL which needs no reloading and needs no temporary 1301;; registers--no registers other than the operands. For example, if 1302;; you support the pattern with a `define_expand', then in such a 1303;; case the `define_expand' mustn't call `force_reg' or any other such 1304;; function which might generate new pseudo registers. 1305 1306;; This requirement exists even for subword modes on a RISC machine 1307;; where fetching those modes from memory normally requires several 1308;; insns and some temporary registers. Look in `spur.md' to see how 1309;; the requirement can be satisfied. 1310 1311;; During reload a memory reference with an invalid address may be passed as an 1312;; operand. Such an address will be replaced with a valid address later in the 1313;; reload pass. In this case, nothing may be done with the address except to 1314;; use it as it stands. If it is copied, it will not be replaced with a valid 1315;; address. No attempt should be made to make such an address into a valid 1316;; address and no routine (such as `change_address') that will do so may be 1317;; called. Note that `general_operand' will fail when applied to such an 1318;; address. 1319;; 1320;; The global variable `reload_in_progress' (which must be explicitly declared 1321;; if required) can be used to determine whether such special handling is 1322;; required. 1323;; 1324;; The variety of operands that have reloads depends on the rest of 1325;; the machine description, but typically on a RISC machine these can 1326;; only be pseudo registers that did not get hard registers, while on 1327;; other machines explicit memory references will get optional 1328;; reloads. 1329;; 1330;; If a scratch register is required to move an object to or from memory, it 1331;; can be allocated using `gen_reg_rtx' prior to reload. But this is 1332;; impossible during and after reload. If there are cases needing scratch 1333;; registers after reload, you must define `SECONDARY_INPUT_RELOAD_CLASS' and 1334;; perhaps also `SECONDARY_OUTPUT_RELOAD_CLASS' to detect them, and provide 1335;; patterns `reload_inM' or `reload_outM' to handle them. 1336 1337;; The constraints on a `moveM' must permit moving any hard register to any 1338;; other hard register provided that `TARGET_HARD_REGNO_MODE_OK' permits 1339;; mode M in both registers and `REGISTER_MOVE_COST' applied to their 1340;; classes returns a value of 2. 1341 1342;; It is obligatory to support floating point `moveM' instructions 1343;; into and out of any registers that can hold fixed point values, 1344;; because unions and structures (which have modes `SImode' or 1345;; `DImode') can be in those registers and they may have floating 1346;; point members. 1347 1348;; There may also be a need to support fixed point `moveM' instructions 1349;; in and out of floating point registers. Unfortunately, I have 1350;; forgotten why this was so, and I don't know whether it is still true. 1351;; If `TARGET_HARD_REGNO_MODE_OK' rejects fixed point values in floating 1352;; point registers, then the constraints of the fixed point `moveM' 1353;; instructions must be designed to avoid ever trying to reload into a 1354;; floating point register. 1355 1356(define_expand "movqi" 1357 [(set (match_operand:QI 0 "general_operand" "") 1358 (match_operand:QI 1 "general_operand" ""))] 1359 "" 1360 "{ frv_emit_move (QImode, operands[0], operands[1]); DONE; }") 1361 1362(define_insn "*movqi_load" 1363 [(set (match_operand:QI 0 "register_operand" "=d,f") 1364 (match_operand:QI 1 "frv_load_operand" "m,m"))] 1365 "" 1366 "* return output_move_single (operands, insn);" 1367 [(set_attr "length" "4") 1368 (set_attr "type" "gload,fload")]) 1369 1370(define_insn "*movqi_internal" 1371 [(set (match_operand:QI 0 "move_destination_operand" "=d,d,m,m,?f,?f,?d,?m,f,d,f") 1372 (match_operand:QI 1 "move_source_operand" "L,d,d,O, d, f, f, f,GO,!m,!m"))] 1373 "register_operand(operands[0], QImode) || reg_or_0_operand (operands[1], QImode)" 1374 "* return output_move_single (operands, insn);" 1375 [(set_attr "length" "4") 1376 (set_attr "type" "int,int,gstore,gstore,movgf,fsconv,movfg,fstore,movgf,gload,fload")]) 1377 1378(define_expand "movhi" 1379 [(set (match_operand:HI 0 "general_operand" "") 1380 (match_operand:HI 1 "general_operand" ""))] 1381 "" 1382 "{ frv_emit_move (HImode, operands[0], operands[1]); DONE; }") 1383 1384(define_insn "*movhi_load" 1385 [(set (match_operand:HI 0 "register_operand" "=d,f") 1386 (match_operand:HI 1 "frv_load_operand" "m,m"))] 1387 "" 1388 "* return output_move_single (operands, insn);" 1389 [(set_attr "length" "4") 1390 (set_attr "type" "gload,fload")]) 1391 1392(define_insn "*movhi_internal" 1393 [(set (match_operand:HI 0 "move_destination_operand" "=d,d,d,m,m,?f,?f,?d,?m,f,d,f") 1394 (match_operand:HI 1 "move_source_operand" "L,n,d,d,O, d, f, f, f,GO,!m,!m"))] 1395 "register_operand(operands[0], HImode) || reg_or_0_operand (operands[1], HImode)" 1396 "* return output_move_single (operands, insn);" 1397 [(set_attr "length" "4,8,4,4,4,4,4,4,4,4,4,4") 1398 (set_attr "type" "int,multi,int,gstore,gstore,movgf,fsconv,movfg,fstore,movgf,gload,fload")]) 1399 1400;; Split 2 word load of constants into sethi/setlo instructions 1401(define_split 1402 [(set (match_operand:HI 0 "integer_register_operand" "") 1403 (match_operand:HI 1 "int_2word_operand" ""))] 1404 "reload_completed" 1405 [(set (match_dup 0) 1406 (high:HI (match_dup 1))) 1407 (set (match_dup 0) 1408 (lo_sum:HI (match_dup 0) 1409 (match_dup 1)))] 1410 "") 1411 1412(define_insn "movhi_high" 1413 [(set (match_operand:HI 0 "integer_register_operand" "=d") 1414 (high:HI (match_operand:HI 1 "int_2word_operand" "i")))] 1415 "" 1416 "sethi #hi(%1), %0" 1417 [(set_attr "type" "sethi") 1418 (set_attr "length" "4")]) 1419 1420(define_insn "movhi_lo_sum" 1421 [(set (match_operand:HI 0 "integer_register_operand" "+d") 1422 (lo_sum:HI (match_dup 0) 1423 (match_operand:HI 1 "int_2word_operand" "i")))] 1424 "" 1425 "setlo #lo(%1), %0" 1426 [(set_attr "type" "setlo") 1427 (set_attr "length" "4")]) 1428 1429(define_expand "movsi" 1430 [(set (match_operand:SI 0 "move_destination_operand" "") 1431 (match_operand:SI 1 "move_source_operand" ""))] 1432 "" 1433 "{ frv_emit_move (SImode, operands[0], operands[1]); DONE; }") 1434 1435;; Note - it is best to only have one movsi pattern and to handle 1436;; all the various contingencies by the use of alternatives. This 1437;; allows reload the greatest amount of flexibility (since reload will 1438;; only choose amongst alternatives for a selected insn, it will not 1439;; replace the insn with another one). 1440 1441;; Unfortunately, we do have to separate out load-type moves from the rest, 1442;; and only allow memory source operands in the former. If we do memory and 1443;; constant loads in a single pattern, reload will be tempted to force 1444;; constants into memory when the destination is a floating-point register. 1445;; That may make a function use a PIC pointer when it didn't before, and we 1446;; cannot change PIC usage (and hence stack layout) so late in the game. 1447;; The resulting sequences for loading constants into FPRs are preferable 1448;; even when we're not generating PIC code. 1449 1450;; However, if we don't accept input from memory at all in the generic 1451;; movsi pattern, reloads for asm instructions that reference pseudos 1452;; that end up assigned to memory will fail to match, because we 1453;; recognize them right after they're emitted, and we don't 1454;; re-recognize them again after the substitution for memory. So keep 1455;; a memory constraint available, just make sure reload won't be 1456;; tempted to use it. 1457;; 1458 1459 1460(define_insn "*movsi_load" 1461 [(set (match_operand:SI 0 "register_operand" "=d,f") 1462 (match_operand:SI 1 "frv_load_operand" "m,m"))] 1463 "" 1464 "* return output_move_single (operands, insn);" 1465 [(set_attr "length" "4") 1466 (set_attr "type" "gload,fload")]) 1467 1468(define_insn "*movsi_got" 1469 [(set (match_operand:SI 0 "integer_register_operand" "=d") 1470 (match_operand:SI 1 "got12_operand" ""))] 1471 "" 1472 "addi gr0, %1, %0" 1473 [(set_attr "type" "int") 1474 (set_attr "length" "4")]) 1475 1476(define_insn "*movsi_high_got" 1477 [(set (match_operand:SI 0 "integer_register_operand" "=d") 1478 (high:SI (match_operand:SI 1 "const_unspec_operand" "")))] 1479 "" 1480 "sethi %1, %0" 1481 [(set_attr "type" "sethi") 1482 (set_attr "length" "4")]) 1483 1484(define_insn "*movsi_lo_sum_got" 1485 [(set (match_operand:SI 0 "integer_register_operand" "=d") 1486 (lo_sum:SI (match_operand:SI 1 "integer_register_operand" "0") 1487 (match_operand:SI 2 "const_unspec_operand" "")))] 1488 "" 1489 "setlo %2, %0" 1490 [(set_attr "type" "setlo") 1491 (set_attr "length" "4")]) 1492 1493(define_insn "*movsi_internal" 1494 [(set (match_operand:SI 0 "move_destination_operand" "=d,d,d,m,m,z,d,d,f,f,m,?f,?z,d,f") 1495 (match_operand:SI 1 "move_source_operand" "L,n,d,d,O,d,z,f,d,f,f,GO,GO,!m,!m"))] 1496 "register_operand (operands[0], SImode) || reg_or_0_operand (operands[1], SImode)" 1497 "* return output_move_single (operands, insn);" 1498 [(set_attr "length" "4,8,4,4,4,4,4,4,4,4,4,4,4,4,4") 1499 (set_attr "type" "int,multi,int,gstore,gstore,spr,spr,movfg,movgf,fsconv,fstore,movgf,spr,gload,fload")]) 1500 1501;; Split 2 word load of constants into sethi/setlo instructions 1502(define_insn_and_split "*movsi_2word" 1503 [(set (match_operand:SI 0 "integer_register_operand" "=d") 1504 (match_operand:SI 1 "int_2word_operand" "i"))] 1505 "" 1506 "#" 1507 "reload_completed" 1508 [(set (match_dup 0) 1509 (high:SI (match_dup 1))) 1510 (set (match_dup 0) 1511 (lo_sum:SI (match_dup 0) 1512 (match_dup 1)))] 1513 "" 1514 [(set_attr "length" "8") 1515 (set_attr "type" "multi")]) 1516 1517(define_insn "movsi_high" 1518 [(set (match_operand:SI 0 "integer_register_operand" "=d") 1519 (high:SI (match_operand:SI 1 "int_2word_operand" "i")))] 1520 "" 1521 "sethi #hi(%1), %0" 1522 [(set_attr "type" "sethi") 1523 (set_attr "length" "4")]) 1524 1525(define_insn "movsi_lo_sum" 1526 [(set (match_operand:SI 0 "integer_register_operand" "+d") 1527 (lo_sum:SI (match_dup 0) 1528 (match_operand:SI 1 "int_2word_operand" "i")))] 1529 "" 1530 "setlo #lo(%1), %0" 1531 [(set_attr "type" "setlo") 1532 (set_attr "length" "4")]) 1533 1534(define_expand "movdi" 1535 [(set (match_operand:DI 0 "nonimmediate_operand" "") 1536 (match_operand:DI 1 "general_operand" ""))] 1537 "" 1538 "{ frv_emit_move (DImode, operands[0], operands[1]); DONE; }") 1539 1540(define_insn "*movdi_double" 1541 [(set (match_operand:DI 0 "move_destination_operand" "=e,?h,??d,??f,R,?R,??m,??m,e,?h,??d,??f,?e,??d,?h,??f,R,m,e,??d,e,??d,?h,??f") 1542 (match_operand:DI 1 "move_source_operand" " e,h,d,f,e,h,d,f,R,R,m,m,h,f,e,d,GO,GO,GO,GO,nF,nF,GO,GO"))] 1543 "TARGET_DOUBLE 1544 && (register_operand (operands[0], DImode) 1545 || reg_or_0_operand (operands[1], DImode))" 1546 "* return output_move_double (operands, insn);" 1547 [(set_attr "length" "8,4,8,8,4,4,8,8,4,4,8,8,4,8,4,8,4,8,8,8,16,16,8,8") 1548 (set_attr "type" "multi,fdconv,multi,multi,gstore,fstore,gstore,fstore,gload,fload,gload,fload,movfg,movfg,movgf,movgf,gstore,gstore,multi,multi,multi,multi,movgf,movgf")]) 1549 1550(define_insn "*movdi_nodouble" 1551 [(set (match_operand:DI 0 "move_destination_operand" "=e,?h,??d,??f,R,?R,??m,??m,e,?h,??d,??f,?e,??d,?h,??f,R,m,e,??d,e,??d,?h,??f") 1552 (match_operand:DI 1 "move_source_operand" " e,h,d,f,e,h,d,f,R,R,m,m,h,f,e,d,GO,GO,GO,GO,nF,nF,GO,GO"))] 1553 "!TARGET_DOUBLE 1554 && (register_operand (operands[0], DImode) 1555 || reg_or_0_operand (operands[1], DImode))" 1556 "* return output_move_double (operands, insn);" 1557 [(set_attr "length" "8,8,8,8,4,4,8,8,4,4,8,8,8,8,8,8,4,8,8,8,16,16,8,8") 1558 (set_attr "type" "multi,multi,multi,multi,gstore,fstore,gstore,fstore,gload,fload,gload,fload,movfg,movfg,movgf,movgf,gstore,gstore,multi,multi,multi,multi,movgf,movgf")]) 1559 1560(define_split 1561 [(set (match_operand:DI 0 "register_operand" "") 1562 (match_operand:DI 1 "dbl_memory_two_insn_operand" ""))] 1563 "reload_completed" 1564 [(const_int 0)] 1565 "frv_split_double_load (operands[0], operands[1]);") 1566 1567(define_split 1568 [(set (match_operand:DI 0 "odd_reg_operand" "") 1569 (match_operand:DI 1 "memory_operand" ""))] 1570 "reload_completed" 1571 [(const_int 0)] 1572 "frv_split_double_load (operands[0], operands[1]);") 1573 1574(define_split 1575 [(set (match_operand:DI 0 "dbl_memory_two_insn_operand" "") 1576 (match_operand:DI 1 "reg_or_0_operand" ""))] 1577 "reload_completed" 1578 [(const_int 0)] 1579 "frv_split_double_store (operands[0], operands[1]);") 1580 1581(define_split 1582 [(set (match_operand:DI 0 "memory_operand" "") 1583 (match_operand:DI 1 "odd_reg_operand" ""))] 1584 "reload_completed" 1585 [(const_int 0)] 1586 "frv_split_double_store (operands[0], operands[1]);") 1587 1588(define_split 1589 [(set (match_operand:DI 0 "register_operand" "") 1590 (match_operand:DI 1 "register_operand" ""))] 1591 "reload_completed 1592 && (odd_reg_operand (operands[0], DImode) 1593 || odd_reg_operand (operands[1], DImode) 1594 || (integer_register_operand (operands[0], DImode) 1595 && integer_register_operand (operands[1], DImode)) 1596 || (!TARGET_DOUBLE 1597 && fpr_operand (operands[0], DImode) 1598 && fpr_operand (operands[1], DImode)))" 1599 [(set (match_dup 2) (match_dup 4)) 1600 (set (match_dup 3) (match_dup 5))] 1601 " 1602{ 1603 rtx op0 = operands[0]; 1604 rtx op0_low = gen_lowpart (SImode, op0); 1605 rtx op0_high = gen_highpart (SImode, op0); 1606 rtx op1 = operands[1]; 1607 rtx op1_low = gen_lowpart (SImode, op1); 1608 rtx op1_high = gen_highpart (SImode, op1); 1609 1610 /* We normally copy the low-numbered register first. However, if the first 1611 register operand 0 is the same as the second register of operand 1, we 1612 must copy in the opposite order. */ 1613 1614 if (REGNO (op0_high) == REGNO (op1_low)) 1615 { 1616 operands[2] = op0_low; 1617 operands[3] = op0_high; 1618 operands[4] = op1_low; 1619 operands[5] = op1_high; 1620 } 1621 else 1622 { 1623 operands[2] = op0_high; 1624 operands[3] = op0_low; 1625 operands[4] = op1_high; 1626 operands[5] = op1_low; 1627 } 1628}") 1629 1630(define_split 1631 [(set (match_operand:DI 0 "register_operand" "") 1632 (match_operand:DI 1 "const_int_operand" ""))] 1633 "reload_completed" 1634 [(set (match_dup 2) (match_dup 4)) 1635 (set (match_dup 3) (match_dup 5))] 1636 " 1637{ 1638 rtx op0 = operands[0]; 1639 rtx op1 = operands[1]; 1640 1641 operands[2] = gen_highpart (SImode, op0); 1642 operands[3] = gen_lowpart (SImode, op0); 1643 if (HOST_BITS_PER_WIDE_INT <= 32) 1644 { 1645 operands[4] = GEN_INT ((INTVAL (op1) < 0) ? -1 : 0); 1646 operands[5] = op1; 1647 } 1648 else 1649 { 1650 operands[4] = gen_int_mode ((INTVAL (op1) >> 16) >> 16, SImode); 1651 operands[5] = gen_int_mode (INTVAL (op1), SImode); 1652 } 1653}") 1654 1655(define_split 1656 [(set (match_operand:DI 0 "register_operand" "") 1657 (match_operand:DI 1 "const_double_operand" ""))] 1658 "reload_completed" 1659 [(set (match_dup 2) (match_dup 4)) 1660 (set (match_dup 3) (match_dup 5))] 1661 " 1662{ 1663 rtx op0 = operands[0]; 1664 rtx op1 = operands[1]; 1665 1666 operands[2] = gen_highpart (SImode, op0); 1667 operands[3] = gen_lowpart (SImode, op0); 1668 operands[4] = GEN_INT (CONST_DOUBLE_HIGH (op1)); 1669 operands[5] = GEN_INT (CONST_DOUBLE_LOW (op1)); 1670}") 1671 1672;; Floating Point Moves 1673;; 1674;; Note - Patterns for SF mode moves are compulsory, but 1675;; patterns for DF are optional, as GCC can synthesize them. 1676 1677(define_expand "movsf" 1678 [(set (match_operand:SF 0 "general_operand" "") 1679 (match_operand:SF 1 "general_operand" ""))] 1680 "" 1681 "{ frv_emit_move (SFmode, operands[0], operands[1]); DONE; }") 1682 1683(define_split 1684 [(set (match_operand:SF 0 "integer_register_operand" "") 1685 (match_operand:SF 1 "int_2word_operand" ""))] 1686 "reload_completed" 1687 [(set (match_dup 0) 1688 (high:SF (match_dup 1))) 1689 (set (match_dup 0) 1690 (lo_sum:SF (match_dup 0) 1691 (match_dup 1)))] 1692 "") 1693 1694(define_insn "*movsf_load_has_fprs" 1695 [(set (match_operand:SF 0 "register_operand" "=f,d") 1696 (match_operand:SF 1 "frv_load_operand" "m,m"))] 1697 "TARGET_HAS_FPRS" 1698 "* return output_move_single (operands, insn);" 1699 [(set_attr "length" "4") 1700 (set_attr "type" "fload,gload")]) 1701 1702(define_insn "*movsf_internal_has_fprs" 1703 [(set (match_operand:SF 0 "move_destination_operand" "=f,f,m,m,?f,?d,?d,m,?d") 1704 (match_operand:SF 1 "move_source_operand" "f,OG,f,OG,d,f,d,d,F"))] 1705 "TARGET_HAS_FPRS 1706 && (register_operand (operands[0], SFmode) || reg_or_0_operand (operands[1], SFmode))" 1707 "* return output_move_single (operands, insn);" 1708 [(set_attr "length" "4,4,4,4,4,4,4,4,8") 1709 (set_attr "type" "fsconv,movgf,fstore,gstore,movgf,movfg,int,gstore,multi")]) 1710 1711;; If we don't support the double instructions, prefer gprs over fprs, since it 1712;; will all be emulated 1713(define_insn "*movsf_internal_no_fprs" 1714 [(set (match_operand:SF 0 "move_destination_operand" "=d,d,m,d,d") 1715 (match_operand:SF 1 "move_source_operand" " d,OG,dOG,m,F"))] 1716 "!TARGET_HAS_FPRS 1717 && (register_operand (operands[0], SFmode) || reg_or_0_operand (operands[1], SFmode))" 1718 "* return output_move_single (operands, insn);" 1719 [(set_attr "length" "4,4,4,4,8") 1720 (set_attr "type" "int,int,gstore,gload,multi")]) 1721 1722(define_insn "movsf_high" 1723 [(set (match_operand:SF 0 "integer_register_operand" "=d") 1724 (high:SF (match_operand:SF 1 "int_2word_operand" "i")))] 1725 "" 1726 "sethi #hi(%1), %0" 1727 [(set_attr "type" "sethi") 1728 (set_attr "length" "4")]) 1729 1730(define_insn "movsf_lo_sum" 1731 [(set (match_operand:SF 0 "integer_register_operand" "+d") 1732 (lo_sum:SF (match_dup 0) 1733 (match_operand:SF 1 "int_2word_operand" "i")))] 1734 "" 1735 "setlo #lo(%1), %0" 1736 [(set_attr "type" "setlo") 1737 (set_attr "length" "4")]) 1738 1739(define_expand "movdf" 1740 [(set (match_operand:DF 0 "nonimmediate_operand" "") 1741 (match_operand:DF 1 "general_operand" ""))] 1742 "" 1743 "{ frv_emit_move (DFmode, operands[0], operands[1]); DONE; }") 1744 1745(define_insn "*movdf_double" 1746 [(set (match_operand:DF 0 "move_destination_operand" "=h,?e,??f,??d,R,?R,??m,??m,h,?e,??f,??d,?h,??f,?e,??d,R,m,h,??f,e,??d,e,??d") 1747 (match_operand:DF 1 "move_source_operand" " h,e,f,d,h,e,f,d,R,R,m,m,e,d,h,f,GO,GO,GO,GO,GO,GO,F,F"))] 1748 "TARGET_DOUBLE 1749 && (register_operand (operands[0], DFmode) 1750 || reg_or_0_operand (operands[1], DFmode))" 1751 "* return output_move_double (operands, insn);" 1752 [(set_attr "length" "4,8,8,8,4,4,8,8,4,4,8,8,4,8,4,8,4,8,8,8,8,8,16,16") 1753 (set_attr "type" "fdconv,multi,multi,multi,fstore,gstore,fstore,gstore,fload,gload,fload,gload,movgf,movgf,movfg,movfg,gstore,gstore,movgf,movgf,multi,multi,multi,multi")]) 1754 1755;; If we don't support the double instructions, prefer gprs over fprs, since it 1756;; will all be emulated 1757(define_insn "*movdf_nodouble" 1758 [(set (match_operand:DF 0 "move_destination_operand" "=e,?h,??d,??f,R,?R,??m,??m,e,?h,??d,??f,?e,??d,?h,??f,R,m,e,??d,e,??d,?h,??f") 1759 (match_operand:DF 1 "move_source_operand" " e,h,d,f,e,h,d,f,R,R,m,m,h,f,e,d,GO,GO,GO,GO,nF,nF,GO,GO"))] 1760 "!TARGET_DOUBLE 1761 && (register_operand (operands[0], DFmode) 1762 || reg_or_0_operand (operands[1], DFmode))" 1763 "* return output_move_double (operands, insn);" 1764 [(set_attr "length" "8,8,8,8,4,4,8,8,4,4,8,8,8,8,8,8,4,8,8,8,16,16,8,8") 1765 (set_attr "type" "multi,multi,multi,multi,gstore,fstore,gstore,fstore,gload,fload,gload,fload,movfg,movfg,movgf,movgf,gstore,gstore,multi,multi,multi,multi,movgf,movgf")]) 1766 1767(define_split 1768 [(set (match_operand:DF 0 "register_operand" "") 1769 (match_operand:DF 1 "dbl_memory_two_insn_operand" ""))] 1770 "reload_completed" 1771 [(const_int 0)] 1772 "frv_split_double_load (operands[0], operands[1]);") 1773 1774(define_split 1775 [(set (match_operand:DF 0 "odd_reg_operand" "") 1776 (match_operand:DF 1 "memory_operand" ""))] 1777 "reload_completed" 1778 [(const_int 0)] 1779 "frv_split_double_load (operands[0], operands[1]);") 1780 1781(define_split 1782 [(set (match_operand:DF 0 "dbl_memory_two_insn_operand" "") 1783 (match_operand:DF 1 "reg_or_0_operand" ""))] 1784 "reload_completed" 1785 [(const_int 0)] 1786 "frv_split_double_store (operands[0], operands[1]);") 1787 1788(define_split 1789 [(set (match_operand:DF 0 "memory_operand" "") 1790 (match_operand:DF 1 "odd_reg_operand" ""))] 1791 "reload_completed" 1792 [(const_int 0)] 1793 "frv_split_double_store (operands[0], operands[1]);") 1794 1795(define_split 1796 [(set (match_operand:DF 0 "register_operand" "") 1797 (match_operand:DF 1 "register_operand" ""))] 1798 "reload_completed 1799 && (odd_reg_operand (operands[0], DFmode) 1800 || odd_reg_operand (operands[1], DFmode) 1801 || (integer_register_operand (operands[0], DFmode) 1802 && integer_register_operand (operands[1], DFmode)) 1803 || (!TARGET_DOUBLE 1804 && fpr_operand (operands[0], DFmode) 1805 && fpr_operand (operands[1], DFmode)))" 1806 [(set (match_dup 2) (match_dup 4)) 1807 (set (match_dup 3) (match_dup 5))] 1808 " 1809{ 1810 rtx op0 = operands[0]; 1811 rtx op0_low = gen_lowpart (SImode, op0); 1812 rtx op0_high = gen_highpart (SImode, op0); 1813 rtx op1 = operands[1]; 1814 rtx op1_low = gen_lowpart (SImode, op1); 1815 rtx op1_high = gen_highpart (SImode, op1); 1816 1817 /* We normally copy the low-numbered register first. However, if the first 1818 register operand 0 is the same as the second register of operand 1, we 1819 must copy in the opposite order. */ 1820 1821 if (REGNO (op0_high) == REGNO (op1_low)) 1822 { 1823 operands[2] = op0_low; 1824 operands[3] = op0_high; 1825 operands[4] = op1_low; 1826 operands[5] = op1_high; 1827 } 1828 else 1829 { 1830 operands[2] = op0_high; 1831 operands[3] = op0_low; 1832 operands[4] = op1_high; 1833 operands[5] = op1_low; 1834 } 1835}") 1836 1837(define_split 1838 [(set (match_operand:DF 0 "register_operand" "") 1839 (match_operand:DF 1 "const_int_operand" ""))] 1840 "reload_completed" 1841 [(set (match_dup 2) (match_dup 4)) 1842 (set (match_dup 3) (match_dup 5))] 1843 " 1844{ 1845 rtx op0 = operands[0]; 1846 rtx op1 = operands[1]; 1847 1848 operands[2] = gen_highpart (SImode, op0); 1849 operands[3] = gen_lowpart (SImode, op0); 1850 if (HOST_BITS_PER_WIDE_INT <= 32) 1851 { 1852 operands[4] = GEN_INT ((INTVAL (op1) < 0) ? -1 : 0); 1853 operands[5] = op1; 1854 } 1855 else 1856 { 1857 operands[4] = GEN_INT (((((unsigned HOST_WIDE_INT)INTVAL (op1) >> 16) 1858 >> 16) ^ ((unsigned HOST_WIDE_INT)1 << 31)) 1859 - ((unsigned HOST_WIDE_INT)1 << 31)); 1860 operands[5] = GEN_INT (trunc_int_for_mode (INTVAL (op1), SImode)); 1861 } 1862}") 1863 1864(define_split 1865 [(set (match_operand:DF 0 "register_operand" "") 1866 (match_operand:DF 1 "const_double_operand" ""))] 1867 "reload_completed" 1868 [(set (match_dup 2) (match_dup 4)) 1869 (set (match_dup 3) (match_dup 5))] 1870 " 1871{ 1872 rtx op0 = operands[0]; 1873 rtx op1 = operands[1]; 1874 long l[2]; 1875 1876 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (op1), l); 1877 1878 operands[2] = gen_highpart (SImode, op0); 1879 operands[3] = gen_lowpart (SImode, op0); 1880 operands[4] = GEN_INT (l[0]); 1881 operands[5] = GEN_INT (l[1]); 1882}") 1883 1884;; String/block move insn. 1885;; Argument 0 is the destination 1886;; Argument 1 is the source 1887;; Argument 2 is the length 1888;; Argument 3 is the alignment 1889 1890(define_expand "movmemsi" 1891 [(parallel [(set (match_operand:BLK 0 "" "") 1892 (match_operand:BLK 1 "" "")) 1893 (use (match_operand:SI 2 "" "")) 1894 (use (match_operand:SI 3 "" ""))])] 1895 "" 1896 " 1897{ 1898 if (frv_expand_block_move (operands)) 1899 DONE; 1900 else 1901 FAIL; 1902}") 1903 1904;; String/block set insn. 1905;; Argument 0 is the destination 1906;; Argument 1 is the length 1907;; Argument 2 is the byte value -- ignore any value but zero 1908;; Argument 3 is the alignment 1909 1910(define_expand "setmemsi" 1911 [(parallel [(set (match_operand:BLK 0 "" "") 1912 (match_operand 2 "" "")) 1913 (use (match_operand:SI 1 "" "")) 1914 (use (match_operand:SI 3 "" ""))])] 1915 "" 1916 " 1917{ 1918 /* If value to set is not zero, use the library routine. */ 1919 if (operands[2] != const0_rtx) 1920 FAIL; 1921 1922 if (frv_expand_block_clear (operands)) 1923 DONE; 1924 else 1925 FAIL; 1926}") 1927 1928 1929;; The "membar" part of a __builtin_read* or __builtin_write* function. 1930;; Operand 0 is a volatile reference to the memory that the function reads 1931;; or writes. Operand 1 is the address being accessed, or zero if the 1932;; address isn't a known constant. Operand 2 describes the __builtin 1933;; function (either FRV_IO_READ or FRV_IO_WRITE). 1934(define_insn "optional_membar_<mode>" 1935 [(set (match_operand:IMODE 0 "memory_operand" "=m") 1936 (unspec:IMODE [(match_operand 1 "const_int_operand" "") 1937 (match_operand 2 "const_int_operand" "")] 1938 UNSPEC_OPTIONAL_MEMBAR))] 1939 "" 1940 "membar" 1941 [(set_attr "length" "4")]) 1942 1943;; :::::::::::::::::::: 1944;; :: 1945;; :: Reload CC registers 1946;; :: 1947;; :::::::::::::::::::: 1948 1949;; Use as a define_expand so that cse/gcse/combine can't accidentally 1950;; create movcc insns. 1951 1952(define_expand "movcc" 1953 [(parallel [(set (match_operand:CC 0 "move_destination_operand" "") 1954 (match_operand:CC 1 "move_source_operand" "")) 1955 (clobber (match_dup 2))])] 1956 "" 1957 " 1958{ 1959 if (! reload_in_progress && ! reload_completed) 1960 FAIL; 1961 1962 operands[2] = gen_rtx_REG (CC_CCRmode, ICR_TEMP); 1963}") 1964 1965(define_insn "*internal_movcc" 1966 [(set (match_operand:CC 0 "move_destination_operand" "=t,d,d,m,d") 1967 (match_operand:CC 1 "move_source_operand" "d,d,m,d,t")) 1968 (clobber (match_scratch:CC_CCR 2 "=X,X,X,X,&v"))] 1969 "reload_in_progress || reload_completed" 1970 "@ 1971 cmpi %1, #0, %0 1972 mov %1, %0 1973 ld%I1%U1 %M1, %0 1974 st%I0%U0 %1, %M0 1975 #" 1976 [(set_attr "length" "4,4,4,4,20") 1977 (set_attr "type" "int,int,gload,gstore,multi")]) 1978 1979;; To move an ICC value to a GPR for a signed comparison, we create a value 1980;; that when compared to 0, sets the N and Z flags appropriately (we don't care 1981;; about the V and C flags, since these comparisons are signed). 1982 1983(define_split 1984 [(set (match_operand:CC 0 "integer_register_operand" "") 1985 (match_operand:CC 1 "icc_operand" "")) 1986 (clobber (match_operand:CC_CCR 2 "icr_operand" ""))] 1987 "reload_in_progress || reload_completed" 1988 [(match_dup 3)] 1989 " 1990{ 1991 rtx dest = simplify_gen_subreg (SImode, operands[0], CCmode, 0); 1992 rtx icc = operands[1]; 1993 rtx icr = operands[2]; 1994 1995 start_sequence (); 1996 1997 emit_insn (gen_rtx_SET (icr, gen_rtx_LT (CC_CCRmode, icc, const0_rtx))); 1998 1999 emit_insn (gen_movsi (dest, const1_rtx)); 2000 2001 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 2002 gen_rtx_NE (CC_CCRmode, icr, const0_rtx), 2003 gen_rtx_SET (dest, 2004 gen_rtx_NEG (SImode, dest)))); 2005 2006 emit_insn (gen_rtx_SET (icr, gen_rtx_EQ (CC_CCRmode, icc, const0_rtx))); 2007 2008 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 2009 gen_rtx_NE (CC_CCRmode, icr, const0_rtx), 2010 gen_rtx_SET (dest, const0_rtx))); 2011 2012 operands[3] = get_insns (); 2013 end_sequence (); 2014}") 2015 2016;; Reload CC_UNSmode for unsigned integer comparisons 2017;; Use define_expand so that cse/gcse/combine can't create movcc_uns insns 2018 2019(define_expand "movcc_uns" 2020 [(parallel [(set (match_operand:CC_UNS 0 "move_destination_operand" "") 2021 (match_operand:CC_UNS 1 "move_source_operand" "")) 2022 (clobber (match_dup 2))])] 2023 "" 2024 " 2025{ 2026 if (! reload_in_progress && ! reload_completed) 2027 FAIL; 2028 operands[2] = gen_rtx_REG (CC_CCRmode, ICR_TEMP); 2029}") 2030 2031(define_insn "*internal_movcc_uns" 2032 [(set (match_operand:CC_UNS 0 "move_destination_operand" "=t,d,d,m,d") 2033 (match_operand:CC_UNS 1 "move_source_operand" "d,d,m,d,t")) 2034 (clobber (match_scratch:CC_CCR 2 "=X,X,X,X,&v"))] 2035 "reload_in_progress || reload_completed" 2036 "@ 2037 cmpi %1, #1, %0 2038 mov %1, %0 2039 ld%I1%U1 %M1, %0 2040 st%I0%U0 %1, %M0 2041 #" 2042 [(set_attr "length" "4,4,4,4,20") 2043 (set_attr "type" "int,int,gload,gstore,multi")]) 2044 2045;; To move an ICC value to a GPR for an unsigned comparison, we create a value 2046;; that when compared to 1, sets the Z, V, and C flags appropriately (we don't 2047;; care about the N flag, since these comparisons are unsigned). 2048 2049(define_split 2050 [(set (match_operand:CC_UNS 0 "integer_register_operand" "") 2051 (match_operand:CC_UNS 1 "icc_operand" "")) 2052 (clobber (match_operand:CC_CCR 2 "icr_operand" ""))] 2053 "reload_in_progress || reload_completed" 2054 [(match_dup 3)] 2055 " 2056{ 2057 rtx dest = simplify_gen_subreg (SImode, operands[0], CC_UNSmode, 0); 2058 rtx icc = operands[1]; 2059 rtx icr = operands[2]; 2060 2061 start_sequence (); 2062 2063 emit_insn (gen_rtx_SET (icr, gen_rtx_GTU (CC_CCRmode, icc, const0_rtx))); 2064 2065 emit_insn (gen_movsi (dest, const1_rtx)); 2066 2067 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 2068 gen_rtx_NE (CC_CCRmode, icr, const0_rtx), 2069 gen_addsi3 (dest, dest, dest))); 2070 2071 emit_insn (gen_rtx_SET (icr, gen_rtx_LTU (CC_CCRmode, icc, const0_rtx))); 2072 2073 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 2074 gen_rtx_NE (CC_CCRmode, icr, const0_rtx), 2075 gen_rtx_SET (dest, const0_rtx))); 2076 2077 operands[3] = get_insns (); 2078 end_sequence (); 2079}") 2080 2081;; Reload CC_NZmode. This is mostly the same as the CCmode and CC_UNSmode 2082;; handling, but it uses different sequences for moving between GPRs and ICCs. 2083 2084(define_expand "movcc_nz" 2085 [(parallel [(set (match_operand:CC_NZ 0 "move_destination_operand" "") 2086 (match_operand:CC_NZ 1 "move_source_operand" "")) 2087 (clobber (match_dup 2))])] 2088 "" 2089 " 2090{ 2091 if (!reload_in_progress && !reload_completed) 2092 FAIL; 2093 operands[2] = gen_rtx_REG (CC_CCRmode, ICR_TEMP); 2094}") 2095 2096(define_insn "*internal_movcc_nz" 2097 [(set (match_operand:CC_NZ 0 "move_destination_operand" "=t,d,d,m,d") 2098 (match_operand:CC_NZ 1 "move_source_operand" "d,d,m,d,t")) 2099 (clobber (match_scratch:CC_CCR 2 "=X,X,X,X,&v"))] 2100 "reload_in_progress || reload_completed" 2101 "@ 2102 cmpi %1, #0, %0 2103 mov %1, %0 2104 ld%I1%U1 %M1, %0 2105 st%I0%U0 %1, %M0 2106 #" 2107 [(set_attr "length" "4,4,4,4,20") 2108 (set_attr "type" "int,int,gload,gstore,multi")]) 2109 2110;; Set the destination to a value that, when compared with zero, will 2111;; restore the value of the Z and N flags. The values of the other 2112;; flags don't matter. The sequence is: 2113;; 2114;; setlos op0,#-1 2115;; ckp op1,op2 2116;; csub gr0,op0,op0,op2 2117;; ckeq op1,op2 2118;; cmov gr0,op0,op2 2119(define_split 2120 [(set (match_operand:CC_NZ 0 "integer_register_operand" "") 2121 (match_operand:CC_NZ 1 "icc_operand" "")) 2122 (clobber (match_operand:CC_CCR 2 "icr_operand" ""))] 2123 "reload_in_progress || reload_completed" 2124 [(set (match_dup 3) 2125 (const_int -1)) 2126 (set (match_dup 2) 2127 (ge:CC_CCR (match_dup 1) 2128 (const_int 0))) 2129 (cond_exec (ne:CC_CCR (match_dup 2) 2130 (const_int 0)) 2131 (set (match_dup 3) 2132 (neg:SI (match_dup 3)))) 2133 (set (match_dup 2) 2134 (eq:CC_CCR (match_dup 1) 2135 (const_int 0))) 2136 (cond_exec (ne:CC_CCR (match_dup 2) 2137 (const_int 0)) 2138 (set (match_dup 3) (const_int 0)))] 2139 "operands[3] = simplify_gen_subreg (SImode, operands[0], CC_NZmode, 0);") 2140 2141;; Reload CC_FPmode for floating point comparisons 2142;; We use a define_expand here so that cse/gcse/combine can't accidentally 2143;; create movcc insns. If this was a named define_insn, we would not be able 2144;; to make it conditional on reload. 2145 2146(define_expand "movcc_fp" 2147 [(set (match_operand:CC_FP 0 "movcc_fp_destination_operand" "") 2148 (match_operand:CC_FP 1 "move_source_operand" ""))] 2149 "TARGET_HAS_FPRS" 2150 " 2151{ 2152 if (! reload_in_progress && ! reload_completed) 2153 FAIL; 2154}") 2155 2156(define_insn "*movcc_fp_internal" 2157 [(set (match_operand:CC_FP 0 "movcc_fp_destination_operand" "=d,d,d,m") 2158 (match_operand:CC_FP 1 "move_source_operand" "u,d,m,d"))] 2159 "TARGET_HAS_FPRS && (reload_in_progress || reload_completed)" 2160 "@ 2161 # 2162 mov %1, %0 2163 ld%I1%U1 %M1, %0 2164 st%I0%U0 %1, %M0" 2165 [(set_attr "length" "12,4,4,4") 2166 (set_attr "type" "multi,int,gload,gstore")]) 2167 2168 2169(define_expand "reload_incc_fp" 2170 [(match_operand:CC_FP 0 "fcc_operand" "=u") 2171 (match_operand:CC_FP 1 "gpr_or_memory_operand_with_scratch" "m") 2172 (match_operand:TI 2 "integer_register_operand" "=&d")] 2173 "TARGET_HAS_FPRS" 2174 " 2175{ 2176 rtx cc_op2 = simplify_gen_subreg (CC_FPmode, operands[2], TImode, 0); 2177 rtx int_op2 = simplify_gen_subreg (SImode, operands[2], TImode, 0); 2178 rtx temp1 = simplify_gen_subreg (SImode, operands[2], TImode, 4); 2179 rtx temp2 = simplify_gen_subreg (SImode, operands[2], TImode, 8); 2180 int shift = CC_SHIFT_RIGHT (REGNO (operands[0])); 2181 HOST_WIDE_INT mask; 2182 2183 if (!gpr_or_memory_operand (operands[1], CC_FPmode)) 2184 { 2185 rtx addr; 2186 rtx temp3 = simplify_gen_subreg (SImode, operands[2], TImode, 12); 2187 2188 gcc_assert (GET_CODE (operands[1]) == MEM); 2189 2190 addr = XEXP (operands[1], 0); 2191 2192 gcc_assert (GET_CODE (addr) == PLUS); 2193 2194 emit_move_insn (temp3, XEXP (addr, 1)); 2195 2196 operands[1] = replace_equiv_address (operands[1], 2197 gen_rtx_PLUS (GET_MODE (addr), 2198 XEXP (addr, 0), 2199 temp3)); 2200 } 2201 2202 emit_insn (gen_movcc_fp (cc_op2, operands[1])); 2203 if (shift) 2204 emit_insn (gen_ashlsi3 (int_op2, int_op2, GEN_INT (shift))); 2205 2206 mask = ~ ((HOST_WIDE_INT)CC_MASK << shift); 2207 emit_insn (gen_movsi (temp1, GEN_INT (mask))); 2208 emit_insn (gen_update_fcc (operands[0], int_op2, temp1, temp2)); 2209 DONE; 2210}") 2211 2212(define_expand "reload_outcc_fp" 2213 [(set (match_operand:CC_FP 2 "integer_register_operand" "=&d") 2214 (match_operand:CC_FP 1 "fcc_operand" "u")) 2215 (set (match_operand:CC_FP 0 "memory_operand" "=m") 2216 (match_dup 2))] 2217 "TARGET_HAS_FPRS" 2218 "") 2219 2220;; Convert a FCC value to gpr 2221(define_insn "read_fcc" 2222 [(set (match_operand:SI 0 "integer_register_operand" "=d") 2223 (unspec:SI [(match_operand:CC_FP 1 "fcc_operand" "u")] 2224 UNSPEC_CC_TO_GPR))] 2225 "TARGET_HAS_FPRS" 2226 "movsg ccr, %0" 2227 [(set_attr "type" "spr") 2228 (set_attr "length" "4")]) 2229 2230(define_split 2231 [(set (match_operand:CC_FP 0 "integer_register_operand" "") 2232 (match_operand:CC_FP 1 "fcc_operand" ""))] 2233 "reload_completed && TARGET_HAS_FPRS" 2234 [(match_dup 2)] 2235 " 2236{ 2237 rtx int_op0 = simplify_gen_subreg (SImode, operands[0], CC_FPmode, 0); 2238 int shift = CC_SHIFT_RIGHT (REGNO (operands[1])); 2239 2240 start_sequence (); 2241 2242 emit_insn (gen_read_fcc (int_op0, operands[1])); 2243 if (shift) 2244 emit_insn (gen_lshrsi3 (int_op0, int_op0, GEN_INT (shift))); 2245 2246 emit_insn (gen_andsi3 (int_op0, int_op0, GEN_INT (CC_MASK))); 2247 2248 operands[2] = get_insns (); 2249 end_sequence (); 2250}") 2251 2252;; Move a gpr value to FCC. 2253;; Operand0 = FCC 2254;; Operand1 = reloaded value shifted appropriately 2255;; Operand2 = mask to eliminate current register 2256;; Operand3 = temporary to load/store ccr 2257(define_insn "update_fcc" 2258 [(set (match_operand:CC_FP 0 "fcc_operand" "=u") 2259 (unspec:CC_FP [(match_operand:SI 1 "integer_register_operand" "d") 2260 (match_operand:SI 2 "integer_register_operand" "d")] 2261 UNSPEC_GPR_TO_CC)) 2262 (clobber (match_operand:SI 3 "integer_register_operand" "=&d"))] 2263 "TARGET_HAS_FPRS" 2264 "movsg ccr, %3\;and %2, %3, %3\;or %1, %3, %3\;movgs %3, ccr" 2265 [(set_attr "type" "multi") 2266 (set_attr "length" "16")]) 2267 2268;; Reload CC_CCRmode for conditional execution registers 2269(define_insn "movcc_ccr" 2270 [(set (match_operand:CC_CCR 0 "move_destination_operand" "=d,d,d,m,v,?w,C,d") 2271 (match_operand:CC_CCR 1 "move_source_operand" "C,d,m,d,n,n,C,L"))] 2272 "" 2273 "@ 2274 # 2275 mov %1, %0 2276 ld%I1%U1 %M1, %0 2277 st%I0%U0 %1, %M0 2278 # 2279 # 2280 orcr %1, %1, %0 2281 setlos #%1, %0" 2282 [(set_attr "length" "8,4,4,4,8,12,4,4") 2283 (set_attr "type" "multi,int,gload,gstore,multi,multi,ccr,int")]) 2284 2285(define_expand "reload_incc_ccr" 2286 [(match_operand:CC_CCR 0 "cr_operand" "=C") 2287 (match_operand:CC_CCR 1 "memory_operand" "m") 2288 (match_operand:CC_CCR 2 "integer_register_operand" "=&d")] 2289 "" 2290 " 2291{ 2292 rtx icc = gen_rtx_REG (CCmode, ICC_TEMP); 2293 rtx int_op2 = simplify_gen_subreg (SImode, operands[2], CC_CCRmode, 0); 2294 rtx icr = (ICR_P (REGNO (operands[0])) 2295 ? operands[0] : gen_rtx_REG (CC_CCRmode, ICR_TEMP)); 2296 2297 emit_insn (gen_movcc_ccr (operands[2], operands[1])); 2298 emit_insn (gen_cmpsi_cc (icc, int_op2, const0_rtx)); 2299 emit_insn (gen_movcc_ccr (icr, gen_rtx_NE (CC_CCRmode, icc, const0_rtx))); 2300 2301 if (! ICR_P (REGNO (operands[0]))) 2302 emit_insn (gen_movcc_ccr (operands[0], icr)); 2303 2304 DONE; 2305}") 2306 2307(define_expand "reload_outcc_ccr" 2308 [(set (match_operand:CC_CCR 2 "integer_register_operand" "=&d") 2309 (match_operand:CC_CCR 1 "cr_operand" "C")) 2310 (set (match_operand:CC_CCR 0 "memory_operand" "=m") 2311 (match_dup 2))] 2312 "" 2313 "") 2314 2315(define_split 2316 [(set (match_operand:CC_CCR 0 "integer_register_operand" "") 2317 (match_operand:CC_CCR 1 "cr_operand" ""))] 2318 "reload_completed" 2319 [(match_dup 2)] 2320 " 2321{ 2322 rtx int_op0 = simplify_gen_subreg (SImode, operands[0], CC_CCRmode, 0); 2323 2324 start_sequence (); 2325 emit_move_insn (operands[0], const1_rtx); 2326 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 2327 gen_rtx_EQ (CC_CCRmode, 2328 operands[1], 2329 const0_rtx), 2330 gen_rtx_SET (int_op0, const0_rtx))); 2331 2332 operands[2] = get_insns (); 2333 end_sequence (); 2334}") 2335 2336(define_split 2337 [(set (match_operand:CC_CCR 0 "cr_operand" "") 2338 (match_operand:CC_CCR 1 "const_int_operand" ""))] 2339 "reload_completed" 2340 [(match_dup 2)] 2341 " 2342{ 2343 rtx icc = gen_rtx_REG (CCmode, ICC_TEMP); 2344 rtx r0 = gen_rtx_REG (SImode, GPR_FIRST); 2345 rtx icr = (ICR_P (REGNO (operands[0])) 2346 ? operands[0] : gen_rtx_REG (CC_CCRmode, ICR_TEMP)); 2347 2348 start_sequence (); 2349 2350 emit_insn (gen_cmpsi_cc (icc, r0, const0_rtx)); 2351 2352 emit_insn (gen_movcc_ccr (icr, 2353 gen_rtx_fmt_ee (((INTVAL (operands[1]) == 0) 2354 ? EQ : NE), CC_CCRmode, 2355 r0, const0_rtx))); 2356 2357 if (! ICR_P (REGNO (operands[0]))) 2358 emit_insn (gen_movcc_ccr (operands[0], icr)); 2359 2360 operands[2] = get_insns (); 2361 end_sequence (); 2362}") 2363 2364 2365;; :::::::::::::::::::: 2366;; :: 2367;; :: Conversions 2368;; :: 2369;; :::::::::::::::::::: 2370 2371;; Signed conversions from a smaller integer to a larger integer 2372;; 2373;; These operations are optional. If they are not 2374;; present GCC will synthesize them for itself 2375;; Even though frv does not provide these instructions, we define them 2376;; to allow load + sign extend to be collapsed together 2377(define_insn "extendqihi2" 2378 [(set (match_operand:HI 0 "integer_register_operand" "=d,d") 2379 (sign_extend:HI (match_operand:QI 1 "gpr_or_memory_operand" "d,m")))] 2380 "" 2381 "@ 2382 # 2383 ldsb%I1%U1 %M1,%0" 2384 [(set_attr "length" "8,4") 2385 (set_attr "type" "multi,gload")]) 2386 2387(define_split 2388 [(set (match_operand:HI 0 "integer_register_operand" "") 2389 (sign_extend:HI (match_operand:QI 1 "integer_register_operand" "")))] 2390 "reload_completed" 2391 [(match_dup 2) 2392 (match_dup 3)] 2393 " 2394{ 2395 rtx op0 = gen_lowpart (SImode, operands[0]); 2396 rtx op1 = gen_lowpart (SImode, operands[1]); 2397 rtx shift = GEN_INT (24); 2398 2399 operands[2] = gen_ashlsi3 (op0, op1, shift); 2400 operands[3] = gen_ashrsi3 (op0, op0, shift); 2401}") 2402 2403(define_insn "extendqisi2" 2404 [(set (match_operand:SI 0 "integer_register_operand" "=d,d") 2405 (sign_extend:SI (match_operand:QI 1 "gpr_or_memory_operand" "d,m")))] 2406 "" 2407 "@ 2408 # 2409 ldsb%I1%U1 %M1,%0" 2410 [(set_attr "length" "8,4") 2411 (set_attr "type" "multi,gload")]) 2412 2413(define_split 2414 [(set (match_operand:SI 0 "integer_register_operand" "") 2415 (sign_extend:SI (match_operand:QI 1 "integer_register_operand" "")))] 2416 "reload_completed" 2417 [(match_dup 2) 2418 (match_dup 3)] 2419 " 2420{ 2421 rtx op0 = gen_lowpart (SImode, operands[0]); 2422 rtx op1 = gen_lowpart (SImode, operands[1]); 2423 rtx shift = GEN_INT (24); 2424 2425 operands[2] = gen_ashlsi3 (op0, op1, shift); 2426 operands[3] = gen_ashrsi3 (op0, op0, shift); 2427}") 2428 2429;;(define_insn "extendqidi2" 2430;; [(set (match_operand:DI 0 "register_operand" "=r") 2431;; (sign_extend:DI (match_operand:QI 1 "general_operand" "g")))] 2432;; "" 2433;; "extendqihi2 %0,%1" 2434;; [(set_attr "length" "4")]) 2435 2436(define_insn "extendhisi2" 2437 [(set (match_operand:SI 0 "integer_register_operand" "=d,d") 2438 (sign_extend:SI (match_operand:HI 1 "gpr_or_memory_operand" "d,m")))] 2439 "" 2440 "@ 2441 # 2442 ldsh%I1%U1 %M1,%0" 2443 [(set_attr "length" "8,4") 2444 (set_attr "type" "multi,gload")]) 2445 2446(define_split 2447 [(set (match_operand:SI 0 "integer_register_operand" "") 2448 (sign_extend:SI (match_operand:HI 1 "integer_register_operand" "")))] 2449 "reload_completed" 2450 [(match_dup 2) 2451 (match_dup 3)] 2452 " 2453{ 2454 rtx op0 = gen_lowpart (SImode, operands[0]); 2455 rtx op1 = gen_lowpart (SImode, operands[1]); 2456 rtx shift = GEN_INT (16); 2457 2458 operands[2] = gen_ashlsi3 (op0, op1, shift); 2459 operands[3] = gen_ashrsi3 (op0, op0, shift); 2460}") 2461 2462;;(define_insn "extendhidi2" 2463;; [(set (match_operand:DI 0 "register_operand" "=r") 2464;; (sign_extend:DI (match_operand:HI 1 "general_operand" "g")))] 2465;; "" 2466;; "extendhihi2 %0,%1" 2467;; [(set_attr "length" "4")]) 2468;; 2469;;(define_insn "extendsidi2" 2470;; [(set (match_operand:DI 0 "register_operand" "=r") 2471;; (sign_extend:DI (match_operand:SI 1 "general_operand" "g")))] 2472;; "" 2473;; "extendsidi2 %0,%1" 2474;; [(set_attr "length" "4")]) 2475 2476;; Unsigned conversions from a smaller integer to a larger integer 2477(define_insn "zero_extendqihi2" 2478 [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d") 2479 (zero_extend:HI 2480 (match_operand:QI 1 "gpr_or_memory_operand" "d,L,m")))] 2481 "" 2482 "@ 2483 andi %1,#0xff,%0 2484 setlos %1,%0 2485 ldub%I1%U1 %M1,%0" 2486 [(set_attr "length" "4") 2487 (set_attr "type" "int,int,gload")]) 2488 2489(define_insn "zero_extendqisi2" 2490 [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d") 2491 (zero_extend:SI 2492 (match_operand:QI 1 "gpr_or_memory_operand" "d,L,m")))] 2493 "" 2494 "@ 2495 andi %1,#0xff,%0 2496 setlos %1,%0 2497 ldub%I1%U1 %M1,%0" 2498 [(set_attr "length" "4") 2499 (set_attr "type" "int,int,gload")]) 2500 2501;;(define_insn "zero_extendqidi2" 2502;; [(set (match_operand:DI 0 "register_operand" "=r") 2503;; (zero_extend:DI (match_operand:QI 1 "general_operand" "g")))] 2504;; "" 2505;; "zero_extendqihi2 %0,%1" 2506;; [(set_attr "length" "4")]) 2507 2508;; Do not set the type for the sethi to "sethi", since the scheduler will think 2509;; the sethi takes 0 cycles as part of allowing sethi/setlo to be in the same 2510;; VLIW instruction. 2511(define_insn "zero_extendhisi2" 2512 [(set (match_operand:SI 0 "integer_register_operand" "=d,d") 2513 (zero_extend:SI (match_operand:HI 1 "gpr_or_memory_operand" "0,m")))] 2514 "" 2515 "@ 2516 sethi #hi(#0),%0 2517 lduh%I1%U1 %M1,%0" 2518 [(set_attr "length" "4") 2519 (set_attr "type" "int,gload")]) 2520 2521;;(define_insn "zero_extendhidi2" 2522;; [(set (match_operand:DI 0 "register_operand" "=r") 2523;; (zero_extend:DI (match_operand:HI 1 "general_operand" "g")))] 2524;; "" 2525;; "zero_extendhihi2 %0,%1" 2526;; [(set_attr "length" "4")]) 2527;; 2528;;(define_insn "zero_extendsidi2" 2529;; [(set (match_operand:DI 0 "register_operand" "=r") 2530;; (zero_extend:DI (match_operand:SI 1 "general_operand" "g")))] 2531;; "" 2532;; "zero_extendsidi2 %0,%1" 2533;; [(set_attr "length" "4")]) 2534;; 2535;;;; Convert between floating point types of different sizes. 2536;; 2537;;(define_insn "extendsfdf2" 2538;; [(set (match_operand:DF 0 "register_operand" "=r") 2539;; (float_extend:DF (match_operand:SF 1 "register_operand" "r")))] 2540;; "" 2541;; "extendsfdf2 %0,%1" 2542;; [(set_attr "length" "4")]) 2543;; 2544;;(define_insn "truncdfsf2" 2545;; [(set (match_operand:SF 0 "register_operand" "=r") 2546;; (float_truncate:SF (match_operand:DF 1 "register_operand" "r")))] 2547;; "" 2548;; "truncdfsf2 %0,%1" 2549;; [(set_attr "length" "4")]) 2550 2551;;;; Convert between signed integer types and floating point. 2552(define_insn "floatsisf2" 2553 [(set (match_operand:SF 0 "fpr_operand" "=f") 2554 (float:SF (match_operand:SI 1 "fpr_operand" "f")))] 2555 "TARGET_HARD_FLOAT" 2556 "fitos %1,%0" 2557 [(set_attr "length" "4") 2558 (set_attr "type" "fsconv")]) 2559 2560(define_insn "floatsidf2" 2561 [(set (match_operand:DF 0 "fpr_operand" "=h") 2562 (float:DF (match_operand:SI 1 "fpr_operand" "f")))] 2563 "TARGET_HARD_FLOAT && TARGET_DOUBLE" 2564 "fitod %1,%0" 2565 [(set_attr "length" "4") 2566 (set_attr "type" "fdconv")]) 2567 2568;;(define_insn "floatdisf2" 2569;; [(set (match_operand:SF 0 "register_operand" "=r") 2570;; (float:SF (match_operand:DI 1 "register_operand" "r")))] 2571;; "" 2572;; "floatdisf2 %0,%1" 2573;; [(set_attr "length" "4")]) 2574;; 2575;;(define_insn "floatdidf2" 2576;; [(set (match_operand:DF 0 "register_operand" "=r") 2577;; (float:DF (match_operand:DI 1 "register_operand" "r")))] 2578;; "" 2579;; "floatdidf2 %0,%1" 2580;; [(set_attr "length" "4")]) 2581 2582(define_insn "fix_truncsfsi2" 2583 [(set (match_operand:SI 0 "fpr_operand" "=f") 2584 (fix:SI (match_operand:SF 1 "fpr_operand" "f")))] 2585 "TARGET_HARD_FLOAT" 2586 "fstoi %1,%0" 2587 [(set_attr "length" "4") 2588 (set_attr "type" "fsconv")]) 2589 2590(define_insn "fix_truncdfsi2" 2591 [(set (match_operand:SI 0 "fpr_operand" "=f") 2592 (fix:SI (match_operand:DF 1 "fpr_operand" "h")))] 2593 "TARGET_HARD_FLOAT && TARGET_DOUBLE" 2594 "fdtoi %1,%0" 2595 [(set_attr "length" "4") 2596 (set_attr "type" "fdconv")]) 2597 2598;;(define_insn "fix_truncsfdi2" 2599;; [(set (match_operand:DI 0 "register_operand" "=r") 2600;; (fix:DI (match_operand:SF 1 "register_operand" "r")))] 2601;; "" 2602;; "fix_truncsfdi2 %0,%1" 2603;; [(set_attr "length" "4")]) 2604;; 2605;;(define_insn "fix_truncdfdi2" 2606;; [(set (match_operand:DI 0 "register_operand" "=r") 2607;; (fix:DI (match_operand:DF 1 "register_operand" "r")))] 2608;; "" 2609;; "fix_truncdfdi2 %0,%1" 2610;; [(set_attr "length" "4")]) 2611;; 2612;;;; Convert between unsigned integer types and floating point. 2613;; 2614;;(define_insn "floatunssisf2" 2615;; [(set (match_operand:SF 0 "register_operand" "=r") 2616;; (unsigned_float:SF (match_operand:SI 1 "register_operand" "r")))] 2617;; "" 2618;; "floatunssisf2 %0,%1" 2619;; [(set_attr "length" "4")]) 2620;; 2621;;(define_insn "floatunssidf2" 2622;; [(set (match_operand:DF 0 "register_operand" "=r") 2623;; (unsigned_float:DF (match_operand:SI 1 "register_operand" "r")))] 2624;; "" 2625;; "floatunssidf2 %0,%1" 2626;; [(set_attr "length" "4")]) 2627;; 2628;;(define_insn "floatunsdisf2" 2629;; [(set (match_operand:SF 0 "register_operand" "=r") 2630;; (unsigned_float:SF (match_operand:DI 1 "register_operand" "r")))] 2631;; "" 2632;; "floatunsdisf2 %0,%1" 2633;; [(set_attr "length" "4")]) 2634;; 2635;;(define_insn "floatunsdidf2" 2636;; [(set (match_operand:DF 0 "register_operand" "=r") 2637;; (unsigned_float:DF (match_operand:DI 1 "register_operand" "r")))] 2638;; "" 2639;; "floatunsdidf2 %0,%1" 2640;; [(set_attr "length" "4")]) 2641;; 2642;;(define_insn "fixuns_truncsfsi2" 2643;; [(set (match_operand:SI 0 "register_operand" "=r") 2644;; (unsigned_fix:SI (match_operand:SF 1 "register_operand" "r")))] 2645;; "" 2646;; "fixuns_truncsfsi2 %0,%1" 2647;; [(set_attr "length" "4")]) 2648;; 2649;;(define_insn "fixuns_truncdfsi2" 2650;; [(set (match_operand:SI 0 "register_operand" "=r") 2651;; (unsigned_fix:SI (match_operand:DF 1 "register_operand" "r")))] 2652;; "" 2653;; "fixuns_truncdfsi2 %0,%1" 2654;; [(set_attr "length" "4")]) 2655;; 2656;;(define_insn "fixuns_truncsfdi2" 2657;; [(set (match_operand:DI 0 "register_operand" "=r") 2658;; (unsigned_fix:DI (match_operand:SF 1 "register_operand" "r")))] 2659;; "" 2660;; "fixuns_truncsfdi2 %0,%1" 2661;; [(set_attr "length" "4")]) 2662;; 2663;;(define_insn "fixuns_truncdfdi2" 2664;; [(set (match_operand:DI 0 "register_operand" "=r") 2665;; (unsigned_fix:DI (match_operand:DF 1 "register_operand" "r")))] 2666;; "" 2667;; "fixuns_truncdfdi2 %0,%1" 2668;; [(set_attr "length" "4")]) 2669 2670 2671;; :::::::::::::::::::: 2672;; :: 2673;; :: 32-bit Integer arithmetic 2674;; :: 2675;; :::::::::::::::::::: 2676 2677;; Addition 2678(define_insn "addsi3" 2679 [(set (match_operand:SI 0 "integer_register_operand" "=d") 2680 (plus:SI (match_operand:SI 1 "integer_register_operand" "%d") 2681 (match_operand:SI 2 "gpr_or_int12_operand" "dNOPQ")))] 2682 "" 2683 "add%I2 %1,%2,%0" 2684 [(set_attr "length" "4") 2685 (set_attr "type" "int")]) 2686 2687;; Subtraction. No need to worry about constants, since the compiler 2688;; canonicalizes them into addsi3's. We prevent SUBREG's here to work around a 2689;; combine bug, that combines the 32x32->upper 32 bit multiply that uses a 2690;; SUBREG with a minus that shows up in modulus by constants. 2691(define_insn "subsi3" 2692 [(set (match_operand:SI 0 "integer_register_operand" "=d") 2693 (minus:SI (match_operand:SI 1 "gpr_no_subreg_operand" "d") 2694 (match_operand:SI 2 "gpr_no_subreg_operand" "d")))] 2695 "" 2696 "sub %1,%2,%0" 2697 [(set_attr "length" "4") 2698 (set_attr "type" "int")]) 2699 2700;; Signed multiplication producing 64-bit results from 32-bit inputs 2701;; Note, frv doesn't have a 32x32->32 bit multiply, but the compiler 2702;; will do the 32x32->64 bit multiply and use the bottom word. 2703(define_expand "mulsidi3" 2704 [(set (match_operand:DI 0 "integer_register_operand" "") 2705 (mult:DI (sign_extend:DI (match_operand:SI 1 "integer_register_operand" "")) 2706 (sign_extend:DI (match_operand:SI 2 "gpr_or_int12_operand" ""))))] 2707 "" 2708 " 2709{ 2710 if (GET_CODE (operands[2]) == CONST_INT) 2711 { 2712 emit_insn (gen_mulsidi3_const (operands[0], operands[1], operands[2])); 2713 DONE; 2714 } 2715}") 2716 2717(define_insn "*mulsidi3_reg" 2718 [(set (match_operand:DI 0 "even_gpr_operand" "=e") 2719 (mult:DI (sign_extend:DI (match_operand:SI 1 "integer_register_operand" "%d")) 2720 (sign_extend:DI (match_operand:SI 2 "integer_register_operand" "d"))))] 2721 "" 2722 "smul %1,%2,%0" 2723 [(set_attr "length" "4") 2724 (set_attr "type" "mul")]) 2725 2726(define_insn "mulsidi3_const" 2727 [(set (match_operand:DI 0 "even_gpr_operand" "=e") 2728 (mult:DI (sign_extend:DI (match_operand:SI 1 "integer_register_operand" "d")) 2729 (match_operand:SI 2 "int12_operand" "NOP")))] 2730 "" 2731 "smuli %1,%2,%0" 2732 [(set_attr "length" "4") 2733 (set_attr "type" "mul")]) 2734 2735;; Unsigned multiplication producing 64-bit results from 32-bit inputs 2736(define_expand "umulsidi3" 2737 [(set (match_operand:DI 0 "even_gpr_operand" "") 2738 (mult:DI (zero_extend:DI (match_operand:SI 1 "integer_register_operand" "")) 2739 (zero_extend:DI (match_operand:SI 2 "gpr_or_int12_operand" ""))))] 2740 "" 2741 " 2742{ 2743 if (GET_CODE (operands[2]) == CONST_INT) 2744 { 2745 emit_insn (gen_umulsidi3_const (operands[0], operands[1], operands[2])); 2746 DONE; 2747 } 2748}") 2749 2750(define_insn "*mulsidi3_reg" 2751 [(set (match_operand:DI 0 "even_gpr_operand" "=e") 2752 (mult:DI (zero_extend:DI (match_operand:SI 1 "integer_register_operand" "%d")) 2753 (zero_extend:DI (match_operand:SI 2 "integer_register_operand" "d"))))] 2754 "" 2755 "umul %1,%2,%0" 2756 [(set_attr "length" "4") 2757 (set_attr "type" "mul")]) 2758 2759(define_insn "umulsidi3_const" 2760 [(set (match_operand:DI 0 "even_gpr_operand" "=e") 2761 (mult:DI (zero_extend:DI (match_operand:SI 1 "integer_register_operand" "d")) 2762 (match_operand:SI 2 "int12_operand" "NOP")))] 2763 "" 2764 "umuli %1,%2,%0" 2765 [(set_attr "length" "4") 2766 (set_attr "type" "mul")]) 2767 2768;; Signed Division 2769(define_insn "divsi3" 2770 [(set (match_operand:SI 0 "register_operand" "=d,d") 2771 (div:SI (match_operand:SI 1 "register_operand" "d,d") 2772 (match_operand:SI 2 "gpr_or_int12_operand" "d,NOP")))] 2773 "" 2774 "sdiv%I2 %1,%2,%0" 2775 [(set_attr "length" "4") 2776 (set_attr "type" "div")]) 2777 2778;; Unsigned Division 2779(define_insn "udivsi3" 2780 [(set (match_operand:SI 0 "register_operand" "=d,d") 2781 (udiv:SI (match_operand:SI 1 "register_operand" "d,d") 2782 (match_operand:SI 2 "gpr_or_int12_operand" "d,NOP")))] 2783 "" 2784 "udiv%I2 %1,%2,%0" 2785 [(set_attr "length" "4") 2786 (set_attr "type" "div")]) 2787 2788;; Negation 2789(define_insn "negsi2" 2790 [(set (match_operand:SI 0 "integer_register_operand" "=d") 2791 (neg:SI (match_operand:SI 1 "integer_register_operand" "d")))] 2792 "" 2793 "sub %.,%1,%0" 2794 [(set_attr "length" "4") 2795 (set_attr "type" "int")]) 2796 2797;; Find first one bit 2798;; (define_insn "ffssi2" 2799;; [(set (match_operand:SI 0 "register_operand" "=r") 2800;; (ffs:SI (match_operand:SI 1 "register_operand" "r")))] 2801;; "" 2802;; "ffssi2 %0,%1" 2803;; [(set_attr "length" "4")]) 2804 2805 2806;; :::::::::::::::::::: 2807;; :: 2808;; :: 64-bit Integer arithmetic 2809;; :: 2810;; :::::::::::::::::::: 2811 2812;; Addition 2813(define_insn_and_split "adddi3" 2814 [(set (match_operand:DI 0 "integer_register_operand" "=&e,e") 2815 (plus:DI (match_operand:DI 1 "integer_register_operand" "%e,0") 2816 (match_operand:DI 2 "gpr_or_int10_operand" "eJ,eJ"))) 2817 (clobber (match_scratch:CC 3 "=t,t"))] 2818 "" 2819 "#" 2820 "reload_completed" 2821 [(match_dup 4) 2822 (match_dup 5)] 2823 " 2824{ 2825 rtx parts[3][2]; 2826 int op, part; 2827 2828 for (op = 0; op < 3; op++) 2829 for (part = 0; part < 2; part++) 2830 parts[op][part] = simplify_gen_subreg (SImode, operands[op], 2831 DImode, part * UNITS_PER_WORD); 2832 2833 operands[4] = gen_adddi3_lower (parts[0][1], parts[1][1], parts[2][1], 2834 operands[3]); 2835 operands[5] = gen_adddi3_upper (parts[0][0], parts[1][0], parts[2][0], 2836 copy_rtx (operands[3])); 2837}" 2838 [(set_attr "length" "8") 2839 (set_attr "type" "multi")]) 2840 2841;; Subtraction No need to worry about constants, since the compiler 2842;; canonicalizes them into adddi3's. 2843(define_insn_and_split "subdi3" 2844 [(set (match_operand:DI 0 "integer_register_operand" "=&e,e,e") 2845 (minus:DI (match_operand:DI 1 "integer_register_operand" "e,0,e") 2846 (match_operand:DI 2 "integer_register_operand" "e,e,0"))) 2847 (clobber (match_scratch:CC 3 "=t,t,t"))] 2848 "" 2849 "#" 2850 "reload_completed" 2851 [(match_dup 4) 2852 (match_dup 5)] 2853 " 2854{ 2855 rtx op0_high = gen_highpart (SImode, operands[0]); 2856 rtx op1_high = gen_highpart (SImode, operands[1]); 2857 rtx op2_high = gen_highpart (SImode, operands[2]); 2858 rtx op0_low = gen_lowpart (SImode, operands[0]); 2859 rtx op1_low = gen_lowpart (SImode, operands[1]); 2860 rtx op2_low = gen_lowpart (SImode, operands[2]); 2861 rtx op3 = operands[3]; 2862 2863 operands[4] = gen_subdi3_lower (op0_low, op1_low, op2_low, op3); 2864 operands[5] = gen_subdi3_upper (op0_high, op1_high, op2_high, op3); 2865}" 2866 [(set_attr "length" "8") 2867 (set_attr "type" "multi")]) 2868 2869;; Patterns for addsi3/subdi3 after splitting 2870(define_insn "adddi3_lower" 2871 [(set (match_operand:SI 0 "integer_register_operand" "=d") 2872 (plus:SI (match_operand:SI 1 "integer_register_operand" "d") 2873 (match_operand:SI 2 "gpr_or_int10_operand" "dJ"))) 2874 (set (match_operand:CC 3 "icc_operand" "=t") 2875 (compare:CC (plus:SI (match_dup 1) 2876 (match_dup 2)) 2877 (const_int 0)))] 2878 "" 2879 "add%I2cc %1,%2,%0,%3" 2880 [(set_attr "length" "4") 2881 (set_attr "type" "int")]) 2882 2883(define_insn "adddi3_upper" 2884 [(set (match_operand:SI 0 "integer_register_operand" "=d") 2885 (plus:SI (match_operand:SI 1 "integer_register_operand" "d") 2886 (plus:SI (match_operand:SI 2 "gpr_or_int10_operand" "dJ") 2887 (match_operand:CC 3 "icc_operand" "t"))))] 2888 "" 2889 "addx%I2 %1,%2,%0,%3" 2890 [(set_attr "length" "4") 2891 (set_attr "type" "int")]) 2892 2893(define_insn "subdi3_lower" 2894 [(set (match_operand:SI 0 "integer_register_operand" "=d") 2895 (minus:SI (match_operand:SI 1 "integer_register_operand" "d") 2896 (match_operand:SI 2 "integer_register_operand" "d"))) 2897 (set (match_operand:CC 3 "icc_operand" "=t") 2898 (compare:CC (plus:SI (match_dup 1) 2899 (match_dup 2)) 2900 (const_int 0)))] 2901 "" 2902 "subcc %1,%2,%0,%3" 2903 [(set_attr "length" "4") 2904 (set_attr "type" "int")]) 2905 2906(define_insn "subdi3_upper" 2907 [(set (match_operand:SI 0 "integer_register_operand" "=d") 2908 (minus:SI (match_operand:SI 1 "integer_register_operand" "d") 2909 (minus:SI (match_operand:SI 2 "integer_register_operand" "d") 2910 (match_operand:CC 3 "icc_operand" "t"))))] 2911 "" 2912 "subx %1,%2,%0,%3" 2913 [(set_attr "length" "4") 2914 (set_attr "type" "int")]) 2915 2916(define_insn_and_split "negdi2" 2917 [(set (match_operand:DI 0 "integer_register_operand" "=&e,e") 2918 (neg:DI (match_operand:DI 1 "integer_register_operand" "e,0"))) 2919 (clobber (match_scratch:CC 2 "=t,t"))] 2920 "" 2921 "#" 2922 "reload_completed" 2923 [(match_dup 3) 2924 (match_dup 4)] 2925 " 2926{ 2927 rtx op0_high = gen_highpart (SImode, operands[0]); 2928 rtx op1_high = gen_rtx_REG (SImode, GPR_FIRST); 2929 rtx op2_high = gen_highpart (SImode, operands[1]); 2930 rtx op0_low = gen_lowpart (SImode, operands[0]); 2931 rtx op1_low = op1_high; 2932 rtx op2_low = gen_lowpart (SImode, operands[1]); 2933 rtx op3 = operands[2]; 2934 2935 operands[3] = gen_subdi3_lower (op0_low, op1_low, op2_low, op3); 2936 operands[4] = gen_subdi3_upper (op0_high, op1_high, op2_high, op3); 2937}" 2938 [(set_attr "length" "8") 2939 (set_attr "type" "multi")]) 2940 2941;; Multiplication (same size) 2942;; (define_insn "muldi3" 2943;; [(set (match_operand:DI 0 "register_operand" "=r") 2944;; (mult:DI (match_operand:DI 1 "register_operand" "%r") 2945;; (match_operand:DI 2 "nonmemory_operand" "ri")))] 2946;; "" 2947;; "muldi3 %0,%1,%2" 2948;; [(set_attr "length" "4")]) 2949 2950;; Signed Division 2951;; (define_insn "divdi3" 2952;; [(set (match_operand:DI 0 "register_operand" "=r") 2953;; (div:DI (match_operand:DI 1 "register_operand" "r") 2954;; (match_operand:DI 2 "nonmemory_operand" "ri")))] 2955;; "" 2956;; "divdi3 %0,%1,%2" 2957;; [(set_attr "length" "4")]) 2958 2959;; Undsgned Division 2960;; (define_insn "udivdi3" 2961;; [(set (match_operand:DI 0 "register_operand" "=r") 2962;; (udiv:DI (match_operand:DI 1 "register_operand" "r") 2963;; (match_operand:DI 2 "nonmemory_operand" "ri")))] 2964;; "" 2965;; "udivdi3 %0,%1,%2" 2966;; [(set_attr "length" "4")]) 2967 2968;; Negation 2969;; (define_insn "negdi2" 2970;; [(set (match_operand:DI 0 "register_operand" "=r") 2971;; (neg:DI (match_operand:DI 1 "register_operand" "r")))] 2972;; "" 2973;; "negdi2 %0,%1" 2974;; [(set_attr "length" "4")]) 2975 2976;; Find first one bit 2977;; (define_insn "ffsdi2" 2978;; [(set (match_operand:DI 0 "register_operand" "=r") 2979;; (ffs:DI (match_operand:DI 1 "register_operand" "r")))] 2980;; "" 2981;; "ffsdi2 %0,%1" 2982;; [(set_attr "length" "4")]) 2983 2984 2985;; :::::::::::::::::::: 2986;; :: 2987;; :: 32-bit floating point arithmetic 2988;; :: 2989;; :::::::::::::::::::: 2990 2991;; Addition 2992(define_insn "addsf3" 2993 [(set (match_operand:SF 0 "fpr_operand" "=f") 2994 (plus:SF (match_operand:SF 1 "fpr_operand" "%f") 2995 (match_operand:SF 2 "fpr_operand" "f")))] 2996 "TARGET_HARD_FLOAT" 2997 "fadds %1,%2,%0" 2998 [(set_attr "length" "4") 2999 (set_attr "type" "fsadd")]) 3000 3001;; Subtraction 3002(define_insn "subsf3" 3003 [(set (match_operand:SF 0 "fpr_operand" "=f") 3004 (minus:SF (match_operand:SF 1 "fpr_operand" "f") 3005 (match_operand:SF 2 "fpr_operand" "f")))] 3006 "TARGET_HARD_FLOAT" 3007 "fsubs %1,%2,%0" 3008 [(set_attr "length" "4") 3009 (set_attr "type" "fsadd")]) 3010 3011;; Multiplication 3012(define_insn "mulsf3" 3013 [(set (match_operand:SF 0 "fpr_operand" "=f") 3014 (mult:SF (match_operand:SF 1 "fpr_operand" "%f") 3015 (match_operand:SF 2 "fpr_operand" "f")))] 3016 "TARGET_HARD_FLOAT" 3017 "fmuls %1,%2,%0" 3018 [(set_attr "length" "4") 3019 (set_attr "type" "fsmul")]) 3020 3021;; Multiplication with addition/subtraction 3022(define_insn "fmasf4" 3023 [(set (match_operand:SF 0 "fpr_operand" "=f") 3024 (fma:SF (match_operand:SF 1 "fpr_operand" "f") 3025 (match_operand:SF 2 "fpr_operand" "f") 3026 (match_operand:SF 3 "fpr_operand" "0")))] 3027 "TARGET_HARD_FLOAT && TARGET_MULADD" 3028 "fmadds %1,%2,%0" 3029 [(set_attr "length" "4") 3030 (set_attr "type" "fsmadd")]) 3031 3032(define_insn "fmssf4" 3033 [(set (match_operand:SF 0 "fpr_operand" "=f") 3034 (fma:SF (match_operand:SF 1 "fpr_operand" "f") 3035 (match_operand:SF 2 "fpr_operand" "f") 3036 (neg:SF (match_operand:SF 3 "fpr_operand" "0"))))] 3037 "TARGET_HARD_FLOAT && TARGET_MULADD" 3038 "fmsubs %1,%2,%0" 3039 [(set_attr "length" "4") 3040 (set_attr "type" "fsmadd")]) 3041 3042;; Division 3043(define_insn "divsf3" 3044 [(set (match_operand:SF 0 "fpr_operand" "=f") 3045 (div:SF (match_operand:SF 1 "fpr_operand" "f") 3046 (match_operand:SF 2 "fpr_operand" "f")))] 3047 "TARGET_HARD_FLOAT" 3048 "fdivs %1,%2,%0" 3049 [(set_attr "length" "4") 3050 (set_attr "type" "fsdiv")]) 3051 3052;; Negation 3053(define_insn "negsf2" 3054 [(set (match_operand:SF 0 "fpr_operand" "=f") 3055 (neg:SF (match_operand:SF 1 "fpr_operand" "f")))] 3056 "TARGET_HARD_FLOAT" 3057 "fnegs %1,%0" 3058 [(set_attr "length" "4") 3059 (set_attr "type" "fsconv")]) 3060 3061;; Absolute value 3062(define_insn "abssf2" 3063 [(set (match_operand:SF 0 "fpr_operand" "=f") 3064 (abs:SF (match_operand:SF 1 "fpr_operand" "f")))] 3065 "TARGET_HARD_FLOAT" 3066 "fabss %1,%0" 3067 [(set_attr "length" "4") 3068 (set_attr "type" "fsconv")]) 3069 3070;; Square root 3071(define_insn "sqrtsf2" 3072 [(set (match_operand:SF 0 "fpr_operand" "=f") 3073 (sqrt:SF (match_operand:SF 1 "fpr_operand" "f")))] 3074 "TARGET_HARD_FLOAT" 3075 "fsqrts %1,%0" 3076 [(set_attr "length" "4") 3077 (set_attr "type" "sqrt_single")]) 3078 3079 3080;; :::::::::::::::::::: 3081;; :: 3082;; :: 64-bit floating point arithmetic 3083;; :: 3084;; :::::::::::::::::::: 3085 3086;; Addition 3087(define_insn "adddf3" 3088 [(set (match_operand:DF 0 "even_fpr_operand" "=h") 3089 (plus:DF (match_operand:DF 1 "fpr_operand" "%h") 3090 (match_operand:DF 2 "fpr_operand" "h")))] 3091 "TARGET_HARD_FLOAT && TARGET_DOUBLE" 3092 "faddd %1,%2,%0" 3093 [(set_attr "length" "4") 3094 (set_attr "type" "fdadd")]) 3095 3096;; Subtraction 3097(define_insn "subdf3" 3098 [(set (match_operand:DF 0 "even_fpr_operand" "=h") 3099 (minus:DF (match_operand:DF 1 "fpr_operand" "h") 3100 (match_operand:DF 2 "fpr_operand" "h")))] 3101 "TARGET_HARD_FLOAT && TARGET_DOUBLE" 3102 "fsubd %1,%2,%0" 3103 [(set_attr "length" "4") 3104 (set_attr "type" "fdadd")]) 3105 3106;; Multiplication 3107(define_insn "muldf3" 3108 [(set (match_operand:DF 0 "even_fpr_operand" "=h") 3109 (mult:DF (match_operand:DF 1 "fpr_operand" "%h") 3110 (match_operand:DF 2 "fpr_operand" "h")))] 3111 "TARGET_HARD_FLOAT && TARGET_DOUBLE" 3112 "fmuld %1,%2,%0" 3113 [(set_attr "length" "4") 3114 (set_attr "type" "fdmul")]) 3115 3116;; Multiplication with addition/subtraction 3117(define_insn "*muladddf4" 3118 [(set (match_operand:DF 0 "fpr_operand" "=f") 3119 (plus:DF (mult:DF (match_operand:DF 1 "fpr_operand" "%f") 3120 (match_operand:DF 2 "fpr_operand" "f")) 3121 (match_operand:DF 3 "fpr_operand" "0")))] 3122 "TARGET_HARD_FLOAT && TARGET_DOUBLE && TARGET_MULADD" 3123 "fmaddd %1,%2,%0" 3124 [(set_attr "length" "4") 3125 (set_attr "type" "fdmadd")]) 3126 3127(define_insn "*mulsubdf4" 3128 [(set (match_operand:DF 0 "fpr_operand" "=f") 3129 (minus:DF (mult:DF (match_operand:DF 1 "fpr_operand" "%f") 3130 (match_operand:DF 2 "fpr_operand" "f")) 3131 (match_operand:DF 3 "fpr_operand" "0")))] 3132 "TARGET_HARD_FLOAT && TARGET_DOUBLE && TARGET_MULADD" 3133 "fmsubd %1,%2,%0" 3134 [(set_attr "length" "4") 3135 (set_attr "type" "fdmadd")]) 3136 3137;; Division 3138(define_insn "divdf3" 3139 [(set (match_operand:DF 0 "even_fpr_operand" "=h") 3140 (div:DF (match_operand:DF 1 "fpr_operand" "h") 3141 (match_operand:DF 2 "fpr_operand" "h")))] 3142 "TARGET_HARD_FLOAT && TARGET_DOUBLE" 3143 "fdivd %1,%2,%0" 3144 [(set_attr "length" "4") 3145 (set_attr "type" "fddiv")]) 3146 3147;; Negation 3148(define_insn "negdf2" 3149 [(set (match_operand:DF 0 "even_fpr_operand" "=h") 3150 (neg:DF (match_operand:DF 1 "fpr_operand" "h")))] 3151 "TARGET_HARD_FLOAT && TARGET_DOUBLE" 3152 "fnegd %1,%0" 3153 [(set_attr "length" "4") 3154 (set_attr "type" "fdconv")]) 3155 3156;; Absolute value 3157(define_insn "absdf2" 3158 [(set (match_operand:DF 0 "even_fpr_operand" "=h") 3159 (abs:DF (match_operand:DF 1 "fpr_operand" "h")))] 3160 "TARGET_HARD_FLOAT && TARGET_DOUBLE" 3161 "fabsd %1,%0" 3162 [(set_attr "length" "4") 3163 (set_attr "type" "fdconv")]) 3164 3165;; Square root 3166(define_insn "sqrtdf2" 3167 [(set (match_operand:DF 0 "even_fpr_operand" "=h") 3168 (sqrt:DF (match_operand:DF 1 "fpr_operand" "h")))] 3169 "TARGET_HARD_FLOAT && TARGET_DOUBLE" 3170 "fsqrtd %1,%0" 3171 [(set_attr "length" "4") 3172 (set_attr "type" "sqrt_double")]) 3173 3174 3175;; :::::::::::::::::::: 3176;; :: 3177;; :: 32-bit Integer Shifts and Rotates 3178;; :: 3179;; :::::::::::::::::::: 3180 3181;; Arithmetic Shift Left 3182(define_insn "ashlsi3" 3183 [(set (match_operand:SI 0 "integer_register_operand" "=d,d") 3184 (ashift:SI (match_operand:SI 1 "integer_register_operand" "d,d") 3185 (match_operand:SI 2 "gpr_or_int12_operand" "d,NOP")))] 3186 "" 3187 "sll%I2 %1,%2,%0" 3188 [(set_attr "length" "4") 3189 (set_attr "type" "int")]) 3190 3191;; Arithmetic Shift Right 3192(define_insn "ashrsi3" 3193 [(set (match_operand:SI 0 "integer_register_operand" "=d,d") 3194 (ashiftrt:SI (match_operand:SI 1 "integer_register_operand" "d,d") 3195 (match_operand:SI 2 "gpr_or_int12_operand" "d,NOP")))] 3196 "" 3197 "sra%I2 %1, %2, %0" 3198 [(set_attr "length" "4") 3199 (set_attr "type" "int")]) 3200 3201;; Logical Shift Right 3202(define_insn "lshrsi3" 3203 [(set (match_operand:SI 0 "integer_register_operand" "=d,d") 3204 (lshiftrt:SI (match_operand:SI 1 "integer_register_operand" "d,d") 3205 (match_operand:SI 2 "gpr_or_int12_operand" "d,NOP")))] 3206 "" 3207 "srl%I2 %1, %2, %0" 3208 [(set_attr "length" "4") 3209 (set_attr "type" "int")]) 3210 3211;; Rotate Left 3212;; (define_insn "rotlsi3" 3213;; [(set (match_operand:SI 0 "register_operand" "=r") 3214;; (rotate:SI (match_operand:SI 1 "register_operand" "r") 3215;; (match_operand:SI 2 "nonmemory_operand" "ri")))] 3216;; "" 3217;; "rotlsi3 %0,%1,%2" 3218;; [(set_attr "length" "4")]) 3219 3220;; Rotate Right 3221;; (define_insn "rotrsi3" 3222;; [(set (match_operand:SI 0 "register_operand" "=r") 3223;; (rotatert:SI (match_operand:SI 1 "register_operand" "r") 3224;; (match_operand:SI 2 "nonmemory_operand" "ri")))] 3225;; "" 3226;; "rotrsi3 %0,%1,%2" 3227;; [(set_attr "length" "4")]) 3228 3229 3230;; :::::::::::::::::::: 3231;; :: 3232;; :: 64-bit Integer Shifts and Rotates 3233;; :: 3234;; :::::::::::::::::::: 3235 3236;; Arithmetic Shift Left 3237;; (define_insn "ashldi3" 3238;; [(set (match_operand:DI 0 "register_operand" "=r") 3239;; (ashift:DI (match_operand:DI 1 "register_operand" "r") 3240;; (match_operand:SI 2 "nonmemory_operand" "ri")))] 3241;; "" 3242;; "ashldi3 %0,%1,%2" 3243;; [(set_attr "length" "4")]) 3244 3245;; Arithmetic Shift Right 3246;; (define_insn "ashrdi3" 3247;; [(set (match_operand:DI 0 "register_operand" "=r") 3248;; (ashiftrt:DI (match_operand:DI 1 "register_operand" "r") 3249;; (match_operand:SI 2 "nonmemory_operand" "ri")))] 3250;; "" 3251;; "ashrdi3 %0,%1,%2" 3252;; [(set_attr "length" "4")]) 3253 3254;; Logical Shift Right 3255;; (define_insn "lshrdi3" 3256;; [(set (match_operand:DI 0 "register_operand" "=r") 3257;; (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") 3258;; (match_operand:SI 2 "nonmemory_operand" "ri")))] 3259;; "" 3260;; "lshrdi3 %0,%1,%2" 3261;; [(set_attr "length" "4")]) 3262 3263;; Rotate Left 3264;; (define_insn "rotldi3" 3265;; [(set (match_operand:DI 0 "register_operand" "=r") 3266;; (rotate:DI (match_operand:DI 1 "register_operand" "r") 3267;; (match_operand:SI 2 "nonmemory_operand" "ri")))] 3268;; "" 3269;; "rotldi3 %0,%1,%2" 3270;; [(set_attr "length" "4")]) 3271 3272;; Rotate Right 3273;; (define_insn "rotrdi3" 3274;; [(set (match_operand:DI 0 "register_operand" "=r") 3275;; (rotatert:DI (match_operand:DI 1 "register_operand" "r") 3276;; (match_operand:SI 2 "nonmemory_operand" "ri")))] 3277;; "" 3278;; "rotrdi3 %0,%1,%2" 3279;; [(set_attr "length" "4")]) 3280 3281 3282;; :::::::::::::::::::: 3283;; :: 3284;; :: 32-Bit Integer Logical operations 3285;; :: 3286;; :::::::::::::::::::: 3287 3288;; Logical AND, 32-bit integers 3289(define_insn "andsi3_media" 3290 [(set (match_operand:SI 0 "gpr_or_fpr_operand" "=d,f") 3291 (and:SI (match_operand:SI 1 "gpr_or_fpr_operand" "%d,f") 3292 (match_operand:SI 2 "gpr_fpr_or_int12_operand" "dNOP,f")))] 3293 "TARGET_MEDIA" 3294 "@ 3295 and%I2 %1, %2, %0 3296 mand %1, %2, %0" 3297 [(set_attr "length" "4") 3298 (set_attr "type" "int,mlogic")]) 3299 3300(define_insn "andsi3_nomedia" 3301 [(set (match_operand:SI 0 "integer_register_operand" "=d") 3302 (and:SI (match_operand:SI 1 "integer_register_operand" "%d") 3303 (match_operand:SI 2 "gpr_or_int12_operand" "dNOP")))] 3304 "!TARGET_MEDIA" 3305 "and%I2 %1, %2, %0" 3306 [(set_attr "length" "4") 3307 (set_attr "type" "int")]) 3308 3309(define_expand "andsi3" 3310 [(set (match_operand:SI 0 "gpr_or_fpr_operand" "") 3311 (and:SI (match_operand:SI 1 "gpr_or_fpr_operand" "") 3312 (match_operand:SI 2 "gpr_fpr_or_int12_operand" "")))] 3313 "" 3314 "") 3315 3316;; Inclusive OR, 32-bit integers 3317(define_insn "iorsi3_media" 3318 [(set (match_operand:SI 0 "gpr_or_fpr_operand" "=d,f") 3319 (ior:SI (match_operand:SI 1 "gpr_or_fpr_operand" "%d,f") 3320 (match_operand:SI 2 "gpr_fpr_or_int12_operand" "dNOP,f")))] 3321 "TARGET_MEDIA" 3322 "@ 3323 or%I2 %1, %2, %0 3324 mor %1, %2, %0" 3325 [(set_attr "length" "4") 3326 (set_attr "type" "int,mlogic")]) 3327 3328(define_insn "iorsi3_nomedia" 3329 [(set (match_operand:SI 0 "integer_register_operand" "=d") 3330 (ior:SI (match_operand:SI 1 "integer_register_operand" "%d") 3331 (match_operand:SI 2 "gpr_or_int12_operand" "dNOP")))] 3332 "!TARGET_MEDIA" 3333 "or%I2 %1, %2, %0" 3334 [(set_attr "length" "4") 3335 (set_attr "type" "int")]) 3336 3337(define_expand "iorsi3" 3338 [(set (match_operand:SI 0 "gpr_or_fpr_operand" "") 3339 (ior:SI (match_operand:SI 1 "gpr_or_fpr_operand" "") 3340 (match_operand:SI 2 "gpr_fpr_or_int12_operand" "")))] 3341 "" 3342 "") 3343 3344;; Exclusive OR, 32-bit integers 3345(define_insn "xorsi3_media" 3346 [(set (match_operand:SI 0 "gpr_or_fpr_operand" "=d,f") 3347 (xor:SI (match_operand:SI 1 "gpr_or_fpr_operand" "%d,f") 3348 (match_operand:SI 2 "gpr_fpr_or_int12_operand" "dNOP,f")))] 3349 "TARGET_MEDIA" 3350 "@ 3351 xor%I2 %1, %2, %0 3352 mxor %1, %2, %0" 3353 [(set_attr "length" "4") 3354 (set_attr "type" "int,mlogic")]) 3355 3356(define_insn "xorsi3_nomedia" 3357 [(set (match_operand:SI 0 "integer_register_operand" "=d") 3358 (xor:SI (match_operand:SI 1 "integer_register_operand" "%d") 3359 (match_operand:SI 2 "gpr_or_int12_operand" "dNOP")))] 3360 "!TARGET_MEDIA" 3361 "xor%I2 %1, %2, %0" 3362 [(set_attr "length" "4") 3363 (set_attr "type" "int")]) 3364 3365(define_expand "xorsi3" 3366 [(set (match_operand:SI 0 "gpr_or_fpr_operand" "") 3367 (xor:SI (match_operand:SI 1 "gpr_or_fpr_operand" "") 3368 (match_operand:SI 2 "gpr_fpr_or_int12_operand" "")))] 3369 "" 3370 "") 3371 3372;; One's complement, 32-bit integers 3373(define_insn "one_cmplsi2_media" 3374 [(set (match_operand:SI 0 "gpr_or_fpr_operand" "=d,f") 3375 (not:SI (match_operand:SI 1 "gpr_or_fpr_operand" "d,f")))] 3376 "TARGET_MEDIA" 3377 "@ 3378 not %1, %0 3379 mnot %1, %0" 3380 [(set_attr "length" "4") 3381 (set_attr "type" "int,mlogic")]) 3382 3383(define_insn "one_cmplsi2_nomedia" 3384 [(set (match_operand:SI 0 "integer_register_operand" "=d") 3385 (not:SI (match_operand:SI 1 "integer_register_operand" "d")))] 3386 "!TARGET_MEDIA" 3387 "not %1,%0" 3388 [(set_attr "length" "4") 3389 (set_attr "type" "int")]) 3390 3391(define_expand "one_cmplsi2" 3392 [(set (match_operand:SI 0 "gpr_or_fpr_operand" "") 3393 (not:SI (match_operand:SI 1 "gpr_or_fpr_operand" "")))] 3394 "" 3395 "") 3396 3397 3398;; :::::::::::::::::::: 3399;; :: 3400;; :: 64-Bit Integer Logical operations 3401;; :: 3402;; :::::::::::::::::::: 3403 3404;; Logical AND, 64-bit integers 3405;; (define_insn "anddi3" 3406;; [(set (match_operand:DI 0 "register_operand" "=r") 3407;; (and:DI (match_operand:DI 1 "register_operand" "%r") 3408;; (match_operand:DI 2 "nonmemory_operand" "ri")))] 3409;; "" 3410;; "anddi3 %0,%1,%2" 3411;; [(set_attr "length" "4")]) 3412 3413;; Inclusive OR, 64-bit integers 3414;; (define_insn "iordi3" 3415;; [(set (match_operand:DI 0 "register_operand" "=r") 3416;; (ior:DI (match_operand:DI 1 "register_operand" "%r") 3417;; (match_operand:DI 2 "nonmemory_operand" "ri")))] 3418;; "" 3419;; "iordi3 %0,%1,%2" 3420;; [(set_attr "length" "4")]) 3421 3422;; Exclusive OR, 64-bit integers 3423;; (define_insn "xordi3" 3424;; [(set (match_operand:DI 0 "register_operand" "=r") 3425;; (xor:DI (match_operand:DI 1 "register_operand" "%r") 3426;; (match_operand:DI 2 "nonmemory_operand" "ri")))] 3427;; "" 3428;; "xordi3 %0,%1,%2" 3429;; [(set_attr "length" "4")]) 3430 3431;; One's complement, 64-bit integers 3432;; (define_insn "one_cmpldi2" 3433;; [(set (match_operand:DI 0 "register_operand" "=r") 3434;; (not:DI (match_operand:DI 1 "register_operand" "r")))] 3435;; "" 3436;; "notdi3 %0,%1" 3437;; [(set_attr "length" "4")]) 3438 3439 3440;; :::::::::::::::::::: 3441;; :: 3442;; :: Combination of integer operation with comparison 3443;; :: 3444;; :::::::::::::::::::: 3445 3446(define_insn "*combo_intop_compare1" 3447 [(set (match_operand:CC_NZ 0 "icc_operand" "=t") 3448 (compare:CC_NZ 3449 (match_operator:SI 1 "intop_compare_operator" 3450 [(match_operand:SI 2 "integer_register_operand" "d") 3451 (match_operand:SI 3 "gpr_or_int10_operand" "dJ")]) 3452 (const_int 0)))] 3453 "" 3454 "%O1%I3cc %2, %3, %., %0" 3455 [(set_attr "type" "int") 3456 (set_attr "length" "4")]) 3457 3458(define_insn "*combo_intop_compare2" 3459 [(set (match_operand:CC_NZ 0 "icc_operand" "=t") 3460 (compare:CC_NZ 3461 (match_operator:SI 1 "intop_compare_operator" 3462 [(match_operand:SI 2 "integer_register_operand" "d") 3463 (match_operand:SI 3 "gpr_or_int10_operand" "dJ")]) 3464 (const_int 0))) 3465 (set (match_operand:SI 4 "integer_register_operand" "=d") 3466 (match_operator:SI 5 "intop_compare_operator" 3467 [(match_dup 2) 3468 (match_dup 3)]))] 3469 "GET_CODE (operands[1]) == GET_CODE (operands[5])" 3470 "%O1%I3cc %2, %3, %4, %0" 3471 [(set_attr "type" "int") 3472 (set_attr "length" "4")]) 3473 3474;; :::::::::::::::::::: 3475;; :: 3476;; :: Comparisons 3477;; :: 3478;; :::::::::::::::::::: 3479 3480;; The comparisons are generated by the branch and/or scc operations 3481 3482(define_insn "cmpsi_cc" 3483 [(set (match_operand:CC 0 "icc_operand" "=t,t") 3484 (compare:CC (match_operand:SI 1 "integer_register_operand" "d,d") 3485 (match_operand:SI 2 "gpr_or_int10_operand" "d,J")))] 3486 "" 3487 "cmp%I2 %1,%2,%0" 3488 [(set_attr "length" "4") 3489 (set_attr "type" "int")]) 3490 3491(define_insn "*cmpsi_cc_uns" 3492 [(set (match_operand:CC_UNS 0 "icc_operand" "=t,t") 3493 (compare:CC_UNS (match_operand:SI 1 "integer_register_operand" "d,d") 3494 (match_operand:SI 2 "gpr_or_int10_operand" "d,J")))] 3495 "" 3496 "cmp%I2 %1,%2,%0" 3497 [(set_attr "length" "4") 3498 (set_attr "type" "int")]) 3499 3500;; The only requirement for a CC_NZmode GPR or memory value is that 3501;; comparing it against zero must set the Z and N flags appropriately. 3502;; The source operand is therefore a valid CC_NZmode value. 3503(define_insn "*cmpsi_cc_nz" 3504 [(set (match_operand:CC_NZ 0 "nonimmediate_operand" "=t,d,m") 3505 (compare:CC_NZ (match_operand:SI 1 "integer_register_operand" "d,d,d") 3506 (const_int 0)))] 3507 "" 3508 "@ 3509 cmpi %1, #0, %0 3510 mov %1, %0 3511 st%I0%U0 %1, %M0" 3512 [(set_attr "length" "4,4,4") 3513 (set_attr "type" "int,int,gstore")]) 3514 3515(define_insn "*cmpsf_cc_fp" 3516 [(set (match_operand:CC_FP 0 "fcc_operand" "=u") 3517 (compare:CC_FP (match_operand:SF 1 "fpr_operand" "f") 3518 (match_operand:SF 2 "fpr_operand" "f")))] 3519 "TARGET_HARD_FLOAT" 3520 "fcmps %1,%2,%0" 3521 [(set_attr "length" "4") 3522 (set_attr "type" "fscmp")]) 3523 3524(define_insn "*cmpdf_cc_fp" 3525 [(set (match_operand:CC_FP 0 "fcc_operand" "=u") 3526 (compare:CC_FP (match_operand:DF 1 "even_fpr_operand" "h") 3527 (match_operand:DF 2 "even_fpr_operand" "h")))] 3528 "TARGET_HARD_FLOAT && TARGET_DOUBLE" 3529 "fcmpd %1,%2,%0" 3530 [(set_attr "length" "4") 3531 (set_attr "type" "fdcmp")]) 3532 3533 3534;; :::::::::::::::::::: 3535;; :: 3536;; :: Branches 3537;; :: 3538;; :::::::::::::::::::: 3539 3540;; Define_expands called by the machine independent part of the compiler 3541;; to allocate a new comparison register. 3542 3543(define_expand "cbranchdf4" 3544 [(use (match_operator 0 "ordered_comparison_operator" 3545 [(match_operand:DF 1 "fpr_operand" "") 3546 (match_operand:DF 2 "fpr_operand" "")])) 3547 (use (match_operand 3 ""))] 3548 "TARGET_HARD_FLOAT && TARGET_DOUBLE" 3549 { if (frv_emit_cond_branch (operands)) DONE; gcc_unreachable (); }) 3550 3551(define_expand "cbranchsf4" 3552 [(use (match_operator 0 "ordered_comparison_operator" 3553 [(match_operand:SF 1 "fpr_operand" "") 3554 (match_operand:SF 2 "fpr_operand" "")])) 3555 (use (match_operand 3 ""))] 3556 "TARGET_HARD_FLOAT" 3557 { if (frv_emit_cond_branch (operands)) DONE; gcc_unreachable (); }) 3558 3559(define_expand "cbranchsi4" 3560 [(use (match_operator 0 "ordered_comparison_operator" 3561 [(match_operand:SI 1 "integer_register_operand" "") 3562 (match_operand:SI 2 "gpr_or_int10_operand" "")])) 3563 (use (match_operand 3 ""))] 3564 "" 3565 { if (frv_emit_cond_branch (operands)) DONE; gcc_unreachable (); }) 3566 3567;; Actual branches. We must allow for the (label_ref) and the (pc) to be 3568;; swapped. If they are swapped, it reverses the sense of the branch. 3569;; 3570;; Note - unlike the define expands above, these patterns can be amalgamated 3571;; into one pattern for branch-if-true and one for branch-if-false. This does 3572;; require an operand operator to select the correct branch mnemonic. 3573;; 3574;; If a fixed condition code register is being used, (as opposed to, say, 3575;; using cc0), then the expands could look like this: 3576;; 3577;; (define_insn "*branch_true" 3578;; [(set (pc) 3579;; (if_then_else (match_operator:CC 0 "comparison_operator" 3580;; [(reg:CC <number_of_CC_register>) 3581;; (const_int 0)]) 3582;; (label_ref (match_operand 1 "" "")) 3583;; (pc)))] 3584;; "" 3585;; "b%B0 %1" 3586;; [(set_attr "length" "4")] 3587;; ) 3588;; 3589;; In the above example the %B is a directive to frv_print_operand() 3590;; to decode and print the correct branch mnemonic. 3591 3592(define_insn "*branch_int_true" 3593 [(set (pc) 3594 (if_then_else (match_operator 0 "integer_relational_operator" 3595 [(match_operand 1 "icc_operand" "t") 3596 (const_int 0)]) 3597 (label_ref (match_operand 2 "" "")) 3598 (pc)))] 3599 "" 3600 "* 3601{ 3602 if (get_attr_length (insn) == 4) 3603 return \"b%c0 %1,%#,%l2\"; 3604 else 3605 return \"b%C0 %1,%#,1f\;call %l2\\n1:\"; 3606}" 3607 [(set (attr "length") 3608 (if_then_else 3609 (and (ge (minus (match_dup 2) (pc)) (const_int -32768)) 3610 (le (minus (match_dup 2) (pc)) (const_int 32764))) 3611 (const_int 4) 3612 (const_int 8))) 3613 (set (attr "far_jump") 3614 (if_then_else 3615 (eq_attr "length" "4") 3616 (const_string "no") 3617 (const_string "yes"))) 3618 (set (attr "type") 3619 (if_then_else 3620 (eq_attr "length" "4") 3621 (const_string "branch") 3622 (const_string "multi")))]) 3623 3624(define_insn "*branch_int_false" 3625 [(set (pc) 3626 (if_then_else (match_operator 0 "integer_relational_operator" 3627 [(match_operand 1 "icc_operand" "t") 3628 (const_int 0)]) 3629 (pc) 3630 (label_ref (match_operand 2 "" ""))))] 3631 "" 3632 "* 3633{ 3634 if (get_attr_length (insn) == 4) 3635 return \"b%C0 %1,%#,%l2\"; 3636 else 3637 return \"b%c0 %1,%#,1f\;call %l2\\n1:\"; 3638}" 3639 [(set (attr "length") 3640 (if_then_else 3641 (and (ge (minus (match_dup 2) (pc)) (const_int -32768)) 3642 (le (minus (match_dup 2) (pc)) (const_int 32764))) 3643 (const_int 4) 3644 (const_int 8))) 3645 (set (attr "far_jump") 3646 (if_then_else 3647 (eq_attr "length" "4") 3648 (const_string "no") 3649 (const_string "yes"))) 3650 (set (attr "type") 3651 (if_then_else 3652 (eq_attr "length" "4") 3653 (const_string "branch") 3654 (const_string "multi")))]) 3655 3656(define_insn "*branch_fp_true" 3657 [(set (pc) 3658 (if_then_else (match_operator:CC_FP 0 "float_relational_operator" 3659 [(match_operand 1 "fcc_operand" "u") 3660 (const_int 0)]) 3661 (label_ref (match_operand 2 "" "")) 3662 (pc)))] 3663 "" 3664 "* 3665{ 3666 if (get_attr_length (insn) == 4) 3667 return \"fb%f0 %1,%#,%l2\"; 3668 else 3669 return \"fb%F0 %1,%#,1f\;call %l2\\n1:\"; 3670}" 3671 [(set (attr "length") 3672 (if_then_else 3673 (and (ge (minus (match_dup 2) (pc)) (const_int -32768)) 3674 (le (minus (match_dup 2) (pc)) (const_int 32764))) 3675 (const_int 4) 3676 (const_int 8))) 3677 (set (attr "far_jump") 3678 (if_then_else 3679 (eq_attr "length" "4") 3680 (const_string "no") 3681 (const_string "yes"))) 3682 (set (attr "type") 3683 (if_then_else 3684 (eq_attr "length" "4") 3685 (const_string "branch") 3686 (const_string "multi")))]) 3687 3688(define_insn "*branch_fp_false" 3689 [(set (pc) 3690 (if_then_else (match_operator:CC_FP 0 "float_relational_operator" 3691 [(match_operand 1 "fcc_operand" "u") 3692 (const_int 0)]) 3693 (pc) 3694 (label_ref (match_operand 2 "" ""))))] 3695 "" 3696 "* 3697{ 3698 if (get_attr_length (insn) == 4) 3699 return \"fb%F0 %1,%#,%l2\"; 3700 else 3701 return \"fb%f0 %1,%#,1f\;call %l2\\n1:\"; 3702}" 3703 [(set (attr "length") 3704 (if_then_else 3705 (and (ge (minus (match_dup 2) (pc)) (const_int -32768)) 3706 (le (minus (match_dup 2) (pc)) (const_int 32764))) 3707 (const_int 4) 3708 (const_int 8))) 3709 (set (attr "far_jump") 3710 (if_then_else 3711 (eq_attr "length" "4") 3712 (const_string "no") 3713 (const_string "yes"))) 3714 (set (attr "type") 3715 (if_then_else 3716 (eq_attr "length" "4") 3717 (const_string "branch") 3718 (const_string "multi")))]) 3719 3720 3721;; :::::::::::::::::::: 3722;; :: 3723;; :: Set flag operations 3724;; :: 3725;; :::::::::::::::::::: 3726 3727;; Define_expands called by the machine independent part of the compiler 3728;; to allocate a new comparison register 3729 3730(define_expand "cstoredf4" 3731 [(use (match_operator:SI 1 "ordered_comparison_operator" 3732 [(match_operand:DF 2 "fpr_operand") 3733 (match_operand:DF 3 "fpr_operand")])) 3734 (clobber (match_operand:SI 0 "register_operand"))] 3735 "TARGET_HARD_FLOAT && TARGET_DOUBLE" 3736 { if (frv_emit_scc (operands)) DONE; else FAIL; }) 3737 3738(define_expand "cstoresf4" 3739 [(use (match_operator:SI 1 "ordered_comparison_operator" 3740 [(match_operand:SF 2 "fpr_operand") 3741 (match_operand:SF 3 "fpr_operand")])) 3742 (clobber (match_operand:SI 0 "register_operand"))] 3743 "TARGET_HARD_FLOAT" 3744 { if (frv_emit_scc (operands)) DONE; else FAIL; }) 3745 3746(define_expand "cstoresi4" 3747 [(use (match_operator:SI 1 "ordered_comparison_operator" 3748 [(match_operand:SI 2 "integer_register_operand") 3749 (match_operand:SI 3 "gpr_or_int10_operand")])) 3750 (clobber (match_operand:SI 0 "register_operand"))] 3751 "" 3752 { if (frv_emit_scc (operands)) DONE; else FAIL; }) 3753 3754(define_insn "*scc_int" 3755 [(set (match_operand:SI 0 "integer_register_operand" "=d") 3756 (match_operator:SI 1 "integer_relational_operator" 3757 [(match_operand 2 "icc_operand" "t") 3758 (const_int 0)])) 3759 (clobber (match_operand:CC_CCR 3 "icr_operand" "=v"))] 3760 "" 3761 "#" 3762 [(set_attr "length" "12") 3763 (set_attr "type" "multi")]) 3764 3765(define_insn "*scc_float" 3766 [(set (match_operand:SI 0 "integer_register_operand" "=d") 3767 (match_operator:SI 1 "float_relational_operator" 3768 [(match_operand:CC_FP 2 "fcc_operand" "u") 3769 (const_int 0)])) 3770 (clobber (match_operand:CC_CCR 3 "fcr_operand" "=w"))] 3771 "" 3772 "#" 3773 [(set_attr "length" "12") 3774 (set_attr "type" "multi")]) 3775 3776;; XXX -- add reload_completed to the splits, because register allocation 3777;; currently isn't ready to see cond_exec packets. 3778(define_split 3779 [(set (match_operand:SI 0 "integer_register_operand" "") 3780 (match_operator:SI 1 "relational_operator" 3781 [(match_operand 2 "cc_operand" "") 3782 (const_int 0)])) 3783 (clobber (match_operand 3 "cr_operand" ""))] 3784 "reload_completed" 3785 [(match_dup 4)] 3786 "operands[4] = frv_split_scc (operands[0], operands[1], operands[2], 3787 operands[3], (HOST_WIDE_INT) 1);") 3788 3789(define_insn "*scc_neg1_int" 3790 [(set (match_operand:SI 0 "integer_register_operand" "=d") 3791 (neg:SI (match_operator:SI 1 "integer_relational_operator" 3792 [(match_operand 2 "icc_operand" "t") 3793 (const_int 0)]))) 3794 (clobber (match_operand:CC_CCR 3 "icr_operand" "=v"))] 3795 "" 3796 "#" 3797 [(set_attr "length" "12") 3798 (set_attr "type" "multi")]) 3799 3800(define_insn "*scc_neg1_float" 3801 [(set (match_operand:SI 0 "integer_register_operand" "=d") 3802 (neg:SI (match_operator:SI 1 "float_relational_operator" 3803 [(match_operand:CC_FP 2 "fcc_operand" "u") 3804 (const_int 0)]))) 3805 (clobber (match_operand:CC_CCR 3 "fcr_operand" "=w"))] 3806 "" 3807 "#" 3808 [(set_attr "length" "12") 3809 (set_attr "type" "multi")]) 3810 3811(define_split 3812 [(set (match_operand:SI 0 "integer_register_operand" "") 3813 (neg:SI (match_operator:SI 1 "relational_operator" 3814 [(match_operand 2 "cc_operand" "") 3815 (const_int 0)]))) 3816 (clobber (match_operand 3 "cr_operand" ""))] 3817 "reload_completed" 3818 [(match_dup 4)] 3819 "operands[4] = frv_split_scc (operands[0], operands[1], operands[2], 3820 operands[3], (HOST_WIDE_INT) -1);") 3821 3822 3823;; :::::::::::::::::::: 3824;; :: 3825;; :: Conditionally executed instructions 3826;; :: 3827;; :::::::::::::::::::: 3828 3829;; Convert ICC/FCC comparison into CCR bits so we can do conditional execution 3830(define_insn "*ck_signed" 3831 [(set (match_operand:CC_CCR 0 "icr_operand" "=v") 3832 (match_operator:CC_CCR 1 "integer_relational_operator" 3833 [(match_operand 2 "icc_operand" "t") 3834 (const_int 0)]))] 3835 "" 3836 "ck%c1 %2, %0" 3837 [(set_attr "length" "4") 3838 (set_attr "type" "ccr")]) 3839 3840(define_insn "*fck_float" 3841 [(set (match_operand:CC_CCR 0 "fcr_operand" "=w") 3842 (match_operator:CC_CCR 1 "float_relational_operator" 3843 [(match_operand:CC_FP 2 "fcc_operand" "u") 3844 (const_int 0)]))] 3845 "TARGET_HAS_FPRS" 3846 "fck%c1 %2, %0" 3847 [(set_attr "length" "4") 3848 (set_attr "type" "ccr")]) 3849 3850;; Conditionally convert ICC/FCC comparison into CCR bits to provide && and || 3851;; tests in conditional execution 3852(define_insn "cond_exec_ck" 3853 [(set (match_operand:CC_CCR 0 "cr_operand" "=v,w") 3854 (if_then_else:CC_CCR (match_operator 1 "ccr_eqne_operator" 3855 [(match_operand 2 "cr_operand" "C,C") 3856 (const_int 0)]) 3857 (match_operator 3 "relational_operator" 3858 [(match_operand 4 "cc_operand" "t,u") 3859 (const_int 0)]) 3860 (const_int 0)))] 3861 "" 3862 "@ 3863 cck%c3 %4, %0, %2, %e1 3864 cfck%f3 %4, %0, %2, %e1" 3865 [(set_attr "length" "4") 3866 (set_attr "type" "ccr")]) 3867 3868;; Conditionally set a register to either 0 or another register 3869(define_insn "*cond_exec_movqi" 3870 [(cond_exec 3871 (match_operator 0 "ccr_eqne_operator" 3872 [(match_operand 1 "cr_operand" "C,C,C,C,C,C") 3873 (const_int 0)]) 3874 (set (match_operand:QI 2 "condexec_dest_operand" "=d,d,U,?f,?f,?d") 3875 (match_operand:QI 3 "condexec_source_operand" "dO,U,dO,f,d,f")))] 3876 "register_operand(operands[2], QImode) || reg_or_0_operand (operands[3], QImode)" 3877 "* return output_condmove_single (operands, insn);" 3878 [(set_attr "length" "4") 3879 (set_attr "type" "int,gload,gstore,fsconv,movgf,movfg")]) 3880 3881(define_insn "*cond_exec_movhi" 3882 [(cond_exec 3883 (match_operator 0 "ccr_eqne_operator" 3884 [(match_operand 1 "cr_operand" "C,C,C,C,C,C") 3885 (const_int 0)]) 3886 (set (match_operand:HI 2 "condexec_dest_operand" "=d,d,U,?f,?f,?d") 3887 (match_operand:HI 3 "condexec_source_operand" "dO,U,dO,f,d,f")))] 3888 "register_operand(operands[2], HImode) || reg_or_0_operand (operands[3], HImode)" 3889 "* return output_condmove_single (operands, insn);" 3890 [(set_attr "length" "4") 3891 (set_attr "type" "int,gload,gstore,fsconv,movgf,movfg")]) 3892 3893(define_insn "*cond_exec_movsi" 3894 [(cond_exec 3895 (match_operator 0 "ccr_eqne_operator" 3896 [(match_operand 1 "cr_operand" "C,C,C,C,C,C,C,C") 3897 (const_int 0)]) 3898 (set (match_operand:SI 2 "condexec_dest_operand" "=d,d,U,?f,?f,?d,?f,?m") 3899 (match_operand:SI 3 "condexec_source_operand" "dO,U,dO,f,d,f,m,f")))] 3900 "register_operand(operands[2], SImode) || reg_or_0_operand (operands[3], SImode)" 3901 "* return output_condmove_single (operands, insn);" 3902 [(set_attr "length" "4") 3903 (set_attr "type" "int,gload,gstore,fsconv,movgf,movfg,fload,fstore")]) 3904 3905 3906(define_insn "*cond_exec_movsf_has_fprs" 3907 [(cond_exec 3908 (match_operator 0 "ccr_eqne_operator" 3909 [(match_operand 1 "cr_operand" "C,C,C,C,C,C,C,C,C,C") 3910 (const_int 0)]) 3911 (set (match_operand:SF 2 "condexec_dest_operand" "=f,?d,?d,?f,f,f,?d,U,?U,U") 3912 (match_operand:SF 3 "condexec_source_operand" "f,d,f,d,G,U,U,f,d,G")))] 3913 "TARGET_HAS_FPRS" 3914 "* return output_condmove_single (operands, insn);" 3915 [(set_attr "length" "4") 3916 (set_attr "type" "fsconv,int,movgf,movfg,movgf,fload,gload,fstore,gstore,gstore")]) 3917 3918(define_insn "*cond_exec_movsf_no_fprs" 3919 [(cond_exec 3920 (match_operator 0 "ccr_eqne_operator" 3921 [(match_operand 1 "cr_operand" "C,C,C") 3922 (const_int 0)]) 3923 (set (match_operand:SF 2 "condexec_dest_operand" "=d,d,U") 3924 (match_operand:SF 3 "condexec_source_operand" "d,U,dG")))] 3925 "! TARGET_HAS_FPRS" 3926 "* return output_condmove_single (operands, insn);" 3927 [(set_attr "length" "4") 3928 (set_attr "type" "int,gload,gstore")]) 3929 3930(define_insn "*cond_exec_si_binary1" 3931 [(cond_exec 3932 (match_operator 0 "ccr_eqne_operator" 3933 [(match_operand 1 "cr_operand" "C") 3934 (const_int 0)]) 3935 (set (match_operand:SI 2 "integer_register_operand" "=d") 3936 (match_operator:SI 3 "condexec_si_binary_operator" 3937 [(match_operand:SI 4 "integer_register_operand" "d") 3938 (match_operand:SI 5 "integer_register_operand" "d")])))] 3939 "" 3940 "* 3941{ 3942 switch (GET_CODE (operands[3])) 3943 { 3944 case PLUS: return \"cadd %4, %z5, %2, %1, %e0\"; 3945 case MINUS: return \"csub %4, %z5, %2, %1, %e0\"; 3946 case AND: return \"cand %4, %z5, %2, %1, %e0\"; 3947 case IOR: return \"cor %4, %z5, %2, %1, %e0\"; 3948 case XOR: return \"cxor %4, %z5, %2, %1, %e0\"; 3949 case ASHIFT: return \"csll %4, %z5, %2, %1, %e0\"; 3950 case ASHIFTRT: return \"csra %4, %z5, %2, %1, %e0\"; 3951 case LSHIFTRT: return \"csrl %4, %z5, %2, %1, %e0\"; 3952 default: gcc_unreachable (); 3953 } 3954}" 3955 [(set_attr "length" "4") 3956 (set_attr "type" "int")]) 3957 3958(define_insn "*cond_exec_si_binary2" 3959 [(cond_exec 3960 (match_operator 0 "ccr_eqne_operator" 3961 [(match_operand 1 "cr_operand" "C") 3962 (const_int 0)]) 3963 (set (match_operand:SI 2 "fpr_operand" "=f") 3964 (match_operator:SI 3 "condexec_si_media_operator" 3965 [(match_operand:SI 4 "fpr_operand" "f") 3966 (match_operand:SI 5 "fpr_operand" "f")])))] 3967 "TARGET_MEDIA" 3968 "* 3969{ 3970 switch (GET_CODE (operands[3])) 3971 { 3972 case AND: return \"cmand %4, %5, %2, %1, %e0\"; 3973 case IOR: return \"cmor %4, %5, %2, %1, %e0\"; 3974 case XOR: return \"cmxor %4, %5, %2, %1, %e0\"; 3975 default: gcc_unreachable (); 3976 } 3977}" 3978 [(set_attr "length" "4") 3979 (set_attr "type" "mlogic")]) 3980 3981;; Note, flow does not (currently) know how to handle an operation that uses 3982;; only part of the hard registers allocated for a multiregister value, such as 3983;; DImode in this case if the user is only interested in the lower 32-bits. So 3984;; we emit a USE of the entire register after the csmul instruction so it won't 3985;; get confused. See frv_ifcvt_modify_insn for more details. 3986 3987(define_insn "*cond_exec_si_smul" 3988 [(cond_exec 3989 (match_operator 0 "ccr_eqne_operator" 3990 [(match_operand 1 "cr_operand" "C") 3991 (const_int 0)]) 3992 (set (match_operand:DI 2 "even_gpr_operand" "=e") 3993 (mult:DI (sign_extend:DI (match_operand:SI 3 "integer_register_operand" "%d")) 3994 (sign_extend:DI (match_operand:SI 4 "integer_register_operand" "d")))))] 3995 "" 3996 "csmul %3, %4, %2, %1, %e0" 3997 [(set_attr "length" "4") 3998 (set_attr "type" "mul")]) 3999 4000(define_insn "*cond_exec_si_divide" 4001 [(cond_exec 4002 (match_operator 0 "ccr_eqne_operator" 4003 [(match_operand 1 "cr_operand" "C") 4004 (const_int 0)]) 4005 (set (match_operand:SI 2 "integer_register_operand" "=d") 4006 (match_operator:SI 3 "condexec_si_divide_operator" 4007 [(match_operand:SI 4 "integer_register_operand" "d") 4008 (match_operand:SI 5 "integer_register_operand" "d")])))] 4009 "" 4010 "* 4011{ 4012 switch (GET_CODE (operands[3])) 4013 { 4014 case DIV: return \"csdiv %4, %z5, %2, %1, %e0\"; 4015 case UDIV: return \"cudiv %4, %z5, %2, %1, %e0\"; 4016 default: gcc_unreachable (); 4017 } 4018}" 4019 [(set_attr "length" "4") 4020 (set_attr "type" "div")]) 4021 4022(define_insn "*cond_exec_si_unary1" 4023 [(cond_exec 4024 (match_operator 0 "ccr_eqne_operator" 4025 [(match_operand 1 "cr_operand" "C") 4026 (const_int 0)]) 4027 (set (match_operand:SI 2 "integer_register_operand" "=d") 4028 (match_operator:SI 3 "condexec_si_unary_operator" 4029 [(match_operand:SI 4 "integer_register_operand" "d")])))] 4030 "" 4031 "* 4032{ 4033 switch (GET_CODE (operands[3])) 4034 { 4035 case NOT: return \"cnot %4, %2, %1, %e0\"; 4036 case NEG: return \"csub %., %4, %2, %1, %e0\"; 4037 default: gcc_unreachable (); 4038 } 4039}" 4040 [(set_attr "length" "4") 4041 (set_attr "type" "int")]) 4042 4043(define_insn "*cond_exec_si_unary2" 4044 [(cond_exec 4045 (match_operator 0 "ccr_eqne_operator" 4046 [(match_operand 1 "cr_operand" "C") 4047 (const_int 0)]) 4048 (set (match_operand:SI 2 "fpr_operand" "=f") 4049 (not:SI (match_operand:SI 3 "fpr_operand" "f"))))] 4050 "TARGET_MEDIA" 4051 "cmnot %3, %2, %1, %e0" 4052 [(set_attr "length" "4") 4053 (set_attr "type" "mlogic")]) 4054 4055(define_insn "*cond_exec_cmpsi_cc" 4056 [(cond_exec 4057 (match_operator 0 "ccr_eqne_operator" 4058 [(match_operand 1 "cr_operand" "C") 4059 (const_int 0)]) 4060 (set (match_operand:CC 2 "icc_operand" "=t") 4061 (compare:CC (match_operand:SI 3 "integer_register_operand" "d") 4062 (match_operand:SI 4 "reg_or_0_operand" "dO"))))] 4063 "reload_completed 4064 && REGNO (operands[1]) == REGNO (operands[2]) - ICC_FIRST + ICR_FIRST" 4065 "ccmp %3, %z4, %1, %e0" 4066 [(set_attr "length" "4") 4067 (set_attr "type" "int")]) 4068 4069(define_insn "*cond_exec_cmpsi_cc_uns" 4070 [(cond_exec 4071 (match_operator 0 "ccr_eqne_operator" 4072 [(match_operand 1 "cr_operand" "C") 4073 (const_int 0)]) 4074 (set (match_operand:CC_UNS 2 "icc_operand" "=t") 4075 (compare:CC_UNS (match_operand:SI 3 "integer_register_operand" "d") 4076 (match_operand:SI 4 "reg_or_0_operand" "dO"))))] 4077 "reload_completed 4078 && REGNO (operands[1]) == REGNO (operands[2]) - ICC_FIRST + ICR_FIRST" 4079 "ccmp %3, %z4, %1, %e0" 4080 [(set_attr "length" "4") 4081 (set_attr "type" "int")]) 4082 4083(define_insn "*cond_exec_cmpsi_cc_nz" 4084 [(cond_exec 4085 (match_operator 0 "ccr_eqne_operator" 4086 [(match_operand 1 "cr_operand" "C") 4087 (const_int 0)]) 4088 (set (match_operand:CC_NZ 2 "icc_operand" "=t") 4089 (compare:CC_NZ (match_operand:SI 3 "integer_register_operand" "d") 4090 (const_int 0))))] 4091 "reload_completed 4092 && REGNO (operands[1]) == REGNO (operands[2]) - ICC_FIRST + ICR_FIRST" 4093 "ccmp %3, %., %1, %e0" 4094 [(set_attr "length" "4") 4095 (set_attr "type" "int")]) 4096 4097(define_insn "*cond_exec_sf_conv" 4098 [(cond_exec 4099 (match_operator 0 "ccr_eqne_operator" 4100 [(match_operand 1 "cr_operand" "C") 4101 (const_int 0)]) 4102 (set (match_operand:SF 2 "fpr_operand" "=f") 4103 (match_operator:SF 3 "condexec_sf_conv_operator" 4104 [(match_operand:SF 4 "fpr_operand" "f")])))] 4105 "TARGET_HARD_FLOAT" 4106 "* 4107{ 4108 switch (GET_CODE (operands[3])) 4109 { 4110 case ABS: return \"cfabss %4, %2, %1, %e0\"; 4111 case NEG: return \"cfnegs %4, %2, %1, %e0\"; 4112 default: gcc_unreachable (); 4113 } 4114}" 4115 [(set_attr "length" "4") 4116 (set_attr "type" "fsconv")]) 4117 4118(define_insn "*cond_exec_sf_add" 4119 [(cond_exec 4120 (match_operator 0 "ccr_eqne_operator" 4121 [(match_operand 1 "cr_operand" "C") 4122 (const_int 0)]) 4123 (set (match_operand:SF 2 "fpr_operand" "=f") 4124 (match_operator:SF 3 "condexec_sf_add_operator" 4125 [(match_operand:SF 4 "fpr_operand" "f") 4126 (match_operand:SF 5 "fpr_operand" "f")])))] 4127 "TARGET_HARD_FLOAT" 4128 "* 4129{ 4130 switch (GET_CODE (operands[3])) 4131 { 4132 case PLUS: return \"cfadds %4, %5, %2, %1, %e0\"; 4133 case MINUS: return \"cfsubs %4, %5, %2, %1, %e0\"; 4134 default: gcc_unreachable (); 4135 } 4136}" 4137 [(set_attr "length" "4") 4138 (set_attr "type" "fsadd")]) 4139 4140(define_insn "*cond_exec_sf_mul" 4141 [(cond_exec 4142 (match_operator 0 "ccr_eqne_operator" 4143 [(match_operand 1 "cr_operand" "C") 4144 (const_int 0)]) 4145 (set (match_operand:SF 2 "fpr_operand" "=f") 4146 (mult:SF (match_operand:SF 3 "fpr_operand" "f") 4147 (match_operand:SF 4 "fpr_operand" "f"))))] 4148 "TARGET_HARD_FLOAT" 4149 "cfmuls %3, %4, %2, %1, %e0" 4150 [(set_attr "length" "4") 4151 (set_attr "type" "fsmul")]) 4152 4153(define_insn "*cond_exec_sf_div" 4154 [(cond_exec 4155 (match_operator 0 "ccr_eqne_operator" 4156 [(match_operand 1 "cr_operand" "C") 4157 (const_int 0)]) 4158 (set (match_operand:SF 2 "fpr_operand" "=f") 4159 (div:SF (match_operand:SF 3 "fpr_operand" "f") 4160 (match_operand:SF 4 "fpr_operand" "f"))))] 4161 "TARGET_HARD_FLOAT" 4162 "cfdivs %3, %4, %2, %1, %e0" 4163 [(set_attr "length" "4") 4164 (set_attr "type" "fsdiv")]) 4165 4166(define_insn "*cond_exec_sf_sqrt" 4167 [(cond_exec 4168 (match_operator 0 "ccr_eqne_operator" 4169 [(match_operand 1 "cr_operand" "C") 4170 (const_int 0)]) 4171 (set (match_operand:SF 2 "fpr_operand" "=f") 4172 (sqrt:SF (match_operand:SF 3 "fpr_operand" "f"))))] 4173 "TARGET_HARD_FLOAT" 4174 "cfsqrts %3, %2, %1, %e0" 4175 [(set_attr "length" "4") 4176 (set_attr "type" "fsdiv")]) 4177 4178(define_insn "*cond_exec_cmpsi_cc_fp" 4179 [(cond_exec 4180 (match_operator 0 "ccr_eqne_operator" 4181 [(match_operand 1 "cr_operand" "C") 4182 (const_int 0)]) 4183 (set (match_operand:CC_FP 2 "fcc_operand" "=u") 4184 (compare:CC_FP (match_operand:SF 3 "fpr_operand" "f") 4185 (match_operand:SF 4 "fpr_operand" "f"))))] 4186 "reload_completed && TARGET_HARD_FLOAT 4187 && REGNO (operands[1]) == REGNO (operands[2]) - FCC_FIRST + FCR_FIRST" 4188 "cfcmps %3, %4, %2, %1, %e0" 4189 [(set_attr "length" "4") 4190 (set_attr "type" "fsconv")]) 4191 4192 4193;; :::::::::::::::::::: 4194;; :: 4195;; :: Logical operations on CR registers 4196;; :: 4197;; :::::::::::::::::::: 4198 4199;; We use UNSPEC to encode andcr/iorcr/etc. rather than the normal RTL 4200;; operations, since the RTL operations only have an idea of TRUE and FALSE, 4201;; while the CRs have TRUE, FALSE, and UNDEFINED. 4202 4203(define_expand "andcr" 4204 [(set (match_operand:CC_CCR 0 "cr_operand" "") 4205 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "") 4206 (match_operand:CC_CCR 2 "cr_operand" "") 4207 (const_int 0)] UNSPEC_CR_LOGIC))] 4208 "" 4209 "") 4210 4211(define_expand "orcr" 4212 [(set (match_operand:CC_CCR 0 "cr_operand" "") 4213 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "") 4214 (match_operand:CC_CCR 2 "cr_operand" "") 4215 (const_int 1)] UNSPEC_CR_LOGIC))] 4216 "" 4217 "") 4218 4219(define_expand "xorcr" 4220 [(set (match_operand:CC_CCR 0 "cr_operand" "") 4221 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "") 4222 (match_operand:CC_CCR 2 "cr_operand" "") 4223 (const_int 2)] UNSPEC_CR_LOGIC))] 4224 "" 4225 "") 4226 4227(define_expand "nandcr" 4228 [(set (match_operand:CC_CCR 0 "cr_operand" "") 4229 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "") 4230 (match_operand:CC_CCR 2 "cr_operand" "") 4231 (const_int 3)] UNSPEC_CR_LOGIC))] 4232 "" 4233 "") 4234 4235(define_expand "norcr" 4236 [(set (match_operand:CC_CCR 0 "cr_operand" "") 4237 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "") 4238 (match_operand:CC_CCR 2 "cr_operand" "") 4239 (const_int 4)] UNSPEC_CR_LOGIC))] 4240 "" 4241 "") 4242 4243(define_expand "andncr" 4244 [(set (match_operand:CC_CCR 0 "cr_operand" "") 4245 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "") 4246 (match_operand:CC_CCR 2 "cr_operand" "") 4247 (const_int 5)] UNSPEC_CR_LOGIC))] 4248 "" 4249 "") 4250 4251(define_expand "orncr" 4252 [(set (match_operand:CC_CCR 0 "cr_operand" "") 4253 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "") 4254 (match_operand:CC_CCR 2 "cr_operand" "") 4255 (const_int 6)] UNSPEC_CR_LOGIC))] 4256 "" 4257 "") 4258 4259(define_expand "nandncr" 4260 [(set (match_operand:CC_CCR 0 "cr_operand" "") 4261 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "") 4262 (match_operand:CC_CCR 2 "cr_operand" "") 4263 (const_int 7)] UNSPEC_CR_LOGIC))] 4264 "" 4265 "") 4266 4267(define_expand "norncr" 4268 [(set (match_operand:CC_CCR 0 "cr_operand" "") 4269 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "") 4270 (match_operand:CC_CCR 2 "cr_operand" "") 4271 (const_int 8)] UNSPEC_CR_LOGIC))] 4272 "" 4273 "") 4274 4275(define_expand "notcr" 4276 [(set (match_operand:CC_CCR 0 "cr_operand" "") 4277 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "") 4278 (match_dup 1) 4279 (const_int 9)] UNSPEC_CR_LOGIC))] 4280 "" 4281 "") 4282 4283(define_insn "*logical_cr" 4284 [(set (match_operand:CC_CCR 0 "cr_operand" "=C") 4285 (unspec:CC_CCR [(match_operand:CC_CCR 1 "cr_operand" "C") 4286 (match_operand:CC_CCR 2 "cr_operand" "C") 4287 (match_operand:SI 3 "const_int_operand" "n")] 4288 UNSPEC_CR_LOGIC))] 4289 "" 4290 "* 4291{ 4292 switch (INTVAL (operands[3])) 4293 { 4294 default: break; 4295 case 0: return \"andcr %1, %2, %0\"; 4296 case 1: return \"orcr %1, %2, %0\"; 4297 case 2: return \"xorcr %1, %2, %0\"; 4298 case 3: return \"nandcr %1, %2, %0\"; 4299 case 4: return \"norcr %1, %2, %0\"; 4300 case 5: return \"andncr %1, %2, %0\"; 4301 case 6: return \"orncr %1, %2, %0\"; 4302 case 7: return \"nandncr %1, %2, %0\"; 4303 case 8: return \"norncr %1, %2, %0\"; 4304 case 9: return \"notcr %1, %0\"; 4305 } 4306 4307 fatal_insn (\"logical_cr\", insn); 4308}" 4309 [(set_attr "length" "4") 4310 (set_attr "type" "ccr")]) 4311 4312 4313;; :::::::::::::::::::: 4314;; :: 4315;; :: Conditional move instructions 4316;; :: 4317;; :::::::::::::::::::: 4318 4319 4320;; - conditional moves based on floating-point comparisons require 4321;; TARGET_HARD_FLOAT, because an FPU is required to do the comparison. 4322 4323;; - conditional moves between FPRs based on integer comparisons 4324;; require TARGET_HAS_FPRS. 4325 4326(define_expand "movqicc" 4327 [(set (match_operand:QI 0 "integer_register_operand" "") 4328 (if_then_else:QI (match_operand 1 "" "") 4329 (match_operand:QI 2 "gpr_or_int_operand" "") 4330 (match_operand:QI 3 "gpr_or_int_operand" "")))] 4331 "TARGET_COND_MOVE" 4332 " 4333{ 4334 if (!frv_emit_cond_move (operands[0], operands[1], operands[2], operands[3])) 4335 FAIL; 4336 4337 DONE; 4338}") 4339 4340(define_insn "*movqicc_internal1_int" 4341 [(set (match_operand:QI 0 "integer_register_operand" "=d,d,d") 4342 (if_then_else:QI (match_operator 1 "integer_relational_operator" 4343 [(match_operand 2 "icc_operand" "t,t,t") 4344 (const_int 0)]) 4345 (match_operand:QI 3 "reg_or_0_operand" "0,dO,dO") 4346 (match_operand:QI 4 "reg_or_0_operand" "dO,0,dO"))) 4347 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))] 4348 "" 4349 "#" 4350 [(set_attr "length" "8,8,12") 4351 (set_attr "type" "multi")]) 4352 4353(define_insn "*movqicc_internal1_float" 4354 [(set (match_operand:QI 0 "integer_register_operand" "=d,d,d") 4355 (if_then_else:QI (match_operator:CC_FP 1 "float_relational_operator" 4356 [(match_operand:CC_FP 2 "fcc_operand" "u,u,u") 4357 (const_int 0)]) 4358 (match_operand:QI 3 "reg_or_0_operand" "0,dO,dO") 4359 (match_operand:QI 4 "reg_or_0_operand" "dO,0,dO"))) 4360 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))] 4361 "TARGET_HARD_FLOAT" 4362 "#" 4363 [(set_attr "length" "8,8,12") 4364 (set_attr "type" "multi")]) 4365 4366(define_insn "*movqicc_internal2_int" 4367 [(set (match_operand:QI 0 "integer_register_operand" "=d,d,d,d,d") 4368 (if_then_else:QI (match_operator 1 "integer_relational_operator" 4369 [(match_operand 2 "icc_operand" "t,t,t,t,t") 4370 (const_int 0)]) 4371 (match_operand:QI 3 "const_int_operand" "O,O,L,n,n") 4372 (match_operand:QI 4 "const_int_operand" "L,n,O,O,n"))) 4373 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v,v,v"))] 4374 "(INTVAL (operands[3]) == 0 4375 || INTVAL (operands[4]) == 0 4376 || (IN_RANGE (INTVAL (operands[3]), -2048, 2047) 4377 && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))" 4378 "#" 4379 [(set_attr "length" "8,12,8,12,12") 4380 (set_attr "type" "multi")]) 4381 4382(define_insn "*movqicc_internal2_float" 4383 [(set (match_operand:QI 0 "integer_register_operand" "=d,d,d,d,d") 4384 (if_then_else:QI (match_operator:CC_FP 1 "float_relational_operator" 4385 [(match_operand:CC_FP 2 "fcc_operand" "u,u,u,u,u") 4386 (const_int 0)]) 4387 (match_operand:QI 3 "const_int_operand" "O,O,L,n,n") 4388 (match_operand:QI 4 "const_int_operand" "L,n,O,O,n"))) 4389 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w,w,w"))] 4390 "TARGET_HARD_FLOAT 4391 && (INTVAL (operands[3]) == 0 4392 || INTVAL (operands[4]) == 0 4393 || (IN_RANGE (INTVAL (operands[3]), -2048, 2047) 4394 && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))" 4395 "#" 4396 [(set_attr "length" "8,12,8,12,12") 4397 (set_attr "type" "multi")]) 4398 4399(define_split 4400 [(set (match_operand:QI 0 "integer_register_operand" "") 4401 (if_then_else:QI (match_operator 1 "relational_operator" 4402 [(match_operand 2 "cc_operand" "") 4403 (const_int 0)]) 4404 (match_operand:QI 3 "gpr_or_int_operand" "") 4405 (match_operand:QI 4 "gpr_or_int_operand" ""))) 4406 (clobber (match_operand:CC_CCR 5 "cr_operand" ""))] 4407 "reload_completed" 4408 [(match_dup 6)] 4409 "operands[6] = frv_split_cond_move (operands);") 4410 4411(define_expand "movhicc" 4412 [(set (match_operand:HI 0 "integer_register_operand" "") 4413 (if_then_else:HI (match_operand 1 "" "") 4414 (match_operand:HI 2 "gpr_or_int_operand" "") 4415 (match_operand:HI 3 "gpr_or_int_operand" "")))] 4416 "TARGET_COND_MOVE" 4417 " 4418{ 4419 if (!frv_emit_cond_move (operands[0], operands[1], operands[2], operands[3])) 4420 FAIL; 4421 4422 DONE; 4423}") 4424 4425(define_insn "*movhicc_internal1_int" 4426 [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d") 4427 (if_then_else:HI (match_operator 1 "integer_relational_operator" 4428 [(match_operand 2 "icc_operand" "t,t,t") 4429 (const_int 0)]) 4430 (match_operand:HI 3 "reg_or_0_operand" "0,dO,dO") 4431 (match_operand:HI 4 "reg_or_0_operand" "dO,0,dO"))) 4432 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))] 4433 "" 4434 "#" 4435 [(set_attr "length" "8,8,12") 4436 (set_attr "type" "multi")]) 4437 4438(define_insn "*movhicc_internal1_float" 4439 [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d") 4440 (if_then_else:HI (match_operator:CC_FP 1 "float_relational_operator" 4441 [(match_operand:CC_FP 2 "fcc_operand" "u,u,u") 4442 (const_int 0)]) 4443 (match_operand:HI 3 "reg_or_0_operand" "0,dO,dO") 4444 (match_operand:HI 4 "reg_or_0_operand" "dO,0,dO"))) 4445 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))] 4446 "TARGET_HARD_FLOAT" 4447 "#" 4448 [(set_attr "length" "8,8,12") 4449 (set_attr "type" "multi")]) 4450 4451(define_insn "*movhicc_internal2_int" 4452 [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d,d,d") 4453 (if_then_else:HI (match_operator 1 "integer_relational_operator" 4454 [(match_operand 2 "icc_operand" "t,t,t,t,t") 4455 (const_int 0)]) 4456 (match_operand:HI 3 "const_int_operand" "O,O,L,n,n") 4457 (match_operand:HI 4 "const_int_operand" "L,n,O,O,n"))) 4458 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v,v,v"))] 4459 "(INTVAL (operands[3]) == 0 4460 || INTVAL (operands[4]) == 0 4461 || (IN_RANGE (INTVAL (operands[3]), -2048, 2047) 4462 && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))" 4463 "#" 4464 [(set_attr "length" "8,12,8,12,12") 4465 (set_attr "type" "multi")]) 4466 4467(define_insn "*movhicc_internal2_float" 4468 [(set (match_operand:HI 0 "integer_register_operand" "=d,d,d,d,d") 4469 (if_then_else:HI (match_operator:CC_FP 1 "float_relational_operator" 4470 [(match_operand:CC_FP 2 "fcc_operand" "u,u,u,u,u") 4471 (const_int 0)]) 4472 (match_operand:HI 3 "const_int_operand" "O,O,L,n,n") 4473 (match_operand:HI 4 "const_int_operand" "L,n,O,O,n"))) 4474 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w,w,w"))] 4475 "TARGET_HARD_FLOAT 4476 && (INTVAL (operands[3]) == 0 4477 || INTVAL (operands[4]) == 0 4478 || (IN_RANGE (INTVAL (operands[3]), -2048, 2047) 4479 && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))" 4480 "#" 4481 [(set_attr "length" "8,12,8,12,12") 4482 (set_attr "type" "multi")]) 4483 4484(define_split 4485 [(set (match_operand:HI 0 "integer_register_operand" "") 4486 (if_then_else:HI (match_operator 1 "relational_operator" 4487 [(match_operand 2 "cc_operand" "") 4488 (const_int 0)]) 4489 (match_operand:HI 3 "gpr_or_int_operand" "") 4490 (match_operand:HI 4 "gpr_or_int_operand" ""))) 4491 (clobber (match_operand:CC_CCR 5 "cr_operand" ""))] 4492 "reload_completed" 4493 [(match_dup 6)] 4494 "operands[6] = frv_split_cond_move (operands);") 4495 4496(define_expand "movsicc" 4497 [(set (match_operand:SI 0 "integer_register_operand" "") 4498 (if_then_else:SI (match_operand 1 "" "") 4499 (match_operand:SI 2 "gpr_or_int_operand" "") 4500 (match_operand:SI 3 "gpr_or_int_operand" "")))] 4501 "TARGET_COND_MOVE" 4502 " 4503{ 4504 if (!frv_emit_cond_move (operands[0], operands[1], operands[2], operands[3])) 4505 FAIL; 4506 4507 DONE; 4508}") 4509 4510(define_insn "*movsicc_internal1_int" 4511 [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d") 4512 (if_then_else:SI (match_operator 1 "integer_relational_operator" 4513 [(match_operand 2 "icc_operand" "t,t,t") 4514 (const_int 0)]) 4515 (match_operand:SI 3 "reg_or_0_operand" "0,dO,dO") 4516 (match_operand:SI 4 "reg_or_0_operand" "dO,0,dO"))) 4517 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))] 4518 "" 4519 "#" 4520 [(set_attr "length" "8,8,12") 4521 (set_attr "type" "multi")]) 4522 4523(define_insn "*movsicc_internal1_float" 4524 [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d") 4525 (if_then_else:SI (match_operator:CC_FP 1 "float_relational_operator" 4526 [(match_operand:CC_FP 2 "fcc_operand" "u,u,u") 4527 (const_int 0)]) 4528 (match_operand:SI 3 "reg_or_0_operand" "0,dO,dO") 4529 (match_operand:SI 4 "reg_or_0_operand" "dO,0,dO"))) 4530 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))] 4531 "TARGET_HARD_FLOAT" 4532 "#" 4533 [(set_attr "length" "8,8,12") 4534 (set_attr "type" "multi")]) 4535 4536(define_insn "*movsicc_internal2_int" 4537 [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d,d,d") 4538 (if_then_else:SI (match_operator 1 "integer_relational_operator" 4539 [(match_operand 2 "icc_operand" "t,t,t,t,t") 4540 (const_int 0)]) 4541 (match_operand:SI 3 "const_int_operand" "O,O,L,n,n") 4542 (match_operand:SI 4 "const_int_operand" "L,n,O,O,n"))) 4543 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v,v,v"))] 4544 "(INTVAL (operands[3]) == 0 4545 || INTVAL (operands[4]) == 0 4546 || (IN_RANGE (INTVAL (operands[3]), -2048, 2047) 4547 && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))" 4548 "#" 4549 [(set_attr "length" "8,12,8,12,12") 4550 (set_attr "type" "multi")]) 4551 4552(define_insn "*movsicc_internal2_float" 4553 [(set (match_operand:SI 0 "integer_register_operand" "=d,d,d,d,d") 4554 (if_then_else:SI (match_operator:CC_FP 1 "float_relational_operator" 4555 [(match_operand:CC_FP 2 "fcc_operand" "u,u,u,u,u") 4556 (const_int 0)]) 4557 (match_operand:SI 3 "const_int_operand" "O,O,L,n,n") 4558 (match_operand:SI 4 "const_int_operand" "L,n,O,O,n"))) 4559 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w,w,w"))] 4560 "TARGET_HARD_FLOAT 4561 && (INTVAL (operands[3]) == 0 4562 || INTVAL (operands[4]) == 0 4563 || (IN_RANGE (INTVAL (operands[3]), -2048, 2047) 4564 && IN_RANGE (INTVAL (operands[4]) - INTVAL (operands[3]), -2048, 2047)))" 4565 "#" 4566 [(set_attr "length" "8,12,8,12,12") 4567 (set_attr "type" "multi")]) 4568 4569(define_split 4570 [(set (match_operand:SI 0 "integer_register_operand" "") 4571 (if_then_else:SI (match_operator 1 "relational_operator" 4572 [(match_operand 2 "cc_operand" "") 4573 (const_int 0)]) 4574 (match_operand:SI 3 "gpr_or_int_operand" "") 4575 (match_operand:SI 4 "gpr_or_int_operand" ""))) 4576 (clobber (match_operand:CC_CCR 5 "cr_operand" ""))] 4577 "reload_completed" 4578 [(match_dup 6)] 4579 "operands[6] = frv_split_cond_move (operands);") 4580 4581(define_expand "movsfcc" 4582 [(set (match_operand:SF 0 "register_operand" "") 4583 (if_then_else:SF (match_operand 1 "" "") 4584 (match_operand:SF 2 "register_operand" "") 4585 (match_operand:SF 3 "register_operand" "")))] 4586 "TARGET_COND_MOVE" 4587 " 4588{ 4589 if (!frv_emit_cond_move (operands[0], operands[1], operands[2], operands[3])) 4590 FAIL; 4591 4592 DONE; 4593}") 4594 4595(define_insn "*movsfcc_has_fprs_int" 4596 [(set (match_operand:SF 0 "register_operand" "=f,f,f,?f,?f,?d") 4597 (if_then_else:SF (match_operator 1 "integer_relational_operator" 4598 [(match_operand 2 "icc_operand" "t,t,t,t,t,t") 4599 (const_int 0)]) 4600 (match_operand:SF 3 "register_operand" "0,f,f,f,d,fd") 4601 (match_operand:SF 4 "register_operand" "f,0,f,d,fd,fd"))) 4602 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v,v,v,v"))] 4603 "TARGET_HAS_FPRS" 4604 "#" 4605 [(set_attr "length" "8,8,12,12,12,12") 4606 (set_attr "type" "multi")]) 4607 4608(define_insn "*movsfcc_hardfloat_float" 4609 [(set (match_operand:SF 0 "register_operand" "=f,f,f,?f,?f,?d") 4610 (if_then_else:SF (match_operator:CC_FP 1 "float_relational_operator" 4611 [(match_operand:CC_FP 2 "fcc_operand" "u,u,u,u,u,u") 4612 (const_int 0)]) 4613 (match_operand:SF 3 "register_operand" "0,f,f,f,d,fd") 4614 (match_operand:SF 4 "register_operand" "f,0,f,d,fd,fd"))) 4615 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w,w,w,w"))] 4616 "TARGET_HARD_FLOAT" 4617 "#" 4618 [(set_attr "length" "8,8,12,12,12,12") 4619 (set_attr "type" "multi")]) 4620 4621(define_insn "*movsfcc_no_fprs_int" 4622 [(set (match_operand:SF 0 "integer_register_operand" "=d,d,d") 4623 (if_then_else:SF (match_operator 1 "integer_relational_operator" 4624 [(match_operand 2 "icc_operand" "t,t,t") 4625 (const_int 0)]) 4626 (match_operand:SF 3 "integer_register_operand" "0,d,d") 4627 (match_operand:SF 4 "integer_register_operand" "d,0,d"))) 4628 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))] 4629 "! TARGET_HAS_FPRS" 4630 "#" 4631 [(set_attr "length" "8,8,12") 4632 (set_attr "type" "multi")]) 4633 4634(define_split 4635 [(set (match_operand:SF 0 "register_operand" "") 4636 (if_then_else:SF (match_operator 1 "relational_operator" 4637 [(match_operand 2 "cc_operand" "") 4638 (const_int 0)]) 4639 (match_operand:SF 3 "register_operand" "") 4640 (match_operand:SF 4 "register_operand" ""))) 4641 (clobber (match_operand:CC_CCR 5 "cr_operand" ""))] 4642 "reload_completed" 4643 [(match_dup 6)] 4644 "operands[6] = frv_split_cond_move (operands);") 4645 4646 4647;; :::::::::::::::::::: 4648;; :: 4649;; :: Minimum, maximum, and integer absolute value 4650;; :: 4651;; :::::::::::::::::::: 4652 4653;; These 'instructions' are provided to give the compiler a slightly better 4654;; nudge at register allocation, then it would if it constructed the 4655;; instructions from basic building blocks (since it indicates it prefers one 4656;; of the operands to be the same as the destination. It also helps the 4657;; earlier passes of the compiler, by not breaking things into small basic 4658;; blocks. 4659 4660(define_expand "abssi2" 4661 [(parallel [(set (match_operand:SI 0 "integer_register_operand" "") 4662 (abs:SI (match_operand:SI 1 "integer_register_operand" ""))) 4663 (clobber (match_dup 2)) 4664 (clobber (match_dup 3))])] 4665 "TARGET_COND_MOVE" 4666 " 4667{ 4668 operands[2] = gen_reg_rtx (CCmode); 4669 operands[3] = gen_reg_rtx (CC_CCRmode); 4670}") 4671 4672(define_insn_and_split "*abssi2_internal" 4673 [(set (match_operand:SI 0 "integer_register_operand" "=d,d") 4674 (abs:SI (match_operand:SI 1 "integer_register_operand" "0,d"))) 4675 (clobber (match_operand:CC 2 "icc_operand" "=t,t")) 4676 (clobber (match_operand:CC_CCR 3 "icr_operand" "=v,v"))] 4677 "TARGET_COND_MOVE" 4678 "#" 4679 "reload_completed" 4680 [(match_dup 4)] 4681 "operands[4] = frv_split_abs (operands);" 4682 [(set_attr "length" "12,16") 4683 (set_attr "type" "multi")]) 4684 4685(define_expand "sminsi3" 4686 [(parallel [(set (match_operand:SI 0 "integer_register_operand" "") 4687 (smin:SI (match_operand:SI 1 "integer_register_operand" "") 4688 (match_operand:SI 2 "gpr_or_int10_operand" ""))) 4689 (clobber (match_dup 3)) 4690 (clobber (match_dup 4))])] 4691 "TARGET_COND_MOVE" 4692 " 4693{ 4694 operands[3] = gen_reg_rtx (CCmode); 4695 operands[4] = gen_reg_rtx (CC_CCRmode); 4696}") 4697 4698(define_expand "smaxsi3" 4699 [(parallel [(set (match_operand:SI 0 "integer_register_operand" "") 4700 (smax:SI (match_operand:SI 1 "integer_register_operand" "") 4701 (match_operand:SI 2 "gpr_or_int10_operand" ""))) 4702 (clobber (match_dup 3)) 4703 (clobber (match_dup 4))])] 4704 "TARGET_COND_MOVE" 4705 " 4706{ 4707 operands[3] = gen_reg_rtx (CCmode); 4708 operands[4] = gen_reg_rtx (CC_CCRmode); 4709}") 4710 4711(define_insn_and_split "*minmax_si_signed" 4712 [(set (match_operand:SI 0 "integer_register_operand" "=d,d,&d") 4713 (match_operator:SI 1 "minmax_operator" 4714 [(match_operand:SI 2 "integer_register_operand" "%0,dO,d") 4715 (match_operand:SI 3 "gpr_or_int10_operand" "dO,0,dJ")])) 4716 (clobber (match_operand:CC 4 "icc_operand" "=t,t,t")) 4717 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))] 4718 "TARGET_COND_MOVE" 4719 "#" 4720 "reload_completed" 4721 [(match_dup 6)] 4722 "operands[6] = frv_split_minmax (operands);" 4723 [(set_attr "length" "12,12,16") 4724 (set_attr "type" "multi")]) 4725 4726(define_expand "uminsi3" 4727 [(parallel [(set (match_operand:SI 0 "integer_register_operand" "") 4728 (umin:SI (match_operand:SI 1 "integer_register_operand" "") 4729 (match_operand:SI 2 "gpr_or_int10_operand" ""))) 4730 (clobber (match_dup 3)) 4731 (clobber (match_dup 4))])] 4732 "TARGET_COND_MOVE" 4733 " 4734{ 4735 operands[3] = gen_reg_rtx (CC_UNSmode); 4736 operands[4] = gen_reg_rtx (CC_CCRmode); 4737}") 4738 4739(define_expand "umaxsi3" 4740 [(parallel [(set (match_operand:SI 0 "integer_register_operand" "") 4741 (umax:SI (match_operand:SI 1 "integer_register_operand" "") 4742 (match_operand:SI 2 "gpr_or_int10_operand" ""))) 4743 (clobber (match_dup 3)) 4744 (clobber (match_dup 4))])] 4745 "TARGET_COND_MOVE" 4746 " 4747{ 4748 operands[3] = gen_reg_rtx (CC_UNSmode); 4749 operands[4] = gen_reg_rtx (CC_CCRmode); 4750}") 4751 4752(define_insn_and_split "*minmax_si_unsigned" 4753 [(set (match_operand:SI 0 "integer_register_operand" "=d,d,&d") 4754 (match_operator:SI 1 "minmax_operator" 4755 [(match_operand:SI 2 "integer_register_operand" "%0,dO,d") 4756 (match_operand:SI 3 "gpr_or_int10_operand" "dO,0,dJ")])) 4757 (clobber (match_operand:CC_UNS 4 "icc_operand" "=t,t,t")) 4758 (clobber (match_operand:CC_CCR 5 "icr_operand" "=v,v,v"))] 4759 "TARGET_COND_MOVE" 4760 "#" 4761 "reload_completed" 4762 [(match_dup 6)] 4763 "operands[6] = frv_split_minmax (operands);" 4764 [(set_attr "length" "12,12,16") 4765 (set_attr "type" "multi")]) 4766 4767(define_expand "sminsf3" 4768 [(parallel [(set (match_operand:SF 0 "fpr_operand" "") 4769 (smin:SF (match_operand:SF 1 "fpr_operand" "") 4770 (match_operand:SF 2 "fpr_operand" ""))) 4771 (clobber (match_dup 3)) 4772 (clobber (match_dup 4))])] 4773 "TARGET_COND_MOVE && TARGET_HARD_FLOAT" 4774 " 4775{ 4776 operands[3] = gen_reg_rtx (CC_FPmode); 4777 operands[4] = gen_reg_rtx (CC_CCRmode); 4778}") 4779 4780(define_expand "smaxsf3" 4781 [(parallel [(set (match_operand:SF 0 "fpr_operand" "") 4782 (smax:SF (match_operand:SF 1 "fpr_operand" "") 4783 (match_operand:SF 2 "fpr_operand" ""))) 4784 (clobber (match_dup 3)) 4785 (clobber (match_dup 4))])] 4786 "TARGET_COND_MOVE && TARGET_HARD_FLOAT" 4787 " 4788{ 4789 operands[3] = gen_reg_rtx (CC_FPmode); 4790 operands[4] = gen_reg_rtx (CC_CCRmode); 4791}") 4792 4793(define_insn_and_split "*minmax_sf" 4794 [(set (match_operand:SF 0 "fpr_operand" "=f,f,f") 4795 (match_operator:SF 1 "minmax_operator" 4796 [(match_operand:SF 2 "fpr_operand" "%0,f,f") 4797 (match_operand:SF 3 "fpr_operand" "f,0,f")])) 4798 (clobber (match_operand:CC_FP 4 "fcc_operand" "=u,u,u")) 4799 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))] 4800 "TARGET_COND_MOVE && TARGET_HARD_FLOAT" 4801 "#" 4802 "reload_completed" 4803 [(match_dup 6)] 4804 "operands[6] = frv_split_minmax (operands);" 4805 [(set_attr "length" "12,12,16") 4806 (set_attr "type" "multi")]) 4807 4808(define_expand "smindf3" 4809 [(parallel [(set (match_operand:DF 0 "fpr_operand" "") 4810 (smin:DF (match_operand:DF 1 "fpr_operand" "") 4811 (match_operand:DF 2 "fpr_operand" ""))) 4812 (clobber (match_dup 3)) 4813 (clobber (match_dup 4))])] 4814 "TARGET_COND_MOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE" 4815 " 4816{ 4817 operands[3] = gen_reg_rtx (CC_FPmode); 4818 operands[4] = gen_reg_rtx (CC_CCRmode); 4819}") 4820 4821(define_expand "smaxdf3" 4822 [(parallel [(set (match_operand:DF 0 "fpr_operand" "") 4823 (smax:DF (match_operand:DF 1 "fpr_operand" "") 4824 (match_operand:DF 2 "fpr_operand" ""))) 4825 (clobber (match_dup 3)) 4826 (clobber (match_dup 4))])] 4827 "TARGET_COND_MOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE" 4828 " 4829{ 4830 operands[3] = gen_reg_rtx (CC_FPmode); 4831 operands[4] = gen_reg_rtx (CC_CCRmode); 4832}") 4833 4834(define_insn_and_split "*minmax_df" 4835 [(set (match_operand:DF 0 "fpr_operand" "=f,f,f") 4836 (match_operator:DF 1 "minmax_operator" 4837 [(match_operand:DF 2 "fpr_operand" "%0,f,f") 4838 (match_operand:DF 3 "fpr_operand" "f,0,f")])) 4839 (clobber (match_operand:CC_FP 4 "fcc_operand" "=u,u,u")) 4840 (clobber (match_operand:CC_CCR 5 "fcr_operand" "=w,w,w"))] 4841 "TARGET_COND_MOVE && TARGET_HARD_FLOAT && TARGET_DOUBLE" 4842 "#" 4843 "reload_completed" 4844 [(match_dup 6)] 4845 "operands[6] = frv_split_minmax (operands);" 4846 [(set_attr "length" "12,12,16") 4847 (set_attr "type" "multi")]) 4848 4849 4850;; :::::::::::::::::::: 4851;; :: 4852;; :: Call and branch instructions 4853;; :: 4854;; :::::::::::::::::::: 4855 4856;; Subroutine call instruction returning no value. Operand 0 is the function 4857;; to call; operand 1 is the number of bytes of arguments pushed (in mode 4858;; `SImode', except it is normally a `const_int'); operand 2 is the number of 4859;; registers used as operands. 4860 4861;; On most machines, operand 2 is not actually stored into the RTL pattern. It 4862;; is supplied for the sake of some RISC machines which need to put this 4863;; information into the assembler code; they can put it in the RTL instead of 4864;; operand 1. 4865 4866(define_expand "call" 4867 [(use (match_operand:QI 0 "" "")) 4868 (use (match_operand 1 "" "")) 4869 (use (match_operand 2 "" "")) 4870 (use (match_operand 3 "" ""))] 4871 "" 4872 " 4873{ 4874 rtx lr = gen_rtx_REG (Pmode, LR_REGNO); 4875 rtx addr; 4876 4877 gcc_assert (GET_CODE (operands[0]) == MEM); 4878 4879 addr = XEXP (operands[0], 0); 4880 if (! call_operand (addr, Pmode)) 4881 addr = force_reg (Pmode, addr); 4882 4883 if (! operands[2]) 4884 operands[2] = const0_rtx; 4885 4886 if (TARGET_FDPIC) 4887 frv_expand_fdpic_call (operands, false, false); 4888 else 4889 emit_call_insn (gen_call_internal (addr, operands[1], operands[2], lr)); 4890 4891 DONE; 4892}") 4893 4894(define_insn "call_internal" 4895 [(call (mem:QI (match_operand:SI 0 "call_operand" "S,dNOP")) 4896 (match_operand 1 "" "")) 4897 (use (match_operand 2 "" "")) 4898 (clobber (match_operand:SI 3 "lr_operand" "=l,l"))] 4899 "! TARGET_FDPIC" 4900 "@ 4901 call %0 4902 call%i0l %M0" 4903 [(set_attr "length" "4") 4904 (set_attr "type" "call,jumpl")]) 4905 4906;; The odd use of GR0 within the UNSPEC below prevents cseing or 4907;; hoisting function descriptor loads out of loops. This is almost 4908;; never desirable, since if we preserve the function descriptor in a 4909;; pair of registers, it takes two insns to move it to gr14/gr15, and 4910;; if it's in the stack, we just waste space with the store, since 4911;; we'll have to load back from memory anyway. And, in the worst 4912;; case, we may end up reusing a function descriptor still pointing at 4913;; a PLT entry, instead of to the resolved function, which means going 4914;; through the resolver for every call that uses the outdated value. 4915;; Bad! 4916 4917;; The explicit MEM inside the SPEC prevents the compiler from moving 4918;; the load before a branch after a NULL test, or before a store that 4919;; initializes a function descriptor. 4920 4921(define_insn "movdi_ldd" 4922 [(set (match_operand:DI 0 "fdpic_fptr_operand" "=e") 4923 (unspec:DI [(mem:DI (match_operand:SI 1 "ldd_address_operand" "p")) 4924 (reg:SI 0)] UNSPEC_LDD))] 4925 "" 4926 "ldd%I1 %M1, %0" 4927 [(set_attr "length" "4") 4928 (set_attr "type" "gload")]) 4929 4930(define_insn "call_fdpicdi" 4931 [(call (mem:QI (match_operand:DI 0 "fdpic_fptr_operand" "W")) 4932 (match_operand 1 "" "")) 4933 (clobber (match_operand:SI 2 "lr_operand" "=l"))] 4934 "TARGET_FDPIC" 4935 "call%i0l %M0" 4936 [(set_attr "length" "4") 4937 (set_attr "type" "jumpl")]) 4938 4939(define_insn "call_fdpicsi" 4940 [(call (mem:QI (match_operand:SI 0 "call_operand" "S,dNOP")) 4941 (match_operand 1 "" "")) 4942 (use (match_operand 2 "" "")) 4943 (use (match_operand:SI 3 "fdpic_operand" "Z,Z")) 4944 (clobber (match_operand:SI 4 "lr_operand" "=l,l"))] 4945 "TARGET_FDPIC" 4946 "@ 4947 call %0 4948 call%i0l %M0" 4949 [(set_attr "length" "4") 4950 (set_attr "type" "call,jumpl")]) 4951 4952(define_expand "sibcall" 4953 [(use (match_operand:QI 0 "" "")) 4954 (use (match_operand 1 "" "")) 4955 (use (match_operand 2 "" "")) 4956 (use (match_operand 3 "" ""))] 4957 "" 4958 " 4959{ 4960 rtx addr; 4961 4962 gcc_assert (GET_CODE (operands[0]) == MEM); 4963 4964 addr = XEXP (operands[0], 0); 4965 if (! sibcall_operand (addr, Pmode)) 4966 addr = force_reg (Pmode, addr); 4967 4968 if (! operands[2]) 4969 operands[2] = const0_rtx; 4970 4971 if (TARGET_FDPIC) 4972 frv_expand_fdpic_call (operands, false, true); 4973 else 4974 emit_call_insn (gen_sibcall_internal (addr, operands[1], operands[2])); 4975 4976 DONE; 4977}") 4978 4979;; It might seem that these sibcall patterns are missing references to 4980;; LR, but they're not necessary because sibcall_epilogue will make 4981;; sure LR is restored, and having LR here will set 4982;; regs_ever_used[REG_LR], forcing it to be saved on the stack, and 4983;; then restored in sibcalls and regular return code paths, even if 4984;; the function becomes a leaf function after tail-call elimination. 4985 4986;; We must not use a call-saved register here. `W' limits ourselves 4987;; to gr14 or gr15, but since we're almost running out of constraint 4988;; letters, and most other call-clobbered registers are often used for 4989;; argument-passing, this will do. 4990(define_insn "sibcall_internal" 4991 [(call (mem:QI (match_operand:SI 0 "sibcall_operand" "WNOP")) 4992 (match_operand 1 "" "")) 4993 (use (match_operand 2 "" "")) 4994 (return)] 4995 "! TARGET_FDPIC" 4996 "jmp%i0l %M0" 4997 [(set_attr "length" "4") 4998 (set_attr "type" "jumpl")]) 4999 5000(define_insn "sibcall_fdpicdi" 5001 [(call (mem:QI (match_operand:DI 0 "fdpic_fptr_operand" "W")) 5002 (match_operand 1 "" "")) 5003 (return)] 5004 "TARGET_FDPIC" 5005 "jmp%i0l %M0" 5006 [(set_attr "length" "4") 5007 (set_attr "type" "jumpl")]) 5008 5009 5010;; Subroutine call instruction returning a value. Operand 0 is the hard 5011;; register in which the value is returned. There are three more operands, the 5012;; same as the three operands of the `call' instruction (but with numbers 5013;; increased by one). 5014 5015;; Subroutines that return `BLKmode' objects use the `call' insn. 5016 5017(define_expand "call_value" 5018 [(use (match_operand 0 "" "")) 5019 (use (match_operand:QI 1 "" "")) 5020 (use (match_operand 2 "" "")) 5021 (use (match_operand 3 "" "")) 5022 (use (match_operand 4 "" ""))] 5023 "" 5024 " 5025{ 5026 rtx lr = gen_rtx_REG (Pmode, LR_REGNO); 5027 rtx addr; 5028 5029 gcc_assert (GET_CODE (operands[1]) == MEM); 5030 5031 addr = XEXP (operands[1], 0); 5032 if (! call_operand (addr, Pmode)) 5033 addr = force_reg (Pmode, addr); 5034 5035 if (! operands[3]) 5036 operands[3] = const0_rtx; 5037 5038 if (TARGET_FDPIC) 5039 frv_expand_fdpic_call (operands, true, false); 5040 else 5041 emit_call_insn (gen_call_value_internal (operands[0], addr, operands[2], 5042 operands[3], lr)); 5043 5044 DONE; 5045}") 5046 5047(define_insn "call_value_internal" 5048 [(set (match_operand 0 "register_operand" "=d,d") 5049 (call (mem:QI (match_operand:SI 1 "call_operand" "S,dNOP")) 5050 (match_operand 2 "" ""))) 5051 (use (match_operand 3 "" "")) 5052 (clobber (match_operand:SI 4 "lr_operand" "=l,l"))] 5053 "! TARGET_FDPIC" 5054 "@ 5055 call %1 5056 call%i1l %M1" 5057 [(set_attr "length" "4") 5058 (set_attr "type" "call,jumpl")]) 5059 5060(define_insn "call_value_fdpicdi" 5061 [(set (match_operand 0 "register_operand" "=d") 5062 (call (mem:QI (match_operand:DI 1 "fdpic_fptr_operand" "W")) 5063 (match_operand 2 "" ""))) 5064 (clobber (match_operand:SI 3 "lr_operand" "=l"))] 5065 "TARGET_FDPIC" 5066 "call%i1l %M1" 5067 [(set_attr "length" "4") 5068 (set_attr "type" "jumpl")]) 5069 5070(define_insn "call_value_fdpicsi" 5071 [(set (match_operand 0 "register_operand" "=d,d") 5072 (call (mem:QI (match_operand:SI 1 "call_operand" "S,dNOP")) 5073 (match_operand 2 "" ""))) 5074 (use (match_operand 3 "" "")) 5075 (use (match_operand:SI 4 "fdpic_operand" "Z,Z")) 5076 (clobber (match_operand:SI 5 "lr_operand" "=l,l"))] 5077 "TARGET_FDPIC" 5078 "@ 5079 call %1 5080 call%i1l %M1" 5081 [(set_attr "length" "4") 5082 (set_attr "type" "call,jumpl")]) 5083 5084(define_expand "sibcall_value" 5085 [(use (match_operand 0 "" "")) 5086 (use (match_operand:QI 1 "" "")) 5087 (use (match_operand 2 "" "")) 5088 (use (match_operand 3 "" "")) 5089 (use (match_operand 4 "" ""))] 5090 "" 5091 " 5092{ 5093 rtx addr; 5094 5095 gcc_assert (GET_CODE (operands[1]) == MEM); 5096 5097 addr = XEXP (operands[1], 0); 5098 if (! sibcall_operand (addr, Pmode)) 5099 addr = force_reg (Pmode, addr); 5100 5101 if (! operands[3]) 5102 operands[3] = const0_rtx; 5103 5104 if (TARGET_FDPIC) 5105 frv_expand_fdpic_call (operands, true, true); 5106 else 5107 emit_call_insn (gen_sibcall_value_internal (operands[0], addr, operands[2], 5108 operands[3])); 5109 DONE; 5110}") 5111 5112(define_insn "sibcall_value_internal" 5113 [(set (match_operand 0 "register_operand" "=d") 5114 (call (mem:QI (match_operand:SI 1 "sibcall_operand" "WNOP")) 5115 (match_operand 2 "" ""))) 5116 (use (match_operand 3 "" "")) 5117 (return)] 5118 "! TARGET_FDPIC" 5119 "jmp%i1l %M1" 5120 [(set_attr "length" "4") 5121 (set_attr "type" "jumpl")]) 5122 5123(define_insn "sibcall_value_fdpicdi" 5124 [(set (match_operand 0 "register_operand" "=d") 5125 (call (mem:QI (match_operand:DI 1 "fdpic_fptr_operand" "W")) 5126 (match_operand 2 "" ""))) 5127 (return)] 5128 "TARGET_FDPIC" 5129 "jmp%i1l %M1" 5130 [(set_attr "length" "4") 5131 (set_attr "type" "jumpl")]) 5132 5133;; return instruction generated instead of jmp to epilog 5134(define_expand "return" 5135 [(parallel [(return) 5136 (use (match_dup 0)) 5137 (use (const_int 1))])] 5138 "direct_return_p ()" 5139 " 5140{ 5141 operands[0] = gen_rtx_REG (Pmode, LR_REGNO); 5142}") 5143 5144;; return instruction generated by the epilogue 5145(define_expand "epilogue_return" 5146 [(parallel [(return) 5147 (use (match_operand:SI 0 "register_operand" "")) 5148 (use (const_int 0))])] 5149 "" 5150 "") 5151 5152(define_insn "*return_internal" 5153 [(return) 5154 (use (match_operand:SI 0 "register_operand" "l,d")) 5155 (use (match_operand:SI 1 "immediate_operand" "n,n"))] 5156 "" 5157 "@ 5158 ret 5159 jmpl @(%0,%.)" 5160 [(set_attr "length" "4") 5161 (set_attr "type" "jump,jumpl")]) 5162 5163(define_insn "*return_true" 5164 [(set (pc) 5165 (if_then_else (match_operator 0 "integer_relational_operator" 5166 [(match_operand 1 "icc_operand" "t") 5167 (const_int 0)]) 5168 (return) 5169 (pc)))] 5170 "direct_return_p ()" 5171 "b%c0lr %1,%#" 5172 [(set_attr "length" "4") 5173 (set_attr "type" "jump")]) 5174 5175(define_insn "*return_false" 5176 [(set (pc) 5177 (if_then_else (match_operator 0 "integer_relational_operator" 5178 [(match_operand 1 "icc_operand" "t") 5179 (const_int 0)]) 5180 (pc) 5181 (return)))] 5182 "direct_return_p ()" 5183 "b%C0lr %1,%#" 5184 [(set_attr "length" "4") 5185 (set_attr "type" "jump")]) 5186 5187;; A version of addsi3 for deallocating stack space at the end of the 5188;; epilogue. The addition is done in parallel with an (unspec_volatile), 5189;; which represents the clobbering of the deallocated space. 5190(define_insn "stack_adjust" 5191 [(set (match_operand:SI 0 "register_operand" "=d") 5192 (plus:SI (match_operand:SI 1 "register_operand" "d") 5193 (match_operand:SI 2 "general_operand" "dNOP"))) 5194 (unspec_volatile [(const_int 0)] UNSPEC_STACK_ADJUST)] 5195 "" 5196 "add%I2 %1,%2,%0" 5197 [(set_attr "length" "4") 5198 (set_attr "type" "int")]) 5199 5200;; Normal unconditional jump 5201 5202;; Use the "call" instruction for long branches, but prefer to use "bra" for 5203;; short ones since it does not force us to save the link register. 5204 5205;; This define_insn uses the branch-shortening code to decide which 5206;; instruction it emits. Since the main branch-shortening interface is 5207;; through get_attr_length(), the two alternatives must be given different 5208;; lengths. Here we pretend that the far jump is 8 rather than 4 bytes 5209;; long, though both alternatives are really the same size. 5210(define_insn "jump" 5211 [(set (pc) (label_ref (match_operand 0 "" "")))] 5212 "" 5213 "* 5214{ 5215 if (get_attr_length (insn) == 4) 5216 return \"bra %l0\"; 5217 else 5218 return \"call %l0\"; 5219}" 5220 [(set (attr "length") 5221 (if_then_else 5222 (and (ge (minus (match_dup 0) (pc)) (const_int -32768)) 5223 (le (minus (match_dup 0) (pc)) (const_int 32764))) 5224 (const_int 4) 5225 (const_int 8))) 5226 (set (attr "far_jump") 5227 (if_then_else 5228 (eq_attr "length" "4") 5229 (const_string "no") 5230 (const_string "yes"))) 5231 (set (attr "type") 5232 (if_then_else 5233 (eq_attr "length" "4") 5234 (const_string "jump") 5235 (const_string "call")))]) 5236 5237;; Indirect jump through a register 5238(define_insn "indirect_jump" 5239 [(set (pc) (match_operand:SI 0 "register_operand" "d,l"))] 5240 "" 5241 "@ 5242 jmpl @(%0,%.) 5243 bralr" 5244 [(set_attr "length" "4") 5245 (set_attr "type" "jumpl,branch")]) 5246 5247;; Instruction to jump to a variable address. This is a low-level capability 5248;; which can be used to implement a dispatch table when there is no `casesi' 5249;; pattern. Either the 'casesi' pattern or the 'tablejump' pattern, or both, 5250;; MUST be present in this file. 5251 5252;; This pattern requires two operands: the address or offset, and a label which 5253;; should immediately precede the jump table. If the macro 5254;; `CASE_VECTOR_PC_RELATIVE' is defined then the first operand is an offset 5255;; which counts from the address of the table; otherwise, it is an absolute 5256;; address to jump to. In either case, the first operand has mode `Pmode'. 5257 5258;; The `tablejump' insn is always the last insn before the jump table it uses. 5259;; Its assembler code normally has no need to use the second operand, but you 5260;; should incorporate it in the RTL pattern so that the jump optimizer will not 5261;; delete the table as unreachable code. 5262 5263(define_expand "tablejump" 5264 [(parallel [(set (pc) (match_operand:SI 0 "address_operand" "p")) 5265 (use (label_ref (match_operand 1 "" "")))])] 5266 "!flag_pic" 5267 "") 5268 5269(define_insn "tablejump_insn" 5270 [(set (pc) (match_operand:SI 0 "address_operand" "p")) 5271 (use (label_ref (match_operand 1 "" "")))] 5272 "" 5273 "jmp%I0l %M0" 5274 [(set_attr "length" "4") 5275 (set_attr "type" "jumpl")]) 5276 5277;; Implement switch statements when generating PIC code. Switches are 5278;; implemented by `tablejump' when not using -fpic. 5279 5280;; Emit code here to do the range checking and make the index zero based. 5281;; operand 0 is the index 5282;; operand 1 is the lower bound 5283;; operand 2 is the range of indices (highest - lowest + 1) 5284;; operand 3 is the label that precedes the table itself 5285;; operand 4 is the fall through label 5286 5287(define_expand "casesi" 5288 [(use (match_operand:SI 0 "integer_register_operand" "")) 5289 (use (match_operand:SI 1 "const_int_operand" "")) 5290 (use (match_operand:SI 2 "const_int_operand" "")) 5291 (use (match_operand 3 "" "")) 5292 (use (match_operand 4 "" ""))] 5293 "flag_pic" 5294 " 5295{ 5296 rtx indx; 5297 rtx scale; 5298 rtx low = operands[1]; 5299 rtx range = operands[2]; 5300 rtx table = operands[3]; 5301 rtx treg; 5302 rtx fail = operands[4]; 5303 rtx mem; 5304 rtx reg2; 5305 rtx reg3; 5306 5307 gcc_assert (GET_CODE (operands[1]) == CONST_INT); 5308 5309 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 5310 5311 /* If we can't generate an immediate instruction, promote to register. */ 5312 if (! IN_RANGE (INTVAL (range), -2048, 2047)) 5313 range = force_reg (SImode, range); 5314 5315 /* If low bound is 0, we don't have to subtract it. */ 5316 if (INTVAL (operands[1]) == 0) 5317 indx = operands[0]; 5318 else 5319 { 5320 indx = gen_reg_rtx (SImode); 5321 if (IN_RANGE (INTVAL (low), -2047, 2048)) 5322 emit_insn (gen_addsi3 (indx, operands[0], GEN_INT (- INTVAL (low)))); 5323 else 5324 emit_insn (gen_subsi3 (indx, operands[0], force_reg (SImode, low))); 5325 } 5326 5327 /* Do an unsigned comparison (in the proper mode) between the index 5328 expression and the value which represents the length of the range. 5329 Since we just finished subtracting the lower bound of the range 5330 from the index expression, this comparison allows us to simultaneously 5331 check that the original index expression value is both greater than 5332 or equal to the minimum value of the range and less than or equal to 5333 the maximum value of the range. */ 5334 5335 emit_cmp_and_jump_insns (indx, range, GTU, NULL_RTX, SImode, 1, fail); 5336 5337 /* Move the table address to a register. */ 5338 treg = gen_reg_rtx (Pmode); 5339 emit_insn (gen_movsi (treg, gen_rtx_LABEL_REF (VOIDmode, table))); 5340 5341 /* Scale index-low by wordsize. */ 5342 scale = gen_reg_rtx (SImode); 5343 emit_insn (gen_ashlsi3 (scale, indx, const2_rtx)); 5344 5345 /* Load the address, add the start of the table back in, 5346 and jump to it. */ 5347 mem = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, scale, treg)); 5348 reg2 = gen_reg_rtx (SImode); 5349 reg3 = gen_reg_rtx (SImode); 5350 emit_insn (gen_movsi (reg2, mem)); 5351 emit_insn (gen_addsi3 (reg3, reg2, treg)); 5352 emit_jump_insn (gen_tablejump_insn (reg3, table)); 5353 DONE; 5354}") 5355 5356 5357;; :::::::::::::::::::: 5358;; :: 5359;; :: Prologue and Epilogue instructions 5360;; :: 5361;; :::::::::::::::::::: 5362 5363;; Called after register allocation to add any instructions needed for the 5364;; prologue. Using a prologue insn is favored compared to putting all of the 5365;; instructions in the FUNCTION_PROLOGUE macro, since it allows the scheduler 5366;; to intermix instructions with the saves of the caller saved registers. In 5367;; some cases, it might be necessary to emit a barrier instruction as the last 5368;; insn to prevent such scheduling. 5369(define_expand "prologue" 5370 [(const_int 1)] 5371 "" 5372 " 5373{ 5374 frv_expand_prologue (); 5375 DONE; 5376}") 5377 5378;; Called after register allocation to add any instructions needed for the 5379;; epilogue. Using an epilogue insn is favored compared to putting all of the 5380;; instructions in the FUNCTION_EPILOGUE macro, since it allows the scheduler 5381;; to intermix instructions with the restores of the caller saved registers. 5382;; In some cases, it might be necessary to emit a barrier instruction as the 5383;; first insn to prevent such scheduling. 5384(define_expand "epilogue" 5385 [(const_int 2)] 5386 "" 5387 " 5388{ 5389 frv_expand_epilogue (true); 5390 DONE; 5391}") 5392 5393;; This pattern, if defined, emits RTL for exit from a function without the final 5394;; branch back to the calling function. This pattern will be emitted before any 5395;; sibling call (aka tail call) sites. 5396;; 5397;; The sibcall_epilogue pattern must not clobber any arguments used for 5398;; parameter passing or any stack slots for arguments passed to the current 5399;; function. 5400(define_expand "sibcall_epilogue" 5401 [(const_int 3)] 5402 "" 5403 " 5404{ 5405 frv_expand_epilogue (false); 5406 DONE; 5407}") 5408 5409;; Set up the pic register to hold the address of the pic table 5410(define_insn "pic_prologue" 5411 [(set (match_operand:SI 0 "integer_register_operand" "=d") 5412 (unspec_volatile:SI [(const_int 0)] UNSPEC_PIC_PROLOGUE)) 5413 (clobber (match_operand:SI 1 "lr_operand" "=l")) 5414 (clobber (match_operand:SI 2 "integer_register_operand" "=d"))] 5415 "" 5416 "* 5417{ 5418 static int frv_pic_labelno = 0; 5419 5420 operands[3] = GEN_INT (frv_pic_labelno++); 5421 return \"call %P3\\n%P3:\;movsg %1, %0\;sethi #gprelhi(%P3), %2\;setlo #gprello(%P3), %2\;sub %0,%2,%0\"; 5422}" 5423 [(set_attr "length" "16") 5424 (set_attr "type" "multi")]) 5425 5426;; :::::::::::::::::::: 5427;; :: 5428;; :: Miscellaneous instructions 5429;; :: 5430;; :::::::::::::::::::: 5431 5432;; No operation, needed in case the user uses -g but not -O. 5433(define_insn "nop" 5434 [(const_int 0)] 5435 "" 5436 "nop" 5437 [(set_attr "length" "4") 5438 (set_attr "type" "int")]) 5439 5440(define_insn "fnop" 5441 [(const_int 1)] 5442 "" 5443 "fnop" 5444 [(set_attr "length" "4") 5445 (set_attr "type" "fnop")]) 5446 5447(define_insn "mnop" 5448 [(const_int 2)] 5449 "" 5450 "mnop" 5451 [(set_attr "length" "4") 5452 (set_attr "type" "mnop")]) 5453 5454;; Pseudo instruction that prevents the scheduler from moving code above this 5455;; point. Note, type unknown is used to make sure the VLIW instructions are 5456;; not continued past this point. 5457(define_insn "blockage" 5458 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)] 5459 "" 5460 "# blockage" 5461 [(set_attr "length" "0") 5462 (set_attr "type" "unknown")]) 5463 5464;; :::::::::::::::::::: 5465;; :: 5466;; :: Media instructions 5467;; :: 5468;; :::::::::::::::::::: 5469 5470;; Unimplemented instructions: 5471;; - MCMPSH, MCMPUH 5472 5473(define_constants 5474 [(UNSPEC_MLOGIC 100) 5475 (UNSPEC_MNOT 101) 5476 (UNSPEC_MAVEH 102) 5477 (UNSPEC_MSATH 103) 5478 (UNSPEC_MADDH 104) 5479 (UNSPEC_MQADDH 105) 5480 (UNSPEC_MPACKH 106) 5481 (UNSPEC_MUNPACKH 107) 5482 (UNSPEC_MDPACKH 108) 5483 (UNSPEC_MBTOH 109) 5484 (UNSPEC_MHTOB 110) 5485 (UNSPEC_MROT 111) 5486 (UNSPEC_MSHIFT 112) 5487 (UNSPEC_MEXPDHW 113) 5488 (UNSPEC_MEXPDHD 114) 5489 (UNSPEC_MWCUT 115) 5490 (UNSPEC_MMULH 116) 5491 (UNSPEC_MMULXH 117) 5492 (UNSPEC_MMACH 118) 5493 (UNSPEC_MMRDH 119) 5494 (UNSPEC_MQMULH 120) 5495 (UNSPEC_MQMULXH 121) 5496 (UNSPEC_MQMACH 122) 5497 (UNSPEC_MCPX 123) 5498 (UNSPEC_MQCPX 124) 5499 (UNSPEC_MCUT 125) 5500 (UNSPEC_MRDACC 126) 5501 (UNSPEC_MRDACCG 127) 5502 (UNSPEC_MWTACC 128) 5503 (UNSPEC_MWTACCG 129) 5504 (UNSPEC_MTRAP 130) 5505 (UNSPEC_MCLRACC 131) 5506 (UNSPEC_MCLRACCA 132) 5507 (UNSPEC_MCOP1 133) 5508 (UNSPEC_MCOP2 134) 5509 (UNSPEC_MDUNPACKH 135) 5510 (UNSPEC_MDUNPACKH_INTERNAL 136) 5511 (UNSPEC_MBTOHE 137) 5512 (UNSPEC_MBTOHE_INTERNAL 138) 5513 (UNSPEC_MBTOHE 137) 5514 (UNSPEC_MBTOHE_INTERNAL 138) 5515 (UNSPEC_MQMACH2 139) 5516 (UNSPEC_MADDACC 140) 5517 (UNSPEC_MDADDACC 141) 5518 (UNSPEC_MABSHS 142) 5519 (UNSPEC_MDROTLI 143) 5520 (UNSPEC_MCPLHI 144) 5521 (UNSPEC_MCPLI 145) 5522 (UNSPEC_MDCUTSSI 146) 5523 (UNSPEC_MQSATHS 147) 5524 (UNSPEC_MHSETLOS 148) 5525 (UNSPEC_MHSETLOH 149) 5526 (UNSPEC_MHSETHIS 150) 5527 (UNSPEC_MHSETHIH 151) 5528 (UNSPEC_MHDSETS 152) 5529 (UNSPEC_MHDSETH 153) 5530 (UNSPEC_MQLCLRHS 154) 5531 (UNSPEC_MQLMTHS 155) 5532 (UNSPEC_MQSLLHI 156) 5533 (UNSPEC_MQSRAHI 157) 5534 (UNSPEC_MASACCS 158) 5535 (UNSPEC_MDASACCS 159) 5536]) 5537 5538;; Logic operations: type "mlogic" 5539 5540(define_expand "mand" 5541 [(set (match_operand:SI 0 "fpr_operand" "") 5542 (unspec:SI [(match_operand:SI 1 "fpr_operand" "") 5543 (match_operand:SI 2 "fpr_operand" "") 5544 (match_dup 3)] 5545 UNSPEC_MLOGIC))] 5546 "TARGET_MEDIA" 5547 "operands[3] = GEN_INT (FRV_BUILTIN_MAND);") 5548 5549(define_expand "mor" 5550 [(set (match_operand:SI 0 "fpr_operand" "") 5551 (unspec:SI [(match_operand:SI 1 "fpr_operand" "") 5552 (match_operand:SI 2 "fpr_operand" "") 5553 (match_dup 3)] 5554 UNSPEC_MLOGIC))] 5555 "TARGET_MEDIA" 5556 "operands[3] = GEN_INT (FRV_BUILTIN_MOR);") 5557 5558(define_expand "mxor" 5559 [(set (match_operand:SI 0 "fpr_operand" "") 5560 (unspec:SI [(match_operand:SI 1 "fpr_operand" "") 5561 (match_operand:SI 2 "fpr_operand" "") 5562 (match_dup 3)] 5563 UNSPEC_MLOGIC))] 5564 "TARGET_MEDIA" 5565 "operands[3] = GEN_INT (FRV_BUILTIN_MXOR);") 5566 5567(define_insn "*mlogic" 5568 [(set (match_operand:SI 0 "fpr_operand" "=f") 5569 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 5570 (match_operand:SI 2 "fpr_operand" "f") 5571 (match_operand:SI 3 "const_int_operand" "n")] 5572 UNSPEC_MLOGIC))] 5573 "TARGET_MEDIA" 5574 "* 5575{ 5576 switch (INTVAL (operands[3])) 5577 { 5578 default: break; 5579 case FRV_BUILTIN_MAND: return \"mand %1, %2, %0\"; 5580 case FRV_BUILTIN_MOR: return \"mor %1, %2, %0\"; 5581 case FRV_BUILTIN_MXOR: return \"mxor %1, %2, %0\"; 5582 } 5583 5584 fatal_insn (\"Bad media insn, mlogic\", insn); 5585}" 5586 [(set_attr "length" "4") 5587 (set_attr "type" "mlogic")]) 5588 5589(define_insn "*cond_exec_mlogic" 5590 [(cond_exec 5591 (match_operator 0 "ccr_eqne_operator" 5592 [(match_operand 1 "cr_operand" "C") 5593 (const_int 0)]) 5594 (set (match_operand:SI 2 "fpr_operand" "=f") 5595 (unspec:SI [(match_operand:SI 3 "fpr_operand" "f") 5596 (match_operand:SI 4 "fpr_operand" "f") 5597 (match_operand:SI 5 "const_int_operand" "n")] 5598 UNSPEC_MLOGIC)))] 5599 "TARGET_MEDIA" 5600 "* 5601{ 5602 switch (INTVAL (operands[5])) 5603 { 5604 default: break; 5605 case FRV_BUILTIN_MAND: return \"cmand %3, %4, %2, %1, %e0\"; 5606 case FRV_BUILTIN_MOR: return \"cmor %3, %4, %2, %1, %e0\"; 5607 case FRV_BUILTIN_MXOR: return \"cmxor %3, %4, %2, %1, %e0\"; 5608 } 5609 5610 fatal_insn (\"Bad media insn, cond_exec_mlogic\", insn); 5611}" 5612 [(set_attr "length" "4") 5613 (set_attr "type" "mlogic")]) 5614 5615;; Logical not: type "mlogic" 5616 5617(define_insn "mnot" 5618 [(set (match_operand:SI 0 "fpr_operand" "=f") 5619 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")] UNSPEC_MNOT))] 5620 "TARGET_MEDIA" 5621 "mnot %1, %0" 5622 [(set_attr "length" "4") 5623 (set_attr "type" "mlogic")]) 5624 5625(define_insn "*cond_exec_mnot" 5626 [(cond_exec 5627 (match_operator 0 "ccr_eqne_operator" 5628 [(match_operand 1 "cr_operand" "C") 5629 (const_int 0)]) 5630 (set (match_operand:SI 2 "fpr_operand" "=f") 5631 (unspec:SI [(match_operand:SI 3 "fpr_operand" "f")] UNSPEC_MNOT)))] 5632 "TARGET_MEDIA" 5633 "cmnot %3, %2, %1, %e0" 5634 [(set_attr "length" "4") 5635 (set_attr "type" "mlogic")]) 5636 5637;; Dual average (halfword): type "maveh" 5638 5639(define_insn "maveh" 5640 [(set (match_operand:SI 0 "fpr_operand" "=f") 5641 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 5642 (match_operand:SI 2 "fpr_operand" "f")] 5643 UNSPEC_MAVEH))] 5644 "TARGET_MEDIA" 5645 "maveh %1, %2, %0" 5646 [(set_attr "length" "4") 5647 (set_attr "type" "maveh")]) 5648 5649;; Dual saturation (halfword): type "msath" 5650 5651(define_expand "msaths" 5652 [(set (match_operand:SI 0 "fpr_operand" "=f") 5653 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 5654 (match_operand:SI 2 "fpr_operand" "f") 5655 (match_dup 3)] 5656 UNSPEC_MSATH))] 5657 "TARGET_MEDIA" 5658 "operands[3] = GEN_INT (FRV_BUILTIN_MSATHS);") 5659 5660(define_expand "msathu" 5661 [(set (match_operand:SI 0 "fpr_operand" "=f") 5662 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 5663 (match_operand:SI 2 "fpr_operand" "f") 5664 (match_dup 3)] 5665 UNSPEC_MSATH))] 5666 "TARGET_MEDIA" 5667 "operands[3] = GEN_INT (FRV_BUILTIN_MSATHU);") 5668 5669(define_insn "*msath" 5670 [(set (match_operand:SI 0 "fpr_operand" "=f") 5671 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 5672 (match_operand:SI 2 "fpr_operand" "f") 5673 (match_operand:SI 3 "const_int_operand" "n")] 5674 UNSPEC_MSATH))] 5675 "TARGET_MEDIA" 5676 "* 5677{ 5678 switch (INTVAL (operands[3])) 5679 { 5680 default: break; 5681 case FRV_BUILTIN_MSATHS: return \"msaths %1, %2, %0\"; 5682 case FRV_BUILTIN_MSATHU: return \"msathu %1, %2, %0\"; 5683 } 5684 5685 fatal_insn (\"Bad media insn, msath\", insn); 5686}" 5687 [(set_attr "length" "4") 5688 (set_attr "type" "msath")]) 5689 5690;; Dual addition/subtraction with saturation (halfword): type "maddh" 5691 5692(define_expand "maddhss" 5693 [(set (match_operand:SI 0 "fpr_operand" "=f") 5694 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 5695 (match_operand:SI 2 "fpr_operand" "f") 5696 (match_dup 3)] 5697 UNSPEC_MADDH))] 5698 "TARGET_MEDIA" 5699 "operands[3] = GEN_INT (FRV_BUILTIN_MADDHSS);") 5700 5701(define_expand "maddhus" 5702 [(set (match_operand:SI 0 "fpr_operand" "=f") 5703 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 5704 (match_operand:SI 2 "fpr_operand" "f") 5705 (match_dup 3)] 5706 UNSPEC_MADDH))] 5707 "TARGET_MEDIA" 5708 "operands[3] = GEN_INT (FRV_BUILTIN_MADDHUS);") 5709 5710(define_expand "msubhss" 5711 [(set (match_operand:SI 0 "fpr_operand" "=f") 5712 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 5713 (match_operand:SI 2 "fpr_operand" "f") 5714 (match_dup 3)] 5715 UNSPEC_MADDH))] 5716 "TARGET_MEDIA" 5717 "operands[3] = GEN_INT (FRV_BUILTIN_MSUBHSS);") 5718 5719(define_expand "msubhus" 5720 [(set (match_operand:SI 0 "fpr_operand" "=f") 5721 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 5722 (match_operand:SI 2 "fpr_operand" "f") 5723 (match_dup 3)] 5724 UNSPEC_MADDH))] 5725 "TARGET_MEDIA" 5726 "operands[3] = GEN_INT (FRV_BUILTIN_MSUBHUS);") 5727 5728(define_insn "*maddh" 5729 [(set (match_operand:SI 0 "fpr_operand" "=f") 5730 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 5731 (match_operand:SI 2 "fpr_operand" "f") 5732 (match_operand:SI 3 "const_int_operand" "n")] 5733 UNSPEC_MADDH))] 5734 "TARGET_MEDIA" 5735 "* 5736{ 5737 switch (INTVAL (operands[3])) 5738 { 5739 default: break; 5740 case FRV_BUILTIN_MADDHSS: return \"maddhss %1, %2, %0\"; 5741 case FRV_BUILTIN_MADDHUS: return \"maddhus %1, %2, %0\"; 5742 case FRV_BUILTIN_MSUBHSS: return \"msubhss %1, %2, %0\"; 5743 case FRV_BUILTIN_MSUBHUS: return \"msubhus %1, %2, %0\"; 5744 } 5745 5746 fatal_insn (\"Bad media insn, maddh\", insn); 5747}" 5748 [(set_attr "length" "4") 5749 (set_attr "type" "maddh")]) 5750 5751(define_insn "*cond_exec_maddh" 5752 [(cond_exec 5753 (match_operator 0 "ccr_eqne_operator" 5754 [(match_operand 1 "cr_operand" "C") 5755 (const_int 0)]) 5756 (set (match_operand:SI 2 "fpr_operand" "=f") 5757 (unspec:SI [(match_operand:SI 3 "fpr_operand" "f") 5758 (match_operand:SI 4 "fpr_operand" "f") 5759 (match_operand:SI 5 "const_int_operand" "n")] 5760 UNSPEC_MADDH)))] 5761 "TARGET_MEDIA" 5762 "* 5763{ 5764 switch (INTVAL (operands[5])) 5765 { 5766 default: break; 5767 case FRV_BUILTIN_MADDHSS: return \"cmaddhss %3, %4, %2, %1, %e0\"; 5768 case FRV_BUILTIN_MADDHUS: return \"cmaddhus %3, %4, %2, %1, %e0\"; 5769 case FRV_BUILTIN_MSUBHSS: return \"cmsubhss %3, %4, %2, %1, %e0\"; 5770 case FRV_BUILTIN_MSUBHUS: return \"cmsubhus %3, %4, %2, %1, %e0\"; 5771 } 5772 5773 fatal_insn (\"Bad media insn, cond_exec_maddh\", insn); 5774}" 5775 [(set_attr "length" "4") 5776 (set_attr "type" "maddh")]) 5777 5778;; Quad addition/subtraction with saturation (halfword): type "mqaddh" 5779 5780(define_expand "mqaddhss" 5781 [(set (match_operand:DI 0 "even_fpr_operand" "=h") 5782 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h") 5783 (match_operand:DI 2 "even_fpr_operand" "h") 5784 (match_dup 3)] 5785 UNSPEC_MQADDH))] 5786 "TARGET_MEDIA" 5787 "operands[3] = GEN_INT (FRV_BUILTIN_MQADDHSS);") 5788 5789(define_expand "mqaddhus" 5790 [(set (match_operand:DI 0 "even_fpr_operand" "=h") 5791 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h") 5792 (match_operand:DI 2 "even_fpr_operand" "h") 5793 (match_dup 3)] 5794 UNSPEC_MQADDH))] 5795 "TARGET_MEDIA" 5796 "operands[3] = GEN_INT (FRV_BUILTIN_MQADDHUS);") 5797 5798(define_expand "mqsubhss" 5799 [(set (match_operand:DI 0 "even_fpr_operand" "=h") 5800 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h") 5801 (match_operand:DI 2 "even_fpr_operand" "h") 5802 (match_dup 3)] 5803 UNSPEC_MQADDH))] 5804 "TARGET_MEDIA" 5805 "operands[3] = GEN_INT (FRV_BUILTIN_MQSUBHSS);") 5806 5807(define_expand "mqsubhus" 5808 [(set (match_operand:DI 0 "even_fpr_operand" "=h") 5809 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h") 5810 (match_operand:DI 2 "even_fpr_operand" "h") 5811 (match_dup 3)] 5812 UNSPEC_MQADDH))] 5813 "TARGET_MEDIA" 5814 "operands[3] = GEN_INT (FRV_BUILTIN_MQSUBHUS);") 5815 5816(define_insn "*mqaddh" 5817 [(set (match_operand:DI 0 "even_fpr_operand" "=h") 5818 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h") 5819 (match_operand:DI 2 "even_fpr_operand" "h") 5820 (match_operand:SI 3 "const_int_operand" "n")] 5821 UNSPEC_MQADDH))] 5822 "TARGET_MEDIA" 5823 "* 5824{ 5825 switch (INTVAL (operands[3])) 5826 { 5827 default: break; 5828 case FRV_BUILTIN_MQADDHSS: return \"mqaddhss %1, %2, %0\"; 5829 case FRV_BUILTIN_MQADDHUS: return \"mqaddhus %1, %2, %0\"; 5830 case FRV_BUILTIN_MQSUBHSS: return \"mqsubhss %1, %2, %0\"; 5831 case FRV_BUILTIN_MQSUBHUS: return \"mqsubhus %1, %2, %0\"; 5832 } 5833 5834 fatal_insn (\"Bad media insn, mqaddh\", insn); 5835}" 5836 [(set_attr "length" "4") 5837 (set_attr "type" "mqaddh")]) 5838 5839(define_insn "*cond_exec_mqaddh" 5840 [(cond_exec 5841 (match_operator 0 "ccr_eqne_operator" 5842 [(match_operand 1 "cr_operand" "C") 5843 (const_int 0)]) 5844 (set (match_operand:DI 2 "even_fpr_operand" "=h") 5845 (unspec:DI [(match_operand:DI 3 "even_fpr_operand" "h") 5846 (match_operand:DI 4 "even_fpr_operand" "h") 5847 (match_operand:SI 5 "const_int_operand" "n")] 5848 UNSPEC_MQADDH)))] 5849 "TARGET_MEDIA" 5850 "* 5851{ 5852 switch (INTVAL (operands[5])) 5853 { 5854 default: break; 5855 case FRV_BUILTIN_MQADDHSS: return \"cmqaddhss %3, %4, %2, %1, %e0\"; 5856 case FRV_BUILTIN_MQADDHUS: return \"cmqaddhus %3, %4, %2, %1, %e0\"; 5857 case FRV_BUILTIN_MQSUBHSS: return \"cmqsubhss %3, %4, %2, %1, %e0\"; 5858 case FRV_BUILTIN_MQSUBHUS: return \"cmqsubhus %3, %4, %2, %1, %e0\"; 5859 } 5860 5861 fatal_insn (\"Bad media insn, cond_exec_mqaddh\", insn); 5862}" 5863 [(set_attr "length" "4") 5864 (set_attr "type" "mqaddh")]) 5865 5866;; Pack halfword: type "mpackh" 5867 5868(define_insn "mpackh" 5869 [(set (match_operand:SI 0 "fpr_operand" "=f") 5870 (unspec:SI [(match_operand:HI 1 "fpr_operand" "f") 5871 (match_operand:HI 2 "fpr_operand" "f")] 5872 UNSPEC_MPACKH))] 5873 "TARGET_MEDIA" 5874 "mpackh %1, %2, %0" 5875 [(set_attr "length" "4") 5876 (set_attr "type" "mpackh")]) 5877 5878;; Unpack halfword: type "mpackh" 5879 5880(define_insn "munpackh" 5881 [(set (match_operand:DI 0 "even_fpr_operand" "=h") 5882 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")] 5883 UNSPEC_MUNPACKH))] 5884 "TARGET_MEDIA" 5885 "munpackh %1, %0" 5886 [(set_attr "length" "4") 5887 (set_attr "type" "munpackh")]) 5888 5889;; Dual pack halfword: type "mdpackh" 5890 5891(define_insn "mdpackh" 5892 [(set (match_operand:DI 0 "even_fpr_operand" "=h") 5893 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h") 5894 (match_operand:DI 2 "even_fpr_operand" "h")] 5895 UNSPEC_MDPACKH))] 5896 "TARGET_MEDIA" 5897 "mdpackh %1, %2, %0" 5898 [(set_attr "length" "4") 5899 (set_attr "type" "mdpackh")]) 5900 5901;; Byte-halfword conversion: type "mbhconv" 5902 5903(define_insn "mbtoh" 5904 [(set (match_operand:DI 0 "even_fpr_operand" "=h") 5905 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f")] 5906 UNSPEC_MBTOH))] 5907 "TARGET_MEDIA" 5908 "mbtoh %1, %0" 5909 [(set_attr "length" "4") 5910 (set_attr "type" "mbhconv")]) 5911 5912(define_insn "*cond_exec_mbtoh" 5913 [(cond_exec 5914 (match_operator 0 "ccr_eqne_operator" 5915 [(match_operand 1 "cr_operand" "C") 5916 (const_int 0)]) 5917 (set (match_operand:DI 2 "even_fpr_operand" "=h") 5918 (unspec:DI [(match_operand:SI 3 "fpr_operand" "f")] 5919 UNSPEC_MBTOH)))] 5920 "TARGET_MEDIA" 5921 "cmbtoh %3, %2, %1, %e0" 5922 [(set_attr "length" "4") 5923 (set_attr "type" "mbhconv")]) 5924 5925(define_insn "mhtob" 5926 [(set (match_operand:SI 0 "fpr_operand" "=f") 5927 (unspec:SI [(match_operand:DI 1 "even_fpr_operand" "h")] 5928 UNSPEC_MHTOB))] 5929 "TARGET_MEDIA" 5930 "mhtob %1, %0" 5931 [(set_attr "length" "4") 5932 (set_attr "type" "mbhconv")]) 5933 5934(define_insn "*cond_exec_mhtob" 5935 [(cond_exec 5936 (match_operator 0 "ccr_eqne_operator" 5937 [(match_operand 1 "cr_operand" "C") 5938 (const_int 0)]) 5939 (set (match_operand:SI 2 "fpr_operand" "=f") 5940 (unspec:SI [(match_operand:DI 3 "even_fpr_operand" "h")] 5941 UNSPEC_MHTOB)))] 5942 "TARGET_MEDIA" 5943 "cmhtob %3, %2, %1, %e0" 5944 [(set_attr "length" "4") 5945 (set_attr "type" "mbhconv")]) 5946 5947;; Rotate: type "mrot" 5948 5949(define_expand "mrotli" 5950 [(set (match_operand:SI 0 "fpr_operand" "") 5951 (unspec:SI [(match_operand:SI 1 "fpr_operand" "") 5952 (match_operand:SI 2 "uint5_operand" "") 5953 (match_dup 3)] 5954 UNSPEC_MROT))] 5955 "TARGET_MEDIA" 5956 "operands[3] = GEN_INT (FRV_BUILTIN_MROTLI);") 5957 5958(define_expand "mrotri" 5959 [(set (match_operand:SI 0 "fpr_operand" "") 5960 (unspec:SI [(match_operand:SI 1 "fpr_operand" "") 5961 (match_operand:SI 2 "uint5_operand" "") 5962 (match_dup 3)] 5963 UNSPEC_MROT))] 5964 "TARGET_MEDIA" 5965 "operands[3] = GEN_INT (FRV_BUILTIN_MROTRI);") 5966 5967(define_insn "*mrot" 5968 [(set (match_operand:SI 0 "fpr_operand" "=f") 5969 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 5970 (match_operand:SI 2 "uint5_operand" "I") 5971 (match_operand:SI 3 "const_int_operand" "n")] 5972 UNSPEC_MROT))] 5973 "TARGET_MEDIA" 5974 "* 5975{ 5976 switch (INTVAL (operands[3])) 5977 { 5978 default: break; 5979 case FRV_BUILTIN_MROTLI: return \"mrotli %1, %2, %0\"; 5980 case FRV_BUILTIN_MROTRI: return \"mrotri %1, %2, %0\"; 5981 } 5982 5983 fatal_insn (\"Bad media insn, mrot\", insn); 5984}" 5985 [(set_attr "length" "4") 5986 (set_attr "type" "mrot")]) 5987 5988;; Dual shift halfword: type "msh" 5989 5990(define_expand "msllhi" 5991 [(set (match_operand:SI 0 "fpr_operand" "") 5992 (unspec:SI [(match_operand:SI 1 "fpr_operand" "") 5993 (match_operand:SI 2 "uint4_operand" "") 5994 (match_dup 3)] 5995 UNSPEC_MSHIFT))] 5996 "TARGET_MEDIA" 5997 "operands[3] = GEN_INT (FRV_BUILTIN_MSLLHI);") 5998 5999(define_expand "msrlhi" 6000 [(set (match_operand:SI 0 "fpr_operand" "") 6001 (unspec:SI [(match_operand:SI 1 "fpr_operand" "") 6002 (match_operand:SI 2 "uint4_operand" "") 6003 (match_dup 3)] 6004 UNSPEC_MSHIFT))] 6005 "TARGET_MEDIA" 6006 "operands[3] = GEN_INT (FRV_BUILTIN_MSRLHI);") 6007 6008(define_expand "msrahi" 6009 [(set (match_operand:SI 0 "fpr_operand" "") 6010 (unspec:SI [(match_operand:SI 1 "fpr_operand" "") 6011 (match_operand:SI 2 "uint4_operand" "") 6012 (match_dup 3)] 6013 UNSPEC_MSHIFT))] 6014 "TARGET_MEDIA" 6015 "operands[3] = GEN_INT (FRV_BUILTIN_MSRAHI);") 6016 6017(define_insn "*mshift" 6018 [(set (match_operand:SI 0 "fpr_operand" "=f") 6019 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 6020 (match_operand:SI 2 "uint4_operand" "I") 6021 (match_operand:SI 3 "const_int_operand" "n")] 6022 UNSPEC_MSHIFT))] 6023 "TARGET_MEDIA" 6024 "* 6025{ 6026 switch (INTVAL (operands[3])) 6027 { 6028 default: break; 6029 case FRV_BUILTIN_MSLLHI: return \"msllhi %1, %2, %0\"; 6030 case FRV_BUILTIN_MSRLHI: return \"msrlhi %1, %2, %0\"; 6031 case FRV_BUILTIN_MSRAHI: return \"msrahi %1, %2, %0\"; 6032 } 6033 6034 fatal_insn (\"Bad media insn, mshift\", insn); 6035}" 6036 [(set_attr "length" "4") 6037 (set_attr "type" "mshift")]) 6038 6039;; Expand halfword to word: type "mexpdhw" 6040 6041(define_insn "mexpdhw" 6042 [(set (match_operand:SI 0 "fpr_operand" "=f") 6043 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 6044 (match_operand:SI 2 "uint1_operand" "I")] 6045 UNSPEC_MEXPDHW))] 6046 "TARGET_MEDIA" 6047 "mexpdhw %1, %2, %0" 6048 [(set_attr "length" "4") 6049 (set_attr "type" "mexpdhw")]) 6050 6051(define_insn "*cond_exec_mexpdhw" 6052 [(cond_exec 6053 (match_operator 0 "ccr_eqne_operator" 6054 [(match_operand 1 "cr_operand" "C") 6055 (const_int 0)]) 6056 (set (match_operand:SI 2 "fpr_operand" "=f") 6057 (unspec:SI [(match_operand:SI 3 "fpr_operand" "f") 6058 (match_operand:SI 4 "uint1_operand" "I")] 6059 UNSPEC_MEXPDHW)))] 6060 "TARGET_MEDIA" 6061 "cmexpdhw %3, %4, %2, %1, %e0" 6062 [(set_attr "length" "4") 6063 (set_attr "type" "mexpdhw")]) 6064 6065;; Expand halfword to double: type "mexpdhd" 6066 6067(define_insn "mexpdhd" 6068 [(set (match_operand:DI 0 "even_fpr_operand" "=h") 6069 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f") 6070 (match_operand:SI 2 "uint1_operand" "I")] 6071 UNSPEC_MEXPDHD))] 6072 "TARGET_MEDIA" 6073 "mexpdhd %1, %2, %0" 6074 [(set_attr "length" "4") 6075 (set_attr "type" "mexpdhd")]) 6076 6077(define_insn "*cond_exec_mexpdhd" 6078 [(cond_exec 6079 (match_operator 0 "ccr_eqne_operator" 6080 [(match_operand 1 "cr_operand" "C") 6081 (const_int 0)]) 6082 (set (match_operand:DI 2 "even_fpr_operand" "=h") 6083 (unspec:DI [(match_operand:SI 3 "fpr_operand" "f") 6084 (match_operand:SI 4 "uint1_operand" "I")] 6085 UNSPEC_MEXPDHD)))] 6086 "TARGET_MEDIA" 6087 "cmexpdhd %3, %4, %2, %1, %e0" 6088 [(set_attr "length" "4") 6089 (set_attr "type" "mexpdhd")]) 6090 6091;; FR cut: type "mwcut" 6092 6093(define_insn "mwcut" 6094 [(set (match_operand:SI 0 "fpr_operand" "=f") 6095 (unspec:SI [(match_operand:DI 1 "fpr_operand" "f") 6096 (match_operand:SI 2 "fpr_or_int6_operand" "fI")] 6097 UNSPEC_MWCUT))] 6098 "TARGET_MEDIA" 6099 "mwcut%i2 %1, %2, %0" 6100 [(set_attr "length" "4") 6101 (set_attr "type" "mwcut")]) 6102 6103;; Dual multiplication (halfword): type "mmulh" 6104 6105(define_expand "mmulhs" 6106 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b") 6107 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f") 6108 (match_operand:SI 2 "fpr_operand" "f") 6109 (match_dup 4)] 6110 UNSPEC_MMULH)) 6111 (set (match_operand:HI 3 "accg_operand" "=B") 6112 (unspec:HI [(const_int 0)] UNSPEC_MMULH))])] 6113 "TARGET_MEDIA" 6114 "operands[4] = GEN_INT (FRV_BUILTIN_MMULHS);") 6115 6116(define_expand "mmulhu" 6117 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b") 6118 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f") 6119 (match_operand:SI 2 "fpr_operand" "f") 6120 (match_dup 4)] 6121 UNSPEC_MMULH)) 6122 (set (match_operand:HI 3 "accg_operand" "=B") 6123 (unspec:HI [(const_int 0)] UNSPEC_MMULH))])] 6124 "TARGET_MEDIA" 6125 "operands[4] = GEN_INT (FRV_BUILTIN_MMULHU);") 6126 6127(define_insn "*mmulh" 6128 [(set (match_operand:DI 0 "even_acc_operand" "=b") 6129 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f") 6130 (match_operand:SI 2 "fpr_operand" "f") 6131 (match_operand:SI 3 "const_int_operand" "n")] 6132 UNSPEC_MMULH)) 6133 (set (match_operand:HI 4 "accg_operand" "=B") 6134 (unspec:HI [(const_int 0)] UNSPEC_MMULH))] 6135 "TARGET_MEDIA" 6136 "* 6137{ 6138 switch (INTVAL (operands[3])) 6139 { 6140 default: break; 6141 case FRV_BUILTIN_MMULHS: return \"mmulhs %1, %2, %0\"; 6142 case FRV_BUILTIN_MMULHU: return \"mmulhu %1, %2, %0\"; 6143 } 6144 6145 fatal_insn (\"Bad media insn, mmulh\", insn); 6146}" 6147 [(set_attr "length" "4") 6148 (set_attr "type" "mmulh")]) 6149 6150(define_insn "*cond_exec_mmulh" 6151 [(cond_exec 6152 (match_operator 0 "ccr_eqne_operator" 6153 [(match_operand 1 "cr_operand" "C") 6154 (const_int 0)]) 6155 (parallel [(set (match_operand:DI 2 "even_acc_operand" "=b") 6156 (unspec:DI [(match_operand:SI 3 "fpr_operand" "f") 6157 (match_operand:SI 4 "fpr_operand" "f") 6158 (match_operand:SI 5 "const_int_operand" "n")] 6159 UNSPEC_MMULH)) 6160 (set (match_operand:HI 6 "accg_operand" "=B") 6161 (unspec:HI [(const_int 0)] UNSPEC_MMULH))]))] 6162 "TARGET_MEDIA" 6163 "* 6164{ 6165 switch (INTVAL (operands[5])) 6166 { 6167 default: break; 6168 case FRV_BUILTIN_MMULHS: return \"cmmulhs %3, %4, %2, %1, %e0\"; 6169 case FRV_BUILTIN_MMULHU: return \"cmmulhu %3, %4, %2, %1, %e0\"; 6170 } 6171 6172 fatal_insn (\"Bad media insn, cond_exec_mmulh\", insn); 6173}" 6174 [(set_attr "length" "4") 6175 (set_attr "type" "mmulh")]) 6176 6177;; Dual cross multiplication (halfword): type "mmulxh" 6178 6179(define_expand "mmulxhs" 6180 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b") 6181 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f") 6182 (match_operand:SI 2 "fpr_operand" "f") 6183 (match_dup 4)] 6184 UNSPEC_MMULXH)) 6185 (set (match_operand:HI 3 "accg_operand" "=B") 6186 (unspec:HI [(const_int 0)] UNSPEC_MMULXH))])] 6187 "TARGET_MEDIA" 6188 "operands[4] = GEN_INT (FRV_BUILTIN_MMULXHS);") 6189 6190(define_expand "mmulxhu" 6191 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b") 6192 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f") 6193 (match_operand:SI 2 "fpr_operand" "f") 6194 (match_dup 4)] 6195 UNSPEC_MMULXH)) 6196 (set (match_operand:HI 3 "accg_operand" "=B") 6197 (unspec:HI [(const_int 0)] UNSPEC_MMULXH))])] 6198 "TARGET_MEDIA" 6199 "operands[4] = GEN_INT (FRV_BUILTIN_MMULXHU);") 6200 6201(define_insn "*mmulxh" 6202 [(set (match_operand:DI 0 "even_acc_operand" "=b") 6203 (unspec:DI [(match_operand:SI 1 "fpr_operand" "f") 6204 (match_operand:SI 2 "fpr_operand" "f") 6205 (match_operand:SI 3 "const_int_operand" "n")] 6206 UNSPEC_MMULXH)) 6207 (set (match_operand:HI 4 "accg_operand" "=B") 6208 (unspec:HI [(const_int 0)] UNSPEC_MMULXH))] 6209 "TARGET_MEDIA" 6210 "* 6211{ 6212 switch (INTVAL (operands[3])) 6213 { 6214 default: break; 6215 case FRV_BUILTIN_MMULXHS: return \"mmulxhs %1, %2, %0\"; 6216 case FRV_BUILTIN_MMULXHU: return \"mmulxhu %1, %2, %0\"; 6217 } 6218 6219 fatal_insn (\"Bad media insn, mmulxh\", insn); 6220}" 6221 [(set_attr "length" "4") 6222 (set_attr "type" "mmulxh")]) 6223 6224;; Dual product-sum (halfword): type "mmach" 6225 6226(define_expand "mmachs" 6227 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "+b") 6228 (unspec:DI [(match_dup 0) 6229 (match_operand:SI 1 "fpr_operand" "f") 6230 (match_operand:SI 2 "fpr_operand" "f") 6231 (match_operand:HI 3 "accg_operand" "+B") 6232 (match_dup 4)] 6233 UNSPEC_MMACH)) 6234 (set (match_dup 3) 6235 (unspec:HI [(const_int 0)] UNSPEC_MMACH))])] 6236 "TARGET_MEDIA" 6237 "operands[4] = GEN_INT (FRV_BUILTIN_MMACHS);") 6238 6239(define_expand "mmachu" 6240 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "+b") 6241 (unspec:DI [(match_dup 0) 6242 (match_operand:SI 1 "fpr_operand" "f") 6243 (match_operand:SI 2 "fpr_operand" "f") 6244 (match_operand:HI 3 "accg_operand" "+B") 6245 (match_dup 4)] 6246 UNSPEC_MMACH)) 6247 (set (match_dup 3) 6248 (unspec:HI [(const_int 0)] UNSPEC_MMACH))])] 6249 "TARGET_MEDIA" 6250 "operands[4] = GEN_INT (FRV_BUILTIN_MMACHU);") 6251 6252(define_insn "*mmach" 6253 [(set (match_operand:DI 0 "even_acc_operand" "+b") 6254 (unspec:DI [(match_dup 0) 6255 (match_operand:SI 1 "fpr_operand" "f") 6256 (match_operand:SI 2 "fpr_operand" "f") 6257 (match_operand:HI 3 "accg_operand" "+B") 6258 (match_operand:SI 4 "const_int_operand" "n")] 6259 UNSPEC_MMACH)) 6260 (set (match_dup 3) (unspec:HI [(const_int 0)] UNSPEC_MMACH))] 6261 "TARGET_MEDIA" 6262 "* 6263{ 6264 switch (INTVAL (operands[4])) 6265 { 6266 default: break; 6267 case FRV_BUILTIN_MMACHS: return \"mmachs %1, %2, %0\"; 6268 case FRV_BUILTIN_MMACHU: return \"mmachu %1, %2, %0\"; 6269 } 6270 6271 fatal_insn (\"Bad media insn, mmach\", insn); 6272}" 6273 [(set_attr "length" "4") 6274 (set_attr "type" "mmach")]) 6275 6276(define_insn "*cond_exec_mmach" 6277 [(cond_exec 6278 (match_operator 0 "ccr_eqne_operator" 6279 [(match_operand 1 "cr_operand" "C") 6280 (const_int 0)]) 6281 (parallel [(set (match_operand:DI 2 "even_acc_operand" "+b") 6282 (unspec:DI [(match_dup 2) 6283 (match_operand:SI 3 "fpr_operand" "f") 6284 (match_operand:SI 4 "fpr_operand" "f") 6285 (match_operand:HI 5 "accg_operand" "+B") 6286 (match_operand:SI 6 "const_int_operand" "n")] 6287 UNSPEC_MMACH)) 6288 (set (match_dup 5) 6289 (unspec:HI [(const_int 0)] UNSPEC_MMACH))]))] 6290 "TARGET_MEDIA" 6291 "* 6292{ 6293 switch (INTVAL (operands[6])) 6294 { 6295 default: break; 6296 case FRV_BUILTIN_MMACHS: return \"cmmachs %3, %4, %2, %1, %e0\"; 6297 case FRV_BUILTIN_MMACHU: return \"cmmachu %3, %4, %2, %1, %e0\"; 6298 } 6299 6300 fatal_insn (\"Bad media insn, cond_exec_mmach\", insn); 6301}" 6302 [(set_attr "length" "4") 6303 (set_attr "type" "mmach")]) 6304 6305;; Dual product-difference: type "mmrdh" 6306 6307(define_expand "mmrdhs" 6308 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "+b") 6309 (unspec:DI [(match_dup 0) 6310 (match_operand:SI 1 "fpr_operand" "f") 6311 (match_operand:SI 2 "fpr_operand" "f") 6312 (match_operand:HI 3 "accg_operand" "+B") 6313 (match_dup 4)] 6314 UNSPEC_MMRDH)) 6315 (set (match_dup 3) 6316 (unspec:HI [(const_int 0)] UNSPEC_MMRDH))])] 6317 "TARGET_MEDIA" 6318 "operands[4] = GEN_INT (FRV_BUILTIN_MMRDHS);") 6319 6320(define_expand "mmrdhu" 6321 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "+b") 6322 (unspec:DI [(match_dup 0) 6323 (match_operand:SI 1 "fpr_operand" "f") 6324 (match_operand:SI 2 "fpr_operand" "f") 6325 (match_operand:HI 3 "accg_operand" "+B") 6326 (match_dup 4)] 6327 UNSPEC_MMRDH)) 6328 (set (match_dup 3) 6329 (unspec:HI [(const_int 0)] UNSPEC_MMRDH))])] 6330 "TARGET_MEDIA" 6331 "operands[4] = GEN_INT (FRV_BUILTIN_MMRDHU);") 6332 6333(define_insn "*mmrdh" 6334 [(set (match_operand:DI 0 "even_acc_operand" "+b") 6335 (unspec:DI [(match_dup 0) 6336 (match_operand:SI 1 "fpr_operand" "f") 6337 (match_operand:SI 2 "fpr_operand" "f") 6338 (match_operand:HI 3 "accg_operand" "+B") 6339 (match_operand:SI 4 "const_int_operand" "n")] 6340 UNSPEC_MMRDH)) 6341 (set (match_dup 3) 6342 (unspec:HI [(const_int 0)] UNSPEC_MMRDH))] 6343 "TARGET_MEDIA" 6344 "* 6345{ 6346 switch (INTVAL (operands[4])) 6347 { 6348 default: break; 6349 case FRV_BUILTIN_MMRDHS: return \"mmrdhs %1, %2, %0\"; 6350 case FRV_BUILTIN_MMRDHU: return \"mmrdhu %1, %2, %0\"; 6351 } 6352 6353 fatal_insn (\"Bad media insn, mrdh\", insn); 6354}" 6355 [(set_attr "length" "4") 6356 (set_attr "type" "mmrdh")]) 6357 6358;; Quad multiply (halfword): type "mqmulh" 6359 6360(define_expand "mqmulhs" 6361 [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "=A") 6362 (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h") 6363 (match_operand:DI 2 "even_fpr_operand" "h") 6364 (match_dup 4)] 6365 UNSPEC_MQMULH)) 6366 (set (match_operand:V4QI 3 "accg_operand" "=B") 6367 (unspec:V4QI [(const_int 0)] UNSPEC_MQMULH))])] 6368 "TARGET_MEDIA" 6369 "operands[4] = GEN_INT (FRV_BUILTIN_MQMULHS);") 6370 6371(define_expand "mqmulhu" 6372 [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "=A") 6373 (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h") 6374 (match_operand:DI 2 "even_fpr_operand" "h") 6375 (match_dup 4)] 6376 UNSPEC_MQMULH)) 6377 (set (match_operand:V4QI 3 "accg_operand" "=B") 6378 (unspec:V4QI [(const_int 0)] UNSPEC_MQMULH))])] 6379 "TARGET_MEDIA" 6380 "operands[4] = GEN_INT (FRV_BUILTIN_MQMULHU);") 6381 6382(define_insn "*mqmulh" 6383 [(set (match_operand:V4SI 0 "quad_acc_operand" "=A") 6384 (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h") 6385 (match_operand:DI 2 "even_fpr_operand" "h") 6386 (match_operand:SI 3 "const_int_operand" "n")] 6387 UNSPEC_MQMULH)) 6388 (set (match_operand:V4QI 4 "accg_operand" "=B") 6389 (unspec:V4QI [(const_int 0)] UNSPEC_MQMULH))] 6390 "TARGET_MEDIA" 6391 "* 6392{ 6393 switch (INTVAL (operands[3])) 6394 { 6395 default: break; 6396 case FRV_BUILTIN_MQMULHS: return \"mqmulhs %1, %2, %0\"; 6397 case FRV_BUILTIN_MQMULHU: return \"mqmulhu %1, %2, %0\"; 6398 } 6399 6400 fatal_insn (\"Bad media insn, mqmulh\", insn); 6401}" 6402 [(set_attr "length" "4") 6403 (set_attr "type" "mqmulh")]) 6404 6405(define_insn "*cond_exec_mqmulh" 6406 [(cond_exec 6407 (match_operator 0 "ccr_eqne_operator" 6408 [(match_operand 1 "cr_operand" "C") 6409 (const_int 0)]) 6410 (parallel [(set (match_operand:V4SI 2 "quad_acc_operand" "=A") 6411 (unspec:V4SI [(match_operand:DI 3 "even_fpr_operand" "h") 6412 (match_operand:DI 4 "even_fpr_operand" "h") 6413 (match_operand:SI 5 "const_int_operand" "n")] 6414 UNSPEC_MQMULH)) 6415 (set (match_operand:V4QI 6 "accg_operand" "=B") 6416 (unspec:V4QI [(const_int 0)] UNSPEC_MQMULH))]))] 6417 "TARGET_MEDIA" 6418 "* 6419{ 6420 switch (INTVAL (operands[5])) 6421 { 6422 default: break; 6423 case FRV_BUILTIN_MQMULHS: return \"cmqmulhs %3, %4, %2, %1, %e0\"; 6424 case FRV_BUILTIN_MQMULHU: return \"cmqmulhu %3, %4, %2, %1, %e0\"; 6425 } 6426 6427 fatal_insn (\"Bad media insn, cond_exec_mqmulh\", insn); 6428}" 6429 [(set_attr "length" "4") 6430 (set_attr "type" "mqmulh")]) 6431 6432;; Quad cross multiply (halfword): type "mqmulxh" 6433 6434(define_expand "mqmulxhs" 6435 [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "=A") 6436 (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h") 6437 (match_operand:DI 2 "even_fpr_operand" "h") 6438 (match_dup 4)] 6439 UNSPEC_MQMULXH)) 6440 (set (match_operand:V4QI 3 "accg_operand" "=B") 6441 (unspec:V4QI [(const_int 0)] UNSPEC_MQMULXH))])] 6442 "TARGET_MEDIA" 6443 "operands[4] = GEN_INT (FRV_BUILTIN_MQMULXHS);") 6444 6445(define_expand "mqmulxhu" 6446 [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "=A") 6447 (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h") 6448 (match_operand:DI 2 "even_fpr_operand" "h") 6449 (match_dup 4)] 6450 UNSPEC_MQMULXH)) 6451 (set (match_operand:V4QI 3 "accg_operand" "=B") 6452 (unspec:V4QI [(const_int 0)] UNSPEC_MQMULXH))])] 6453 "TARGET_MEDIA" 6454 "operands[4] = GEN_INT (FRV_BUILTIN_MQMULXHU);") 6455 6456(define_insn "*mqmulxh" 6457 [(set (match_operand:V4SI 0 "quad_acc_operand" "=A") 6458 (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h") 6459 (match_operand:DI 2 "even_fpr_operand" "h") 6460 (match_operand:SI 3 "const_int_operand" "n")] 6461 UNSPEC_MQMULXH)) 6462 (set (match_operand:V4QI 4 "accg_operand" "=B") 6463 (unspec:V4QI [(const_int 0)] UNSPEC_MQMULXH))] 6464 "TARGET_MEDIA" 6465 "* 6466{ 6467 switch (INTVAL (operands[3])) 6468 { 6469 default: break; 6470 case FRV_BUILTIN_MQMULXHS: return \"mqmulxhs %1, %2, %0\"; 6471 case FRV_BUILTIN_MQMULXHU: return \"mqmulxhu %1, %2, %0\"; 6472 } 6473 6474 fatal_insn (\"Bad media insn, mqmulxh\", insn); 6475}" 6476 [(set_attr "length" "4") 6477 (set_attr "type" "mqmulxh")]) 6478 6479;; Quad product-sum (halfword): type "mqmach" 6480 6481(define_expand "mqmachs" 6482 [(parallel [(set (match_operand:V4SI 0 "even_acc_operand" "+A") 6483 (unspec:V4SI [(match_dup 0) 6484 (match_operand:DI 1 "even_fpr_operand" "h") 6485 (match_operand:DI 2 "even_fpr_operand" "h") 6486 (match_operand:V4QI 3 "accg_operand" "+B") 6487 (match_dup 4)] 6488 UNSPEC_MQMACH)) 6489 (set (match_dup 3) 6490 (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH))])] 6491 "TARGET_MEDIA" 6492 "operands[4] = GEN_INT (FRV_BUILTIN_MQMACHS);") 6493 6494(define_expand "mqmachu" 6495 [(parallel [(set (match_operand:V4SI 0 "even_acc_operand" "+A") 6496 (unspec:V4SI [(match_dup 0) 6497 (match_operand:DI 1 "even_fpr_operand" "h") 6498 (match_operand:DI 2 "even_fpr_operand" "h") 6499 (match_operand:V4QI 3 "accg_operand" "+B") 6500 (match_dup 4)] 6501 UNSPEC_MQMACH)) 6502 (set (match_dup 3) 6503 (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH))])] 6504 "TARGET_MEDIA" 6505 "operands[4] = GEN_INT (FRV_BUILTIN_MQMACHU);") 6506 6507(define_insn "*mqmach" 6508 [(set (match_operand:V4SI 0 "even_acc_operand" "+A") 6509 (unspec:V4SI [(match_dup 0) 6510 (match_operand:DI 1 "even_fpr_operand" "h") 6511 (match_operand:DI 2 "even_fpr_operand" "h") 6512 (match_operand:V4QI 3 "accg_operand" "+B") 6513 (match_operand:SI 4 "const_int_operand" "n")] 6514 UNSPEC_MQMACH)) 6515 (set (match_dup 3) 6516 (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH))] 6517 "TARGET_MEDIA" 6518 "* 6519{ 6520 switch (INTVAL (operands[4])) 6521 { 6522 default: break; 6523 case FRV_BUILTIN_MQMACHS: return \"mqmachs %1, %2, %0\"; 6524 case FRV_BUILTIN_MQMACHU: return \"mqmachu %1, %2, %0\"; 6525 } 6526 6527 fatal_insn (\"Bad media insn, mqmach\", insn); 6528}" 6529 [(set_attr "length" "4") 6530 (set_attr "type" "mqmach")]) 6531 6532(define_insn "*cond_exec_mqmach" 6533 [(cond_exec 6534 (match_operator 0 "ccr_eqne_operator" 6535 [(match_operand 1 "cr_operand" "C") 6536 (const_int 0)]) 6537 (parallel [(set (match_operand:V4SI 2 "even_acc_operand" "+A") 6538 (unspec:V4SI [(match_dup 2) 6539 (match_operand:DI 3 "even_fpr_operand" "h") 6540 (match_operand:DI 4 "even_fpr_operand" "h") 6541 (match_operand:V4QI 5 "accg_operand" "+B") 6542 (match_operand:SI 6 "const_int_operand" "n")] 6543 UNSPEC_MQMACH)) 6544 (set (match_dup 5) 6545 (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH))]))] 6546 "TARGET_MEDIA" 6547 "* 6548{ 6549 switch (INTVAL (operands[6])) 6550 { 6551 default: break; 6552 case FRV_BUILTIN_MQMACHS: return \"cmqmachs %3, %4, %2, %1, %e0\"; 6553 case FRV_BUILTIN_MQMACHU: return \"cmqmachu %3, %4, %2, %1, %e0\"; 6554 } 6555 6556 fatal_insn (\"Bad media insn, cond_exec_mqmach\", insn); 6557}" 6558 [(set_attr "length" "4") 6559 (set_attr "type" "mqmach")]) 6560 6561;; Dual complex number product-sum (halfword) 6562 6563(define_expand "mcpxrs" 6564 [(parallel [(set (match_operand:SI 0 "acc_operand" "=a") 6565 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 6566 (match_operand:SI 2 "fpr_operand" "f") 6567 (match_dup 4)] 6568 UNSPEC_MCPX)) 6569 (set (match_operand:QI 3 "accg_operand" "=B") 6570 (unspec:QI [(const_int 0)] UNSPEC_MCPX))])] 6571 "TARGET_MEDIA" 6572 "operands[4] = GEN_INT (FRV_BUILTIN_MCPXRS);") 6573 6574(define_expand "mcpxru" 6575 [(parallel [(set (match_operand:SI 0 "acc_operand" "=a") 6576 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 6577 (match_operand:SI 2 "fpr_operand" "f") 6578 (match_dup 4)] 6579 UNSPEC_MCPX)) 6580 (set (match_operand:QI 3 "accg_operand" "=B") 6581 (unspec:QI [(const_int 0)] UNSPEC_MCPX))])] 6582 "TARGET_MEDIA" 6583 "operands[4] = GEN_INT (FRV_BUILTIN_MCPXRU);") 6584 6585(define_expand "mcpxis" 6586 [(parallel [(set (match_operand:SI 0 "acc_operand" "=a") 6587 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 6588 (match_operand:SI 2 "fpr_operand" "f") 6589 (match_dup 4)] 6590 UNSPEC_MCPX)) 6591 (set (match_operand:QI 3 "accg_operand" "=B") 6592 (unspec:QI [(const_int 0)] UNSPEC_MCPX))])] 6593 "TARGET_MEDIA" 6594 "operands[4] = GEN_INT (FRV_BUILTIN_MCPXIS);") 6595 6596(define_expand "mcpxiu" 6597 [(parallel [(set (match_operand:SI 0 "acc_operand" "=a") 6598 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 6599 (match_operand:SI 2 "fpr_operand" "f") 6600 (match_dup 4)] 6601 UNSPEC_MCPX)) 6602 (set (match_operand:QI 3 "accg_operand" "=B") 6603 (unspec:QI [(const_int 0)] UNSPEC_MCPX))])] 6604 "TARGET_MEDIA" 6605 "operands[4] = GEN_INT (FRV_BUILTIN_MCPXIU);") 6606 6607(define_insn "*mcpx" 6608 [(parallel [(set (match_operand:SI 0 "acc_operand" "=a") 6609 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 6610 (match_operand:SI 2 "fpr_operand" "f") 6611 (match_operand:SI 3 "const_int_operand" "n")] 6612 UNSPEC_MCPX)) 6613 (set (match_operand:QI 4 "accg_operand" "=B") 6614 (unspec:QI [(const_int 0)] UNSPEC_MCPX))])] 6615 "TARGET_MEDIA" 6616 "* 6617{ 6618 switch (INTVAL (operands[3])) 6619 { 6620 default: break; 6621 case FRV_BUILTIN_MCPXRS: return \"mcpxrs %1, %2, %0\"; 6622 case FRV_BUILTIN_MCPXRU: return \"mcpxru %1, %2, %0\"; 6623 case FRV_BUILTIN_MCPXIS: return \"mcpxis %1, %2, %0\"; 6624 case FRV_BUILTIN_MCPXIU: return \"mcpxiu %1, %2, %0\"; 6625 } 6626 6627 fatal_insn (\"Bad media insn, mcpx\", insn); 6628}" 6629 [(set_attr "length" "4") 6630 (set_attr "type" "mcpx")]) 6631 6632(define_insn "*cond_exec_mcpx" 6633 [(cond_exec 6634 (match_operator 0 "ccr_eqne_operator" 6635 [(match_operand 1 "cr_operand" "C") 6636 (const_int 0)]) 6637 (parallel [(set (match_operand:SI 2 "acc_operand" "=a") 6638 (unspec:SI [(match_operand:SI 3 "fpr_operand" "f") 6639 (match_operand:SI 4 "fpr_operand" "f") 6640 (match_operand:SI 5 "const_int_operand" "n")] 6641 UNSPEC_MCPX)) 6642 (set (match_operand:QI 6 "accg_operand" "=B") 6643 (unspec:QI [(const_int 0)] UNSPEC_MCPX))]))] 6644 "TARGET_MEDIA" 6645 "* 6646{ 6647 switch (INTVAL (operands[5])) 6648 { 6649 default: break; 6650 case FRV_BUILTIN_MCPXRS: return \"cmcpxrs %3, %4, %2, %1, %e0\"; 6651 case FRV_BUILTIN_MCPXRU: return \"cmcpxru %3, %4, %2, %1, %e0\"; 6652 case FRV_BUILTIN_MCPXIS: return \"cmcpxis %3, %4, %2, %1, %e0\"; 6653 case FRV_BUILTIN_MCPXIU: return \"cmcpxiu %3, %4, %2, %1, %e0\"; 6654 } 6655 6656 fatal_insn (\"Bad media insn, cond_exec_mcpx\", insn); 6657}" 6658 [(set_attr "length" "4") 6659 (set_attr "type" "mcpx")]) 6660 6661;; Quad complex number product-sum (halfword): type "mqcpx" 6662 6663(define_expand "mqcpxrs" 6664 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b") 6665 (unspec:DI [(match_operand:DI 1 "fpr_operand" "f") 6666 (match_operand:DI 2 "fpr_operand" "f") 6667 (match_dup 4)] 6668 UNSPEC_MQCPX)) 6669 (set (match_operand:HI 3 "accg_operand" "=B") 6670 (unspec:HI [(const_int 0)] UNSPEC_MQCPX))])] 6671 "TARGET_MEDIA" 6672 "operands[4] = GEN_INT (FRV_BUILTIN_MQCPXRS);") 6673 6674(define_expand "mqcpxru" 6675 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b") 6676 (unspec:DI [(match_operand:DI 1 "fpr_operand" "f") 6677 (match_operand:DI 2 "fpr_operand" "f") 6678 (match_dup 4)] 6679 UNSPEC_MQCPX)) 6680 (set (match_operand:HI 3 "accg_operand" "=B") 6681 (unspec:HI [(const_int 0)] UNSPEC_MQCPX))])] 6682 "TARGET_MEDIA" 6683 "operands[4] = GEN_INT (FRV_BUILTIN_MQCPXRU);") 6684 6685(define_expand "mqcpxis" 6686 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b") 6687 (unspec:DI [(match_operand:DI 1 "fpr_operand" "f") 6688 (match_operand:DI 2 "fpr_operand" "f") 6689 (match_dup 4)] 6690 UNSPEC_MQCPX)) 6691 (set (match_operand:HI 3 "accg_operand" "=B") 6692 (unspec:HI [(const_int 0)] UNSPEC_MQCPX))])] 6693 "TARGET_MEDIA" 6694 "operands[4] = GEN_INT (FRV_BUILTIN_MQCPXIS);") 6695 6696(define_expand "mqcpxiu" 6697 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "=b") 6698 (unspec:DI [(match_operand:DI 1 "fpr_operand" "f") 6699 (match_operand:DI 2 "fpr_operand" "f") 6700 (match_dup 4)] 6701 UNSPEC_MQCPX)) 6702 (set (match_operand:HI 3 "accg_operand" "=B") 6703 (unspec:HI [(const_int 0)] UNSPEC_MQCPX))])] 6704 "TARGET_MEDIA" 6705 "operands[4] = GEN_INT (FRV_BUILTIN_MQCPXIU);") 6706 6707(define_insn "*mqcpx" 6708 [(set (match_operand:DI 0 "even_acc_operand" "=b") 6709 (unspec:DI [(match_operand:DI 1 "fpr_operand" "f") 6710 (match_operand:DI 2 "fpr_operand" "f") 6711 (match_operand:SI 3 "const_int_operand" "n")] 6712 UNSPEC_MQCPX)) 6713 (set (match_operand:HI 4 "accg_operand" "=B") 6714 (unspec:HI [(const_int 0)] UNSPEC_MQCPX))] 6715 "TARGET_MEDIA" 6716 "* 6717{ 6718 switch (INTVAL (operands[3])) 6719 { 6720 default: break; 6721 case FRV_BUILTIN_MQCPXRS: return \"mqcpxrs %1, %2, %0\"; 6722 case FRV_BUILTIN_MQCPXRU: return \"mqcpxru %1, %2, %0\"; 6723 case FRV_BUILTIN_MQCPXIS: return \"mqcpxis %1, %2, %0\"; 6724 case FRV_BUILTIN_MQCPXIU: return \"mqcpxiu %1, %2, %0\"; 6725 } 6726 6727 fatal_insn (\"Bad media insn, mqcpx\", insn); 6728}" 6729 [(set_attr "length" "4") 6730 (set_attr "type" "mqcpx")]) 6731 6732;; Cut: type "mcut" 6733 6734(define_expand "mcut" 6735 [(set (match_operand:SI 0 "fpr_operand" "=f") 6736 (unspec:SI [(match_operand:SI 1 "acc_operand" "a") 6737 (match_operand:SI 2 "fpr_or_int6_operand" "fI") 6738 (match_operand:QI 3 "accg_operand" "B") 6739 (match_dup 4)] 6740 UNSPEC_MCUT))] 6741 "TARGET_MEDIA" 6742 "operands[4] = GEN_INT (FRV_BUILTIN_MCUT);") 6743 6744(define_expand "mcutss" 6745 [(set (match_operand:SI 0 "fpr_operand" "=f") 6746 (unspec:SI [(match_operand:SI 1 "acc_operand" "a") 6747 (match_operand:SI 2 "fpr_or_int6_operand" "fI") 6748 (match_operand:QI 3 "accg_operand" "B") 6749 (match_dup 4)] 6750 UNSPEC_MCUT))] 6751 "TARGET_MEDIA" 6752 "operands[4] = GEN_INT (FRV_BUILTIN_MCUTSS);") 6753 6754(define_insn "*mcut" 6755 [(set (match_operand:SI 0 "fpr_operand" "=f") 6756 (unspec:SI [(match_operand:SI 1 "acc_operand" "a") 6757 (match_operand:SI 2 "fpr_or_int6_operand" "fI") 6758 (match_operand:QI 3 "accg_operand" "B") 6759 (match_operand:SI 4 "const_int_operand" "n")] 6760 UNSPEC_MCUT))] 6761 "TARGET_MEDIA" 6762 "* 6763{ 6764 switch (INTVAL (operands[4])) 6765 { 6766 default: break; 6767 case FRV_BUILTIN_MCUT: return \"mcut%i2 %1, %2, %0\"; 6768 case FRV_BUILTIN_MCUTSS: return \"mcutss%i2 %1, %2, %0\"; 6769 } 6770 6771 fatal_insn (\"Bad media insn, mcut\", insn); 6772}" 6773 [(set_attr "length" "4") 6774 (set_attr "type" "mcut")]) 6775 6776;; Accumulator read: type "mrdacc" 6777 6778(define_insn "mrdacc" 6779 [(set (match_operand:SI 0 "fpr_operand" "=f") 6780 (unspec:SI [(match_operand:SI 1 "acc_operand" "a")] UNSPEC_MRDACC))] 6781 "TARGET_MEDIA" 6782 "mrdacc %1, %0" 6783 [(set_attr "length" "4") 6784 (set_attr "type" "mrdacc")]) 6785 6786(define_insn "mrdaccg" 6787 [(set (match_operand:SI 0 "fpr_operand" "=f") 6788 (unspec:SI [(match_operand:QI 1 "accg_operand" "B")] UNSPEC_MRDACCG))] 6789 "TARGET_MEDIA" 6790 "mrdaccg %1, %0" 6791 [(set_attr "length" "4") 6792 (set_attr "type" "mrdacc")]) 6793 6794;; Accumulator write: type "mwtacc" 6795 6796(define_insn "mwtacc" 6797 [(set (match_operand:SI 0 "acc_operand" "=a") 6798 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")] UNSPEC_MWTACC))] 6799 "TARGET_MEDIA" 6800 "mwtacc %1, %0" 6801 [(set_attr "length" "4") 6802 (set_attr "type" "mwtacc")]) 6803 6804(define_insn "mwtaccg" 6805 [(set (match_operand:QI 0 "accg_operand" "=B") 6806 (unspec:QI [(match_operand:SI 1 "fpr_operand" "f")] UNSPEC_MWTACCG))] 6807 "TARGET_MEDIA" 6808 "mwtaccg %1, %0" 6809 [(set_attr "length" "4") 6810 (set_attr "type" "mwtacc")]) 6811 6812;; Trap: This one executes on the control unit, not the media units. 6813 6814(define_insn "mtrap" 6815 [(unspec_volatile [(const_int 0)] UNSPEC_MTRAP)] 6816 "TARGET_MEDIA" 6817 "mtrap" 6818 [(set_attr "length" "4") 6819 (set_attr "type" "trap")]) 6820 6821;; Clear single accumulator: type "mclracc" 6822 6823(define_insn "mclracc_internal" 6824 [(set (match_operand:SI 0 "acc_operand" "=a") 6825 (unspec:SI [(const_int 0)] UNSPEC_MCLRACC)) 6826 (set (match_operand:QI 1 "accg_operand" "=B") 6827 (unspec:QI [(const_int 0)] UNSPEC_MCLRACC))] 6828 "TARGET_MEDIA" 6829 "mclracc %0,#0" 6830 [(set_attr "length" "4") 6831 (set_attr "type" "mclracc")]) 6832 6833(define_expand "mclracc" 6834 [(parallel [(set (match_operand:SI 0 "acc_operand" "=a") 6835 (unspec:SI [(const_int 0)] UNSPEC_MCLRACC)) 6836 (set (match_dup 1) 6837 (unspec:QI [(const_int 0)] UNSPEC_MCLRACC))])] 6838 "TARGET_MEDIA" 6839 " 6840{ 6841 if (GET_CODE (operands[0]) != REG || !ACC_P (REGNO (operands[0]))) 6842 FAIL; 6843 6844 operands[1] = frv_matching_accg_for_acc (operands[0]); 6845}") 6846 6847;; Clear all accumulators: type "mclracca" 6848 6849(define_insn "mclracca8_internal" 6850 [(set (match_operand:V4SI 0 "quad_acc_operand" "=b") 6851 (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA)) 6852 (set (match_operand:V4SI 1 "quad_acc_operand" "=b") 6853 (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA)) 6854 (set (match_operand:V4QI 2 "accg_operand" "=B") 6855 (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA)) 6856 (set (match_operand:V4QI 3 "accg_operand" "=B") 6857 (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))] 6858 "TARGET_MEDIA && TARGET_ACC_8" 6859 "mclracc acc0,#1" 6860 [(set_attr "length" "4") 6861 (set_attr "type" "mclracca")]) 6862 6863(define_insn "mclracca4_internal" 6864 [(set (match_operand:V4SI 0 "quad_acc_operand" "=b") 6865 (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA)) 6866 (set (match_operand:V4QI 1 "accg_operand" "=B") 6867 (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))] 6868 "TARGET_MEDIA && TARGET_ACC_4" 6869 "mclracc acc0,#1" 6870 [(set_attr "length" "4") 6871 (set_attr "type" "mclracca")]) 6872 6873(define_expand "mclracca8" 6874 [(parallel [(set (match_dup 0) (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA)) 6875 (set (match_dup 1) (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA)) 6876 (set (match_dup 2) (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA)) 6877 (set (match_dup 3) (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))])] 6878 "TARGET_MEDIA && TARGET_ACC_8" 6879 " 6880{ 6881 operands[0] = gen_rtx_REG (V4SImode, ACC_FIRST); 6882 operands[1] = gen_rtx_REG (V4SImode, ACC_FIRST + (~3 & ACC_MASK)); 6883 operands[2] = gen_rtx_REG (V4QImode, ACCG_FIRST); 6884 operands[3] = gen_rtx_REG (V4QImode, ACCG_FIRST + (~3 & ACC_MASK)); 6885}") 6886 6887(define_expand "mclracca4" 6888 [(parallel [(set (match_dup 0) (unspec:V4SI [(const_int 0)] UNSPEC_MCLRACCA)) 6889 (set (match_dup 1) (unspec:V4QI [(const_int 0)] UNSPEC_MCLRACCA))])] 6890 "TARGET_MEDIA && TARGET_ACC_4" 6891 " 6892{ 6893 operands[0] = gen_rtx_REG (V4SImode, ACC_FIRST); 6894 operands[1] = gen_rtx_REG (V4QImode, ACCG_FIRST); 6895}") 6896 6897(define_insn "mcop1" 6898 [(set (match_operand:SI 0 "fpr_operand" "=f") 6899 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 6900 (match_operand:SI 2 "fpr_operand" "f")] UNSPEC_MCOP1))] 6901 "TARGET_MEDIA_REV1" 6902 "mcop1 %1, %2, %0" 6903 [(set_attr "length" "4") 6904;; What is the class of the insn ??? 6905 (set_attr "type" "multi")]) 6906 6907(define_insn "mcop2" 6908 [(set (match_operand:SI 0 "fpr_operand" "=f") 6909 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f") 6910 (match_operand:SI 2 "fpr_operand" "f")] UNSPEC_MCOP2))] 6911 "TARGET_MEDIA_REV1" 6912 "mcop2 %1, %2, %0" 6913 [(set_attr "length" "4") 6914;; What is the class of the insn ??? 6915 (set_attr "type" "multi")]) 6916 6917(define_insn "*mdunpackh_internal" 6918 [(set (match_operand:V4SI 0 "quad_fpr_operand" "=x") 6919 (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")] 6920 UNSPEC_MDUNPACKH_INTERNAL))] 6921 "TARGET_MEDIA_REV1" 6922 "mdunpackh %1, %0" 6923 [(set_attr "length" "4") 6924 (set_attr "type" "mdunpackh")]) 6925 6926(define_insn_and_split "mdunpackh" 6927 [(set (match_operand:V4SI 0 "memory_operand" "=o") 6928 (unspec:V4SI [(match_operand:DI 1 "even_fpr_operand" "h")] 6929 UNSPEC_MDUNPACKH)) 6930 (clobber (match_scratch:V4SI 2 "=x"))] 6931 "TARGET_MEDIA_REV1" 6932 "#" 6933 "reload_completed" 6934 [(set (match_dup 2) 6935 (unspec:V4SI [(match_dup 1)] UNSPEC_MDUNPACKH_INTERNAL)) 6936 (set (match_dup 3) 6937 (match_dup 4)) 6938 (set (match_dup 5) 6939 (match_dup 6))] 6940 " 6941{ 6942 operands[3] = change_address (operands[0], DImode, NULL_RTX); 6943 operands[4] = gen_rtx_REG (DImode, REGNO (operands[2])); 6944 operands[5] = frv_index_memory (operands[0], DImode, 1); 6945 operands[6] = gen_rtx_REG (DImode, REGNO (operands[2])+2); 6946}" 6947 [(set_attr "length" "20") 6948 (set_attr "type" "multi")]) 6949 6950(define_insn "*mbtohe_internal" 6951 [(set (match_operand:V4SI 0 "quad_fpr_operand" "=x") 6952 (unspec:V4SI [(match_operand:SI 1 "fpr_operand" "f")] 6953 UNSPEC_MBTOHE_INTERNAL))] 6954 "TARGET_MEDIA_REV1" 6955 "mbtohe %1, %0" 6956 [(set_attr "length" "4") 6957 (set_attr "type" "mbhconve")]) 6958 6959(define_insn_and_split "mbtohe" 6960 [(set (match_operand:V4SI 0 "memory_operand" "=o") 6961 (unspec:V4SI [(match_operand:SI 1 "fpr_operand" "f")] 6962 UNSPEC_MBTOHE)) 6963 (clobber (match_scratch:V4SI 2 "=x"))] 6964 "TARGET_MEDIA_REV1" 6965 "#" 6966 "reload_completed" 6967 [(set (match_dup 2) 6968 (unspec:V4SI [(match_dup 1)] UNSPEC_MBTOHE_INTERNAL)) 6969 (set (match_dup 3) 6970 (match_dup 4)) 6971 (set (match_dup 5) 6972 (match_dup 6))] 6973 " 6974{ 6975 operands[3] = change_address (operands[0], DImode, NULL_RTX); 6976 operands[4] = gen_rtx_REG (DImode, REGNO (operands[2])); 6977 operands[5] = frv_index_memory (operands[0], DImode, 1); 6978 operands[6] = gen_rtx_REG (DImode, REGNO (operands[2])+2); 6979}" 6980 [(set_attr "length" "20") 6981 (set_attr "type" "multi")]) 6982 6983;; Quad product-sum (halfword) instructions only found on the FR400. 6984;; type "mqmach" 6985 6986(define_expand "mqxmachs" 6987 [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "") 6988 (unspec:V4SI [(match_dup 0) 6989 (match_operand:DI 1 "even_fpr_operand" "") 6990 (match_operand:DI 2 "even_fpr_operand" "") 6991 (match_operand:V4QI 3 "accg_operand" "") 6992 (match_dup 4)] 6993 UNSPEC_MQMACH2)) 6994 (set (match_dup 3) 6995 (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH2))])] 6996 "TARGET_MEDIA_REV2" 6997 "operands[4] = GEN_INT (FRV_BUILTIN_MQXMACHS);") 6998 6999(define_expand "mqxmacxhs" 7000 [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "") 7001 (unspec:V4SI [(match_dup 0) 7002 (match_operand:DI 1 "even_fpr_operand" "") 7003 (match_operand:DI 2 "even_fpr_operand" "") 7004 (match_operand:V4QI 3 "accg_operand" "") 7005 (match_dup 4)] 7006 UNSPEC_MQMACH2)) 7007 (set (match_dup 3) 7008 (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH2))])] 7009 "TARGET_MEDIA_REV2" 7010 "operands[4] = GEN_INT (FRV_BUILTIN_MQXMACXHS);") 7011 7012(define_expand "mqmacxhs" 7013 [(parallel [(set (match_operand:V4SI 0 "quad_acc_operand" "") 7014 (unspec:V4SI [(match_dup 0) 7015 (match_operand:DI 1 "even_fpr_operand" "") 7016 (match_operand:DI 2 "even_fpr_operand" "") 7017 (match_operand:V4QI 3 "accg_operand" "") 7018 (match_dup 4)] 7019 UNSPEC_MQMACH2)) 7020 (set (match_dup 3) 7021 (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH2))])] 7022 "TARGET_MEDIA_REV2" 7023 "operands[4] = GEN_INT (FRV_BUILTIN_MQMACXHS);") 7024 7025(define_insn "*mqmach2" 7026 [(set (match_operand:V4SI 0 "quad_acc_operand" "+A") 7027 (unspec:V4SI [(match_dup 0) 7028 (match_operand:DI 1 "even_fpr_operand" "h") 7029 (match_operand:DI 2 "even_fpr_operand" "h") 7030 (match_operand:V4QI 3 "accg_operand" "+B") 7031 (match_operand:SI 4 "const_int_operand" "n")] 7032 UNSPEC_MQMACH2)) 7033 (set (match_dup 3) 7034 (unspec:V4QI [(const_int 0)] UNSPEC_MQMACH2))] 7035 "TARGET_MEDIA_REV2" 7036 "* 7037{ 7038 switch (INTVAL (operands[4])) 7039 { 7040 default: break; 7041 case FRV_BUILTIN_MQXMACHS: return \"mqxmachs %1, %2, %0\"; 7042 case FRV_BUILTIN_MQXMACXHS: return \"mqxmacxhs %1, %2, %0\"; 7043 case FRV_BUILTIN_MQMACXHS: return \"mqmacxhs %1, %2, %0\"; 7044 } 7045 7046 fatal_insn (\"Bad media insn, mqmach2\", insn); 7047}" 7048 [(set_attr "length" "4") 7049 (set_attr "type" "mqmach")]) 7050 7051;; Accumulator addition/subtraction: type "maddacc" 7052 7053(define_expand "maddaccs" 7054 [(parallel [(set (match_operand:SI 0 "acc_operand" "") 7055 (unspec:SI [(match_operand:DI 1 "even_acc_operand" "")] 7056 UNSPEC_MADDACC)) 7057 (set (match_operand:QI 2 "accg_operand" "") 7058 (unspec:QI [(match_operand:HI 3 "accg_operand" "") 7059 (match_dup 4)] 7060 UNSPEC_MADDACC))])] 7061 "TARGET_MEDIA_REV2" 7062 "operands[4] = GEN_INT (FRV_BUILTIN_MADDACCS);") 7063 7064(define_expand "msubaccs" 7065 [(parallel [(set (match_operand:SI 0 "acc_operand" "") 7066 (unspec:SI [(match_operand:DI 1 "even_acc_operand" "")] 7067 UNSPEC_MADDACC)) 7068 (set (match_operand:QI 2 "accg_operand" "") 7069 (unspec:QI [(match_operand:HI 3 "accg_operand" "") 7070 (match_dup 4)] 7071 UNSPEC_MADDACC))])] 7072 "TARGET_MEDIA_REV2" 7073 "operands[4] = GEN_INT (FRV_BUILTIN_MSUBACCS);") 7074 7075(define_insn "masaccs" 7076 [(set (match_operand:DI 0 "even_acc_operand" "=b") 7077 (unspec:DI [(match_operand:DI 1 "even_acc_operand" "b")] 7078 UNSPEC_MASACCS)) 7079 (set (match_operand:HI 2 "accg_operand" "=B") 7080 (unspec:HI [(match_operand:HI 3 "accg_operand" "B")] 7081 UNSPEC_MASACCS))] 7082 "TARGET_MEDIA_REV2" 7083 "masaccs %1, %0" 7084 [(set_attr "length" "4") 7085 (set_attr "type" "maddacc")]) 7086 7087(define_insn "*maddacc" 7088 [(set (match_operand:SI 0 "acc_operand" "=a") 7089 (unspec:SI [(match_operand:DI 1 "even_acc_operand" "b")] 7090 UNSPEC_MADDACC)) 7091 (set (match_operand:QI 2 "accg_operand" "=B") 7092 (unspec:QI [(match_operand:HI 3 "accg_operand" "B") 7093 (match_operand:SI 4 "const_int_operand" "n")] 7094 UNSPEC_MADDACC))] 7095 "TARGET_MEDIA_REV2" 7096 "* 7097{ 7098 switch (INTVAL (operands[4])) 7099 { 7100 default: break; 7101 case FRV_BUILTIN_MADDACCS: return \"maddaccs %1, %0\"; 7102 case FRV_BUILTIN_MSUBACCS: return \"msubaccs %1, %0\"; 7103 } 7104 7105 fatal_insn (\"Bad media insn, maddacc\", insn); 7106}" 7107 [(set_attr "length" "4") 7108 (set_attr "type" "maddacc")]) 7109 7110;; Dual accumulator addition/subtraction: type "mdaddacc" 7111 7112(define_expand "mdaddaccs" 7113 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "") 7114 (unspec:DI [(match_operand:V4SI 1 "quad_acc_operand" "")] 7115 UNSPEC_MDADDACC)) 7116 (set (match_operand:HI 2 "accg_operand" "") 7117 (unspec:HI [(match_operand:V4QI 3 "accg_operand" "") 7118 (match_dup 4)] 7119 UNSPEC_MDADDACC))])] 7120 "TARGET_MEDIA_REV2" 7121 "operands[4] = GEN_INT (FRV_BUILTIN_MDADDACCS);") 7122 7123(define_expand "mdsubaccs" 7124 [(parallel [(set (match_operand:DI 0 "even_acc_operand" "") 7125 (unspec:DI [(match_operand:V4SI 1 "quad_acc_operand" "")] 7126 UNSPEC_MDADDACC)) 7127 (set (match_operand:HI 2 "accg_operand" "") 7128 (unspec:HI [(match_operand:V4QI 3 "accg_operand" "") 7129 (match_dup 4)] 7130 UNSPEC_MDADDACC))])] 7131 "TARGET_MEDIA_REV2" 7132 "operands[4] = GEN_INT (FRV_BUILTIN_MDSUBACCS);") 7133 7134(define_insn "mdasaccs" 7135 [(set (match_operand:V4SI 0 "quad_acc_operand" "=A") 7136 (unspec:V4SI [(match_operand:V4SI 1 "quad_acc_operand" "A")] 7137 UNSPEC_MDASACCS)) 7138 (set (match_operand:V4QI 2 "accg_operand" "=B") 7139 (unspec:V4QI [(match_operand:V4QI 3 "accg_operand" "B")] 7140 UNSPEC_MDASACCS))] 7141 "TARGET_MEDIA_REV2" 7142 "mdasaccs %1, %0" 7143 [(set_attr "length" "4") 7144 (set_attr "type" "mdaddacc")]) 7145 7146(define_insn "*mdaddacc" 7147 [(set (match_operand:DI 0 "even_acc_operand" "=b") 7148 (unspec:DI [(match_operand:V4SI 1 "quad_acc_operand" "A")] 7149 UNSPEC_MDADDACC)) 7150 (set (match_operand:HI 2 "accg_operand" "=B") 7151 (unspec:HI [(match_operand:V4QI 3 "accg_operand" "B") 7152 (match_operand:SI 4 "const_int_operand" "n")] 7153 UNSPEC_MDADDACC))] 7154 "TARGET_MEDIA_REV2" 7155 "* 7156{ 7157 switch (INTVAL (operands[4])) 7158 { 7159 default: break; 7160 case FRV_BUILTIN_MDADDACCS: return \"mdaddaccs %1, %0\"; 7161 case FRV_BUILTIN_MDSUBACCS: return \"mdsubaccs %1, %0\"; 7162 } 7163 7164 fatal_insn (\"Bad media insn, mdaddacc\", insn); 7165}" 7166 [(set_attr "length" "4") 7167 (set_attr "type" "mdaddacc")]) 7168 7169;; Dual absolute (halfword): type "mabsh" 7170 7171(define_insn "mabshs" 7172 [(set (match_operand:SI 0 "fpr_operand" "=f") 7173 (unspec:SI [(match_operand:SI 1 "fpr_operand" "f")] UNSPEC_MABSHS))] 7174 "TARGET_MEDIA_REV2" 7175 "mabshs %1, %0" 7176 [(set_attr "length" "4") 7177 (set_attr "type" "mabsh")]) 7178 7179;; Dual rotate: type "mdrot" 7180 7181(define_insn "mdrotli" 7182 [(set (match_operand:DI 0 "even_fpr_operand" "=h") 7183 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h") 7184 (match_operand:SI 2 "uint5_operand" "I")] 7185 UNSPEC_MDROTLI))] 7186 "TARGET_MEDIA_REV2" 7187 "mdrotli %1, %2, %0" 7188 [(set_attr "length" "4") 7189 (set_attr "type" "mdrot")]) 7190 7191;; Dual coupling (concatenation): type "mcpl" 7192 7193(define_insn "mcplhi" 7194 [(set (match_operand:SI 0 "fpr_operand" "=f") 7195 (unspec:SI [(match_operand:DI 1 "fpr_operand" "h") 7196 (match_operand:SI 2 "uint4_operand" "I")] 7197 UNSPEC_MCPLHI))] 7198 "TARGET_MEDIA_REV2" 7199 "mcplhi %1, %2, %0" 7200 [(set_attr "length" "4") 7201 (set_attr "type" "mcpl")]) 7202 7203(define_insn "mcpli" 7204 [(set (match_operand:SI 0 "fpr_operand" "=f") 7205 (unspec:SI [(match_operand:DI 1 "fpr_operand" "h") 7206 (match_operand:SI 2 "uint5_operand" "I")] 7207 UNSPEC_MCPLI))] 7208 "TARGET_MEDIA_REV2" 7209 "mcpli %1, %2, %0" 7210 [(set_attr "length" "4") 7211 (set_attr "type" "mcpl")]) 7212 7213;; Dual cut: type "mdcut" 7214 7215(define_insn "mdcutssi" 7216 [(set (match_operand:DI 0 "even_fpr_operand" "=h") 7217 (unspec:DI [(match_operand:DI 1 "even_acc_operand" "b") 7218 (match_operand:SI 2 "int6_operand" "I") 7219 (match_operand:HI 3 "accg_operand" "B")] 7220 UNSPEC_MDCUTSSI))] 7221 "TARGET_MEDIA_REV2" 7222 "mdcutssi %1, %2, %0" 7223 [(set_attr "length" "4") 7224 (set_attr "type" "mdcut")]) 7225 7226;; Quad saturate (halfword): type "mqsath" 7227 7228(define_insn "mqsaths" 7229 [(set (match_operand:DI 0 "even_fpr_operand" "=h") 7230 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h") 7231 (match_operand:DI 2 "even_fpr_operand" "h")] 7232 UNSPEC_MQSATHS))] 7233 "TARGET_MEDIA_REV2" 7234 "mqsaths %1, %2, %0" 7235 [(set_attr "length" "4") 7236 (set_attr "type" "mqsath")]) 7237 7238;; Quad limit instructions: type "mqlimh" 7239 7240(define_insn "mqlclrhs" 7241 [(set (match_operand:DI 0 "even_fpr_operand" "=h") 7242 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h") 7243 (match_operand:DI 2 "even_fpr_operand" "h")] 7244 UNSPEC_MQLCLRHS))] 7245 "TARGET_MEDIA_FR450" 7246 "mqlclrhs %1, %2, %0" 7247 [(set_attr "length" "4") 7248 (set_attr "type" "mqlimh")]) 7249 7250(define_insn "mqlmths" 7251 [(set (match_operand:DI 0 "even_fpr_operand" "=h") 7252 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h") 7253 (match_operand:DI 2 "even_fpr_operand" "h")] 7254 UNSPEC_MQLMTHS))] 7255 "TARGET_MEDIA_FR450" 7256 "mqlmths %1, %2, %0" 7257 [(set_attr "length" "4") 7258 (set_attr "type" "mqlimh")]) 7259 7260(define_insn "mqsllhi" 7261 [(set (match_operand:DI 0 "even_fpr_operand" "=h") 7262 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h") 7263 (match_operand:SI 2 "int6_operand" "I")] 7264 UNSPEC_MQSLLHI))] 7265 "TARGET_MEDIA_FR450" 7266 "mqsllhi %1, %2, %0" 7267 [(set_attr "length" "4") 7268 (set_attr "type" "mqshift")]) 7269 7270(define_insn "mqsrahi" 7271 [(set (match_operand:DI 0 "even_fpr_operand" "=h") 7272 (unspec:DI [(match_operand:DI 1 "even_fpr_operand" "h") 7273 (match_operand:SI 2 "int6_operand" "I")] 7274 UNSPEC_MQSRAHI))] 7275 "TARGET_MEDIA_FR450" 7276 "mqsrahi %1, %2, %0" 7277 [(set_attr "length" "4") 7278 (set_attr "type" "mqshift")]) 7279 7280;; Set hi/lo instructions: type "mset" 7281 7282(define_insn "mhsetlos" 7283 [(set (match_operand:SI 0 "fpr_operand" "=f") 7284 (unspec:SI [(match_operand:SI 1 "fpr_operand" "0") 7285 (match_operand:SI 2 "int12_operand" "NOP")] 7286 UNSPEC_MHSETLOS))] 7287 "TARGET_MEDIA_REV2" 7288 "mhsetlos %2, %0" 7289 [(set_attr "length" "4") 7290 (set_attr "type" "mset")]) 7291 7292(define_insn "mhsetloh" 7293 [(set (match_operand:SI 0 "fpr_operand" "=f") 7294 (unspec:SI [(match_operand:SI 1 "fpr_operand" "0") 7295 (match_operand:SI 2 "int5_operand" "I")] 7296 UNSPEC_MHSETLOH))] 7297 "TARGET_MEDIA_REV2" 7298 "mhsetloh %2, %0" 7299 [(set_attr "length" "4") 7300 (set_attr "type" "mset")]) 7301 7302(define_insn "mhsethis" 7303 [(set (match_operand:SI 0 "fpr_operand" "=f") 7304 (unspec:SI [(match_operand:SI 1 "fpr_operand" "0") 7305 (match_operand:SI 2 "int12_operand" "NOP")] 7306 UNSPEC_MHSETHIS))] 7307 "TARGET_MEDIA_REV2" 7308 "mhsethis %2, %0" 7309 [(set_attr "length" "4") 7310 (set_attr "type" "mset")]) 7311 7312(define_insn "mhsethih" 7313 [(set (match_operand:SI 0 "fpr_operand" "=f") 7314 (unspec:SI [(match_operand:SI 1 "fpr_operand" "0") 7315 (match_operand:SI 2 "int5_operand" "I")] 7316 UNSPEC_MHSETHIH))] 7317 "TARGET_MEDIA_REV2" 7318 "mhsethih %2, %0" 7319 [(set_attr "length" "4") 7320 (set_attr "type" "mset")]) 7321 7322(define_insn "mhdsets" 7323 [(set (match_operand:SI 0 "fpr_operand" "=f") 7324 (unspec:SI [(match_operand:SI 1 "int12_operand" "NOP")] 7325 UNSPEC_MHDSETS))] 7326 "TARGET_MEDIA_REV2" 7327 "mhdsets %1, %0" 7328 [(set_attr "length" "4") 7329 (set_attr "type" "mset")]) 7330 7331(define_insn "mhdseth" 7332 [(set (match_operand:SI 0 "fpr_operand" "=f") 7333 (unspec:SI [(match_operand:SI 1 "fpr_operand" "0") 7334 (match_operand:SI 2 "int5_operand" "I")] 7335 UNSPEC_MHDSETH))] 7336 "TARGET_MEDIA_REV2" 7337 "mhdseth %2, %0" 7338 [(set_attr "length" "4") 7339 (set_attr "type" "mset")]) 7340 7341;;----------------------------------------------------------------------------- 7342 7343(define_expand "symGOT2reg" 7344 [(match_operand:SI 0 "" "") 7345 (match_operand:SI 1 "" "") 7346 (match_operand:SI 2 "" "") 7347 (match_operand:SI 3 "" "")] 7348 "" 7349 " 7350{ 7351 rtx_insn *insn = emit_insn (gen_symGOT2reg_i (operands[0], operands[1], 7352 operands[2], operands[3])); 7353 7354 MEM_READONLY_P (SET_SRC (PATTERN (insn))) = 1; 7355 7356 set_unique_reg_note (insn, REG_EQUAL, operands[1]); 7357 7358 DONE; 7359}") 7360 7361(define_expand "symGOT2reg_i" 7362 [(set (match_operand:SI 0 "" "") 7363 (mem:SI (plus:SI (match_operand:SI 2 "" "") 7364 (const:SI (unspec:SI [(match_operand:SI 1 "" "") 7365 (match_operand:SI 3 "" "")] 7366 UNSPEC_GOT)))))] 7367 "" 7368 "") 7369 7370(define_expand "symGOT2reg_hilo" 7371 [(set (match_dup 6) 7372 (high:SI (const:SI (unspec:SI [(match_operand:SI 1 "" "") 7373 (match_dup 4)] UNSPEC_GOT)))) 7374 (set (match_dup 5) 7375 (lo_sum:SI (match_dup 6) 7376 (const:SI (unspec:SI [(match_dup 1) 7377 (match_operand:SI 3 "" "")] 7378 UNSPEC_GOT)))) 7379 (set (match_operand:SI 0 "" "") 7380 (mem:SI (plus:SI (match_dup 5) 7381 (match_operand:SI 2 "" "")))) 7382 ] 7383 "" 7384 " 7385{ 7386 if (!can_create_pseudo_p ()) 7387 operands[6] = operands[5] = operands[0]; 7388 else 7389 { 7390 operands[6] = gen_reg_rtx (SImode); 7391 operands[5] = gen_reg_rtx (SImode); 7392 } 7393 7394 operands[4] = GEN_INT (INTVAL (operands[3]) + 1); 7395 operands[3] = GEN_INT (INTVAL (operands[3]) + 2); 7396}") 7397 7398(define_expand "symGOTOFF2reg_hilo" 7399 [(set (match_dup 6) 7400 (high:SI (const:SI (unspec:SI [(match_operand:SI 1 "" "") 7401 (match_dup 4)] UNSPEC_GOT)))) 7402 (set (match_dup 5) 7403 (lo_sum:SI (match_dup 6) 7404 (const:SI (unspec:SI [(match_dup 1) 7405 (match_operand:SI 3 "" "")] 7406 UNSPEC_GOT)))) 7407 (set (match_operand:SI 0 "" "") 7408 (plus:SI (match_dup 5) 7409 (match_operand:SI 2 "" ""))) 7410 ] 7411 "" 7412 " 7413{ 7414 if (!can_create_pseudo_p ()) 7415 operands[6] = operands[5] = operands[0]; 7416 else 7417 { 7418 operands[6] = gen_reg_rtx (SImode); 7419 operands[5] = gen_reg_rtx (SImode); 7420 } 7421 7422 operands[4] = GEN_INT (INTVAL (operands[3]) + 1); 7423 operands[3] = GEN_INT (INTVAL (operands[3]) + 2); 7424}") 7425 7426(define_expand "symGOTOFF2reg" 7427 [(match_operand:SI 0 "" "") 7428 (match_operand:SI 1 "" "") 7429 (match_operand:SI 2 "" "") 7430 (match_operand:SI 3 "" "")] 7431 "" 7432 " 7433{ 7434 rtx_insn *insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1], 7435 operands[2], operands[3])); 7436 7437 set_unique_reg_note (insn, REG_EQUAL, operands[1]); 7438 7439 DONE; 7440}") 7441 7442(define_expand "symGOTOFF2reg_i" 7443 [(set (match_operand:SI 0 "" "") 7444 (plus:SI (match_operand:SI 2 "" "") 7445 (const:SI 7446 (unspec:SI [(match_operand:SI 1 "" "") 7447 (match_operand:SI 3 "" "")] 7448 UNSPEC_GOT))))] 7449 "" 7450 "") 7451 7452(define_expand "symGPREL2reg" 7453 [(match_operand:SI 0 "" "") 7454 (match_operand:SI 1 "" "") 7455 (match_operand:SI 2 "" "") 7456 (match_operand:SI 3 "" "") 7457 (match_dup 4)] 7458 "" 7459 " 7460{ 7461 if (!can_create_pseudo_p ()) 7462 operands[4] = operands[0]; 7463 else 7464 operands[4] = gen_reg_rtx (SImode); 7465 7466 emit_insn (frv_gen_GPsym2reg (operands[4], operands[2])); 7467 7468 rtx_insn *insn = emit_insn (gen_symGOTOFF2reg_i (operands[0], operands[1], 7469 operands[4], operands[3])); 7470 7471 set_unique_reg_note (insn, REG_EQUAL, operands[1]); 7472 7473 DONE; 7474}") 7475 7476(define_expand "symGPREL2reg_hilo" 7477 [(match_operand:SI 0 "" "") 7478 (match_operand:SI 1 "" "") 7479 (match_operand:SI 2 "" "") 7480 (match_operand:SI 3 "" "") 7481 (match_dup 4)] 7482 "" 7483 " 7484{ 7485 if (!can_create_pseudo_p ()) 7486 { 7487 emit_insn (gen_symGOT2reg (operands[0], operands[1], operands[2], 7488 GEN_INT (R_FRV_GOT12))); 7489 DONE; 7490 } 7491 7492 operands[4] = gen_reg_rtx (SImode); 7493 7494 emit_insn (frv_gen_GPsym2reg (operands[4], operands[2])); 7495 7496 rtx_insn *insn = emit_insn (gen_symGOTOFF2reg_hilo (operands[0], operands[1], 7497 operands[4], operands[3])); 7498 7499 set_unique_reg_note (insn, REG_EQUAL, operands[1]); 7500 7501 DONE; 7502}") 7503 7504(define_constants 7505 [ 7506 (UNSPEC_SMUL 154) 7507 (UNSPEC_UMUL 155) 7508 (UNSPEC_SMU 156) 7509 (UNSPEC_ADDSS 157) 7510 (UNSPEC_SUBSS 158) 7511 (UNSPEC_SLASS 159) 7512 (UNSPEC_SCAN 160) 7513 (UNSPEC_INTSS 161) 7514 (UNSPEC_SCUTSS 162) 7515 (UNSPEC_PREFETCH0 163) 7516 (UNSPEC_PREFETCH 164) 7517 (UNSPEC_IACCreadll 165) 7518 (UNSPEC_IACCreadl 166) 7519 (UNSPEC_IACCsetll 167) 7520 (UNSPEC_IACCsetl 168) 7521 (UNSPEC_SMASS 169) 7522 (UNSPEC_SMSSS 170) 7523 (UNSPEC_IMUL 171) 7524 7525 (IACC0_REG 171) 7526]) 7527 7528(define_insn "smul" 7529 [(set (match_operand:DI 0 "integer_register_operand" "=d") 7530 (unspec:DI [(match_operand:SI 1 "integer_register_operand" "d") 7531 (match_operand:SI 2 "integer_register_operand" "d")] 7532 UNSPEC_SMUL))] 7533 "" 7534 "smul %1, %2, %0" 7535 [(set_attr "length" "4") 7536 (set_attr "type" "mul")]) 7537 7538(define_insn "umul" 7539 [(set (match_operand:DI 0 "integer_register_operand" "=d") 7540 (unspec:DI [(match_operand:SI 1 "integer_register_operand" "d") 7541 (match_operand:SI 2 "integer_register_operand" "d")] 7542 UNSPEC_UMUL))] 7543 "" 7544 "umul %1, %2, %0" 7545 [(set_attr "length" "4") 7546 (set_attr "type" "mul")]) 7547 7548(define_insn "smass" 7549 [(set (reg:DI IACC0_REG) 7550 (unspec:DI [(match_operand:SI 0 "integer_register_operand" "d") 7551 (match_operand:SI 1 "integer_register_operand" "d") 7552 (reg:DI IACC0_REG)] 7553 UNSPEC_SMASS))] 7554 "TARGET_FR405_BUILTINS" 7555 "smass %1, %0" 7556 [(set_attr "length" "4") 7557 (set_attr "type" "macc")]) 7558 7559(define_insn "smsss" 7560 [(set (reg:DI IACC0_REG) 7561 (unspec:DI [(match_operand:SI 0 "integer_register_operand" "d") 7562 (match_operand:SI 1 "integer_register_operand" "d") 7563 (reg:DI IACC0_REG)] 7564 UNSPEC_SMSSS))] 7565 "TARGET_FR405_BUILTINS" 7566 "smsss %1, %0" 7567 [(set_attr "length" "4") 7568 (set_attr "type" "macc")]) 7569 7570(define_insn "smu" 7571 [(set (reg:DI IACC0_REG) 7572 (unspec:DI [(match_operand:SI 0 "integer_register_operand" "d") 7573 (match_operand:SI 1 "integer_register_operand" "d")] 7574 UNSPEC_SMU))] 7575 "TARGET_FR405_BUILTINS" 7576 "smu %1, %0" 7577 [(set_attr "length" "4") 7578 (set_attr "type" "macc")]) 7579 7580(define_insn "addss" 7581 [(set (match_operand:SI 0 "integer_register_operand" "=d") 7582 (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d") 7583 (match_operand:SI 2 "integer_register_operand" "d")] 7584 UNSPEC_ADDSS))] 7585 "TARGET_FR405_BUILTINS" 7586 "addss %1, %2, %0" 7587 [(set_attr "length" "4") 7588 (set_attr "type" "int")]) 7589 7590(define_insn "subss" 7591 [(set (match_operand:SI 0 "integer_register_operand" "=d") 7592 (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d") 7593 (match_operand:SI 2 "integer_register_operand" "d")] 7594 UNSPEC_SUBSS))] 7595 "TARGET_FR405_BUILTINS" 7596 "subss %1, %2, %0" 7597 [(set_attr "length" "4") 7598 (set_attr "type" "int")]) 7599 7600(define_insn "slass" 7601 [(set (match_operand:SI 0 "integer_register_operand" "=d") 7602 (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d") 7603 (match_operand:SI 2 "integer_register_operand" "d")] 7604 UNSPEC_SLASS))] 7605 "TARGET_FR405_BUILTINS" 7606 "slass %1, %2, %0" 7607 [(set_attr "length" "4") 7608 (set_attr "type" "int")]) 7609 7610(define_insn "scan" 7611 [(set (match_operand:SI 0 "integer_register_operand" "=d") 7612 (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d") 7613 (match_operand:SI 2 "integer_register_operand" "d")] 7614 UNSPEC_SCAN))] 7615 "" 7616 "scan %1, %2, %0" 7617 [(set_attr "length" "4") 7618 (set_attr "type" "scan")]) 7619 7620(define_insn "scutss" 7621 [(set (match_operand:SI 0 "integer_register_operand" "=d") 7622 (unspec:SI [(match_operand:SI 1 "integer_register_operand" "d") 7623 (reg:DI IACC0_REG)] 7624 UNSPEC_SCUTSS))] 7625 "TARGET_FR405_BUILTINS" 7626 "scutss %1,%0" 7627 [(set_attr "length" "4") 7628 (set_attr "type" "cut")]) 7629 7630(define_insn "frv_prefetch0" 7631 [(prefetch (unspec:SI [(match_operand:SI 0 "register_operand" "r")] 7632 UNSPEC_PREFETCH0) 7633 (const_int 0) 7634 (const_int 0))] 7635 "" 7636 "dcpl %0, gr0, #0" 7637 [(set_attr "length" "4")]) 7638 7639(define_insn "frv_prefetch" 7640 [(prefetch (unspec:SI [(match_operand:SI 0 "register_operand" "r")] 7641 UNSPEC_PREFETCH) 7642 (const_int 0) 7643 (const_int 0))] 7644 "TARGET_FR500_FR550_BUILTINS" 7645 "nop.p\\n\\tnldub @(%0, gr0), gr0" 7646 [(set_attr "length" "8")]) 7647 7648;; TLS patterns 7649 7650(define_insn "call_gettlsoff" 7651 [(set (match_operand:SI 0 "register_operand" "=D09") 7652 (unspec:SI 7653 [(match_operand:SI 1 "symbolic_operand" "")] 7654 UNSPEC_GETTLSOFF)) 7655 (clobber (reg:SI GR8_REG)) 7656 (clobber (reg:SI LRREG)) 7657 (use (match_operand:SI 2 "register_operand" "D15"))] 7658 "HAVE_AS_TLS" 7659 "call #gettlsoff(%a1)" 7660 [(set_attr "length" "4") 7661 (set_attr "type" "load_or_call")]) 7662 7663;; We have to expand this like a libcall (it sort of actually is) 7664;; because otherwise sched may move, for example, an insn that sets up 7665;; GR8 for a subsequence call before the *tls_indirect_call insn, and 7666;; then reload won't be able to fix things up. 7667(define_expand "tls_indirect_call" 7668 [(set (reg:DI GR8_REG) 7669 (match_operand:DI 2 "register_operand" "")) 7670 (parallel 7671 [(set (reg:SI GR9_REG) 7672 (unspec:SI 7673 [(match_operand:SI 1 "symbolic_operand" "") 7674 (reg:DI GR8_REG)] 7675 UNSPEC_TLS_INDIRECT_CALL)) 7676 (clobber (reg:SI GR8_REG)) 7677 (clobber (reg:SI LRREG)) 7678 (use (match_operand:SI 3 "register_operand" ""))]) 7679 (set (match_operand:SI 0 "register_operand" "") 7680 (reg:SI GR9_REG))] 7681 "HAVE_AS_TLS") 7682 7683(define_insn "*tls_indirect_call" 7684 [(set (reg:SI GR9_REG) 7685 (unspec:SI 7686 [(match_operand:SI 0 "symbolic_operand" "") 7687 (reg:DI GR8_REG)] 7688 UNSPEC_TLS_INDIRECT_CALL)) 7689 (clobber (reg:SI GR8_REG)) 7690 (clobber (reg:SI LRREG)) 7691 ;; If there was a way to represent the fact that we don't need GR9 7692 ;; or GR15 to be set before this instruction (it could be in 7693 ;; parallel), we could use it here. This change wouldn't apply to 7694 ;; call_gettlsoff, thought, since the linker may turn the latter 7695 ;; into ldi @(gr15,offset),gr9. 7696 (use (match_operand:SI 1 "register_operand" "D15"))] 7697 "HAVE_AS_TLS" 7698 "calll #gettlsoff(%a0)@(gr8,gr0)" 7699 [(set_attr "length" "4") 7700 (set_attr "type" "jumpl")]) 7701 7702(define_insn "tls_load_gottlsoff12" 7703 [(set (match_operand:SI 0 "register_operand" "=r") 7704 (unspec:SI 7705 [(match_operand:SI 1 "symbolic_operand" "") 7706 (match_operand:SI 2 "register_operand" "r")] 7707 UNSPEC_TLS_LOAD_GOTTLSOFF12))] 7708 "HAVE_AS_TLS" 7709 "ldi @(%2, #gottlsoff12(%1)), %0" 7710 [(set_attr "length" "4")]) 7711 7712(define_expand "tlsoff_hilo" 7713 [(set (match_operand:SI 0 "register_operand" "=r") 7714 (high:SI (const:SI (unspec:SI 7715 [(match_operand:SI 1 "symbolic_operand" "") 7716 (match_operand:SI 2 "immediate_operand" "n")] 7717 UNSPEC_GOT)))) 7718 (set (match_dup 0) 7719 (lo_sum:SI (match_dup 0) 7720 (const:SI (unspec:SI [(match_dup 1) 7721 (match_dup 3)] UNSPEC_GOT))))] 7722 "" 7723 " 7724{ 7725 operands[3] = GEN_INT (INTVAL (operands[2]) + 1); 7726}") 7727 7728;; Just like movdi_ldd, but with relaxation annotations. 7729(define_insn "tls_tlsdesc_ldd" 7730 [(set (match_operand:DI 0 "register_operand" "=r") 7731 (unspec:DI [(mem:DI (unspec:SI 7732 [(match_operand:SI 1 "register_operand" "r") 7733 (match_operand:SI 2 "register_operand" "r") 7734 (match_operand:SI 3 "symbolic_operand" "")] 7735 UNSPEC_TLS_TLSDESC_LDD_AUX))] 7736 UNSPEC_TLS_TLSDESC_LDD))] 7737 "" 7738 "ldd #tlsdesc(%a3)@(%1,%2), %0" 7739 [(set_attr "length" "4") 7740 (set_attr "type" "gload")]) 7741 7742(define_insn "tls_tlsoff_ld" 7743 [(set (match_operand:SI 0 "register_operand" "=r") 7744 (mem:SI (unspec:SI 7745 [(match_operand:SI 1 "register_operand" "r") 7746 (match_operand:SI 2 "register_operand" "r") 7747 (match_operand:SI 3 "symbolic_operand" "")] 7748 UNSPEC_TLS_TLSOFF_LD)))] 7749 "" 7750 "ld #tlsoff(%a3)@(%1,%2), %0" 7751 [(set_attr "length" "4") 7752 (set_attr "type" "gload")]) 7753 7754(define_insn "tls_lddi" 7755 [(set (match_operand:DI 0 "register_operand" "=r") 7756 (unspec:DI [(match_operand:SI 1 "symbolic_operand" "") 7757 (match_operand:SI 2 "register_operand" "d")] 7758 UNSPEC_TLS_LDDI))] 7759 "" 7760 "lddi @(%2, #gottlsdesc12(%a1)), %0" 7761 [(set_attr "length" "4") 7762 (set_attr "type" "gload")]) 7763