mips.md revision 169689
1;; Mips.md Machine Description for MIPS based processors 2;; Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 3;; 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. 4;; Contributed by A. Lichnewsky, lich@inria.inria.fr 5;; Changes by Michael Meissner, meissner@osf.org 6;; 64 bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and 7;; Brendan Eich, brendan@microunity.com. 8 9;; This file is part of GCC. 10 11;; GCC is free software; you can redistribute it and/or modify 12;; it under the terms of the GNU General Public License as published by 13;; the Free Software Foundation; either version 2, or (at your option) 14;; any later version. 15 16;; GCC is distributed in the hope that it will be useful, 17;; but WITHOUT ANY WARRANTY; without even the implied warranty of 18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19;; GNU General Public License for more details. 20 21;; You should have received a copy of the GNU General Public License 22;; along with GCC; see the file COPYING. If not, write to 23;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, 24;; Boston, MA 02110-1301, USA. 25 26(define_constants 27 [(UNSPEC_LOAD_DF_LOW 0) 28 (UNSPEC_LOAD_DF_HIGH 1) 29 (UNSPEC_STORE_DF_HIGH 2) 30 (UNSPEC_GET_FNADDR 3) 31 (UNSPEC_BLOCKAGE 4) 32 (UNSPEC_CPRESTORE 5) 33 (UNSPEC_EH_RECEIVER 6) 34 (UNSPEC_EH_RETURN 7) 35 (UNSPEC_CONSTTABLE_INT 8) 36 (UNSPEC_CONSTTABLE_FLOAT 9) 37 (UNSPEC_ALIGN 14) 38 (UNSPEC_HIGH 17) 39 (UNSPEC_LOAD_LEFT 18) 40 (UNSPEC_LOAD_RIGHT 19) 41 (UNSPEC_STORE_LEFT 20) 42 (UNSPEC_STORE_RIGHT 21) 43 (UNSPEC_LOADGP 22) 44 (UNSPEC_LOAD_CALL 23) 45 (UNSPEC_LOAD_GOT 24) 46 (UNSPEC_GP 25) 47 (UNSPEC_MFHILO 26) 48 (UNSPEC_TLS_LDM 27) 49 (UNSPEC_TLS_GET_TP 28) 50 51 (UNSPEC_ADDRESS_FIRST 100) 52 53 (FAKE_CALL_REGNO 79) 54 55 ;; For MIPS Paired-Singled Floating Point Instructions. 56 57 (UNSPEC_MOVE_TF_PS 200) 58 (UNSPEC_C 201) 59 60 ;; MIPS64/MIPS32R2 alnv.ps 61 (UNSPEC_ALNV_PS 202) 62 63 ;; MIPS-3D instructions 64 (UNSPEC_CABS 203) 65 66 (UNSPEC_ADDR_PS 204) 67 (UNSPEC_CVT_PW_PS 205) 68 (UNSPEC_CVT_PS_PW 206) 69 (UNSPEC_MULR_PS 207) 70 (UNSPEC_ABS_PS 208) 71 72 (UNSPEC_RSQRT1 209) 73 (UNSPEC_RSQRT2 210) 74 (UNSPEC_RECIP1 211) 75 (UNSPEC_RECIP2 212) 76 (UNSPEC_SINGLE_CC 213) 77 (UNSPEC_SCC 214) 78 79 ;; MIPS DSP ASE Revision 0.98 3/24/2005 80 (UNSPEC_ADDQ 300) 81 (UNSPEC_ADDQ_S 301) 82 (UNSPEC_SUBQ 302) 83 (UNSPEC_SUBQ_S 303) 84 (UNSPEC_ADDSC 304) 85 (UNSPEC_ADDWC 305) 86 (UNSPEC_MODSUB 306) 87 (UNSPEC_RADDU_W_QB 307) 88 (UNSPEC_ABSQ_S 308) 89 (UNSPEC_PRECRQ_QB_PH 309) 90 (UNSPEC_PRECRQ_PH_W 310) 91 (UNSPEC_PRECRQ_RS_PH_W 311) 92 (UNSPEC_PRECRQU_S_QB_PH 312) 93 (UNSPEC_PRECEQ_W_PHL 313) 94 (UNSPEC_PRECEQ_W_PHR 314) 95 (UNSPEC_PRECEQU_PH_QBL 315) 96 (UNSPEC_PRECEQU_PH_QBR 316) 97 (UNSPEC_PRECEQU_PH_QBLA 317) 98 (UNSPEC_PRECEQU_PH_QBRA 318) 99 (UNSPEC_PRECEU_PH_QBL 319) 100 (UNSPEC_PRECEU_PH_QBR 320) 101 (UNSPEC_PRECEU_PH_QBLA 321) 102 (UNSPEC_PRECEU_PH_QBRA 322) 103 (UNSPEC_SHLL 323) 104 (UNSPEC_SHLL_S 324) 105 (UNSPEC_SHRL_QB 325) 106 (UNSPEC_SHRA_PH 326) 107 (UNSPEC_SHRA_R 327) 108 (UNSPEC_MULEU_S_PH_QBL 328) 109 (UNSPEC_MULEU_S_PH_QBR 329) 110 (UNSPEC_MULQ_RS_PH 330) 111 (UNSPEC_MULEQ_S_W_PHL 331) 112 (UNSPEC_MULEQ_S_W_PHR 332) 113 (UNSPEC_DPAU_H_QBL 333) 114 (UNSPEC_DPAU_H_QBR 334) 115 (UNSPEC_DPSU_H_QBL 335) 116 (UNSPEC_DPSU_H_QBR 336) 117 (UNSPEC_DPAQ_S_W_PH 337) 118 (UNSPEC_DPSQ_S_W_PH 338) 119 (UNSPEC_MULSAQ_S_W_PH 339) 120 (UNSPEC_DPAQ_SA_L_W 340) 121 (UNSPEC_DPSQ_SA_L_W 341) 122 (UNSPEC_MAQ_S_W_PHL 342) 123 (UNSPEC_MAQ_S_W_PHR 343) 124 (UNSPEC_MAQ_SA_W_PHL 344) 125 (UNSPEC_MAQ_SA_W_PHR 345) 126 (UNSPEC_BITREV 346) 127 (UNSPEC_INSV 347) 128 (UNSPEC_REPL_QB 348) 129 (UNSPEC_REPL_PH 349) 130 (UNSPEC_CMP_EQ 350) 131 (UNSPEC_CMP_LT 351) 132 (UNSPEC_CMP_LE 352) 133 (UNSPEC_CMPGU_EQ_QB 353) 134 (UNSPEC_CMPGU_LT_QB 354) 135 (UNSPEC_CMPGU_LE_QB 355) 136 (UNSPEC_PICK 356) 137 (UNSPEC_PACKRL_PH 357) 138 (UNSPEC_EXTR_W 358) 139 (UNSPEC_EXTR_R_W 359) 140 (UNSPEC_EXTR_RS_W 360) 141 (UNSPEC_EXTR_S_H 361) 142 (UNSPEC_EXTP 362) 143 (UNSPEC_EXTPDP 363) 144 (UNSPEC_SHILO 364) 145 (UNSPEC_MTHLIP 365) 146 (UNSPEC_WRDSP 366) 147 (UNSPEC_RDDSP 367) 148 ] 149) 150 151(include "predicates.md") 152(include "constraints.md") 153 154;; .................... 155;; 156;; Attributes 157;; 158;; .................... 159 160(define_attr "got" "unset,xgot_high,load" 161 (const_string "unset")) 162 163;; For jal instructions, this attribute is DIRECT when the target address 164;; is symbolic and INDIRECT when it is a register. 165(define_attr "jal" "unset,direct,indirect" 166 (const_string "unset")) 167 168;; This attribute is YES if the instruction is a jal macro (not a 169;; real jal instruction). 170;; 171;; jal is always a macro for o32 and o64 abicalls because it includes an 172;; instruction to restore $gp. Direct jals are also macros for -mshared 173;; abicalls because they first load the target address into $25. 174(define_attr "jal_macro" "no,yes" 175 (cond [(eq_attr "jal" "direct") 176 (symbol_ref "TARGET_ABICALLS 177 && (TARGET_OLDABI || !TARGET_ABSOLUTE_ABICALLS)") 178 (eq_attr "jal" "indirect") 179 (symbol_ref "TARGET_ABICALLS && TARGET_OLDABI")] 180 (const_string "no"))) 181 182;; Classification of each insn. 183;; branch conditional branch 184;; jump unconditional jump 185;; call unconditional call 186;; load load instruction(s) 187;; fpload floating point load 188;; fpidxload floating point indexed load 189;; store store instruction(s) 190;; fpstore floating point store 191;; fpidxstore floating point indexed store 192;; prefetch memory prefetch (register + offset) 193;; prefetchx memory indexed prefetch (register + register) 194;; condmove conditional moves 195;; xfer transfer to/from coprocessor 196;; mthilo transfer to hi/lo registers 197;; mfhilo transfer from hi/lo registers 198;; const load constant 199;; arith integer arithmetic and logical instructions 200;; shift integer shift instructions 201;; slt set less than instructions 202;; clz the clz and clo instructions 203;; trap trap if instructions 204;; imul integer multiply 2 operands 205;; imul3 integer multiply 3 operands 206;; imadd integer multiply-add 207;; idiv integer divide 208;; fmove floating point register move 209;; fadd floating point add/subtract 210;; fmul floating point multiply 211;; fmadd floating point multiply-add 212;; fdiv floating point divide 213;; frdiv floating point reciprocal divide 214;; frdiv1 floating point reciprocal divide step 1 215;; frdiv2 floating point reciprocal divide step 2 216;; fabs floating point absolute value 217;; fneg floating point negation 218;; fcmp floating point compare 219;; fcvt floating point convert 220;; fsqrt floating point square root 221;; frsqrt floating point reciprocal square root 222;; frsqrt1 floating point reciprocal square root step1 223;; frsqrt2 floating point reciprocal square root step2 224;; multi multiword sequence (or user asm statements) 225;; nop no operation 226(define_attr "type" 227 "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imul3,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1,frsqrt2,multi,nop" 228 (cond [(eq_attr "jal" "!unset") (const_string "call") 229 (eq_attr "got" "load") (const_string "load")] 230 (const_string "unknown"))) 231 232;; Main data type used by the insn 233(define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" 234 (const_string "unknown")) 235 236;; Mode for conversion types (fcvt) 237;; I2S integer to float single (SI/DI to SF) 238;; I2D integer to float double (SI/DI to DF) 239;; S2I float to integer (SF to SI/DI) 240;; D2I float to integer (DF to SI/DI) 241;; D2S double to float single 242;; S2D float single to double 243 244(define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D" 245 (const_string "unknown")) 246 247;; Is this an extended instruction in mips16 mode? 248(define_attr "extended_mips16" "no,yes" 249 (const_string "no")) 250 251;; Length of instruction in bytes. 252(define_attr "length" "" 253 (cond [;; Direct branch instructions have a range of [-0x40000,0x3fffc]. 254 ;; If a branch is outside this range, we have a choice of two 255 ;; sequences. For PIC, an out-of-range branch like: 256 ;; 257 ;; bne r1,r2,target 258 ;; dslot 259 ;; 260 ;; becomes the equivalent of: 261 ;; 262 ;; beq r1,r2,1f 263 ;; dslot 264 ;; la $at,target 265 ;; jr $at 266 ;; nop 267 ;; 1: 268 ;; 269 ;; where the load address can be up to three instructions long 270 ;; (lw, nop, addiu). 271 ;; 272 ;; The non-PIC case is similar except that we use a direct 273 ;; jump instead of an la/jr pair. Since the target of this 274 ;; jump is an absolute 28-bit bit address (the other bits 275 ;; coming from the address of the delay slot) this form cannot 276 ;; cross a 256MB boundary. We could provide the option of 277 ;; using la/jr in this case too, but we do not do so at 278 ;; present. 279 ;; 280 ;; Note that this value does not account for the delay slot 281 ;; instruction, whose length is added separately. If the RTL 282 ;; pattern has no explicit delay slot, mips_adjust_insn_length 283 ;; will add the length of the implicit nop. The values for 284 ;; forward and backward branches will be different as well. 285 (eq_attr "type" "branch") 286 (cond [(and (le (minus (match_dup 1) (pc)) (const_int 131064)) 287 (le (minus (pc) (match_dup 1)) (const_int 131068))) 288 (const_int 4) 289 (ne (symbol_ref "flag_pic") (const_int 0)) 290 (const_int 24) 291 ] (const_int 12)) 292 293 (eq_attr "got" "load") 294 (const_int 4) 295 (eq_attr "got" "xgot_high") 296 (const_int 8) 297 298 (eq_attr "type" "const") 299 (symbol_ref "mips_const_insns (operands[1]) * 4") 300 (eq_attr "type" "load,fpload") 301 (symbol_ref "mips_fetch_insns (operands[1]) * 4") 302 (eq_attr "type" "store,fpstore") 303 (symbol_ref "mips_fetch_insns (operands[0]) * 4") 304 305 ;; In the worst case, a call macro will take 8 instructions: 306 ;; 307 ;; lui $25,%call_hi(FOO) 308 ;; addu $25,$25,$28 309 ;; lw $25,%call_lo(FOO)($25) 310 ;; nop 311 ;; jalr $25 312 ;; nop 313 ;; lw $gp,X($sp) 314 ;; nop 315 (eq_attr "jal_macro" "yes") 316 (const_int 32) 317 318 (and (eq_attr "extended_mips16" "yes") 319 (ne (symbol_ref "TARGET_MIPS16") (const_int 0))) 320 (const_int 8) 321 322 ;; Various VR4120 errata require a nop to be inserted after a macc 323 ;; instruction. The assembler does this for us, so account for 324 ;; the worst-case length here. 325 (and (eq_attr "type" "imadd") 326 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))) 327 (const_int 8) 328 329 ;; VR4120 errata MD(4): if there are consecutive dmult instructions, 330 ;; the result of the second one is missed. The assembler should work 331 ;; around this by inserting a nop after the first dmult. 332 (and (eq_attr "type" "imul,imul3") 333 (and (eq_attr "mode" "DI") 334 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))) 335 (const_int 8) 336 337 (eq_attr "type" "idiv") 338 (symbol_ref "mips_idiv_insns () * 4") 339 ] (const_int 4))) 340 341;; Attribute describing the processor. This attribute must match exactly 342;; with the processor_type enumeration in mips.h. 343(define_attr "cpu" 344 "r3000,4kc,4kp,5kc,5kf,20kc,24k,24kx,m4k,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,sb1,sb1a,sr71000" 345 (const (symbol_ref "mips_tune"))) 346 347;; The type of hardware hazard associated with this instruction. 348;; DELAY means that the next instruction cannot read the result 349;; of this one. HILO means that the next two instructions cannot 350;; write to HI or LO. 351(define_attr "hazard" "none,delay,hilo" 352 (cond [(and (eq_attr "type" "load,fpload,fpidxload") 353 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0))) 354 (const_string "delay") 355 356 (and (eq_attr "type" "xfer") 357 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0))) 358 (const_string "delay") 359 360 (and (eq_attr "type" "fcmp") 361 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0))) 362 (const_string "delay") 363 364 ;; The r4000 multiplication patterns include an mflo instruction. 365 (and (eq_attr "type" "imul") 366 (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0))) 367 (const_string "hilo") 368 369 (and (eq_attr "type" "mfhilo") 370 (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0))) 371 (const_string "hilo")] 372 (const_string "none"))) 373 374;; Is it a single instruction? 375(define_attr "single_insn" "no,yes" 376 (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)")) 377 378;; Can the instruction be put into a delay slot? 379(define_attr "can_delay" "no,yes" 380 (if_then_else (and (eq_attr "type" "!branch,call,jump") 381 (and (eq_attr "hazard" "none") 382 (eq_attr "single_insn" "yes"))) 383 (const_string "yes") 384 (const_string "no"))) 385 386;; Attribute defining whether or not we can use the branch-likely instructions 387(define_attr "branch_likely" "no,yes" 388 (const 389 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0)) 390 (const_string "yes") 391 (const_string "no")))) 392 393;; True if an instruction might assign to hi or lo when reloaded. 394;; This is used by the TUNE_MACC_CHAINS code. 395(define_attr "may_clobber_hilo" "no,yes" 396 (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthilo") 397 (const_string "yes") 398 (const_string "no"))) 399 400;; Describe a user's asm statement. 401(define_asm_attributes 402 [(set_attr "type" "multi") 403 (set_attr "can_delay" "no")]) 404 405;; This mode macro allows 32-bit and 64-bit GPR patterns to be generated 406;; from the same template. 407(define_mode_macro GPR [SI (DI "TARGET_64BIT")]) 408 409;; This mode macro allows :P to be used for patterns that operate on 410;; pointer-sized quantities. Exactly one of the two alternatives will match. 411(define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) 412 413;; This mode macro allows :MOVECC to be used anywhere that a 414;; conditional-move-type condition is needed. 415(define_mode_macro MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")]) 416 417;; This mode macro allows the QI and HI extension patterns to be defined from 418;; the same template. 419(define_mode_macro SHORT [QI HI]) 420 421;; This mode macro allows :ANYF to be used wherever a scalar or vector 422;; floating-point mode is allowed. 423(define_mode_macro ANYF [(SF "TARGET_HARD_FLOAT") 424 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT") 425 (V2SF "TARGET_PAIRED_SINGLE_FLOAT")]) 426 427;; Like ANYF, but only applies to scalar modes. 428(define_mode_macro SCALARF [(SF "TARGET_HARD_FLOAT") 429 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")]) 430 431;; In GPR templates, a string like "<d>subu" will expand to "subu" in the 432;; 32-bit version and "dsubu" in the 64-bit version. 433(define_mode_attr d [(SI "") (DI "d")]) 434 435;; This attribute gives the length suffix for a sign- or zero-extension 436;; instruction. 437(define_mode_attr size [(QI "b") (HI "h")]) 438 439;; This attributes gives the mode mask of a SHORT. 440(define_mode_attr mask [(QI "0x00ff") (HI "0xffff")]) 441 442;; Mode attributes for GPR loads and stores. 443(define_mode_attr load [(SI "lw") (DI "ld")]) 444(define_mode_attr store [(SI "sw") (DI "sd")]) 445 446;; Similarly for MIPS IV indexed FPR loads and stores. 447(define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")]) 448(define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")]) 449 450;; The unextended ranges of the MIPS16 addiu and daddiu instructions 451;; are different. Some forms of unextended addiu have an 8-bit immediate 452;; field but the equivalent daddiu has only a 5-bit field. 453(define_mode_attr si8_di5 [(SI "8") (DI "5")]) 454 455;; This attribute gives the best constraint to use for registers of 456;; a given mode. 457(define_mode_attr reg [(SI "d") (DI "d") (CC "z")]) 458 459;; This attribute gives the format suffix for floating-point operations. 460(define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")]) 461 462;; This attribute gives the upper-case mode name for one unit of a 463;; floating-point mode. 464(define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")]) 465 466;; This attribute works around the early SB-1 rev2 core "F2" erratum: 467;; 468;; In certain cases, div.s and div.ps may have a rounding error 469;; and/or wrong inexact flag. 470;; 471;; Therefore, we only allow div.s if not working around SB-1 rev2 472;; errata or if a slight loss of precision is OK. 473(define_mode_attr divide_condition 474 [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations") 475 (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")]) 476 477; This attribute gives the condition for which sqrt instructions exist. 478(define_mode_attr sqrt_condition 479 [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")]) 480 481; This attribute gives the condition for which recip and rsqrt instructions 482; exist. 483(define_mode_attr recip_condition 484 [(SF "ISA_HAS_FP4") (DF "ISA_HAS_FP4") (V2SF "TARGET_SB1")]) 485 486;; This code macro allows all branch instructions to be generated from 487;; a single define_expand template. 488(define_code_macro any_cond [unordered ordered unlt unge uneq ltgt unle ungt 489 eq ne gt ge lt le gtu geu ltu leu]) 490 491;; This code macro allows signed and unsigned widening multiplications 492;; to use the same template. 493(define_code_macro any_extend [sign_extend zero_extend]) 494 495;; This code macro allows the three shift instructions to be generated 496;; from the same template. 497(define_code_macro any_shift [ashift ashiftrt lshiftrt]) 498 499;; This code macro allows all native floating-point comparisons to be 500;; generated from the same template. 501(define_code_macro fcond [unordered uneq unlt unle eq lt le]) 502 503;; This code macro is used for comparisons that can be implemented 504;; by swapping the operands. 505(define_code_macro swapped_fcond [ge gt unge ungt]) 506 507;; <u> expands to an empty string when doing a signed operation and 508;; "u" when doing an unsigned operation. 509(define_code_attr u [(sign_extend "") (zero_extend "u")]) 510 511;; <su> is like <u>, but the signed form expands to "s" rather than "". 512(define_code_attr su [(sign_extend "s") (zero_extend "u")]) 513 514;; <optab> expands to the name of the optab for a particular code. 515(define_code_attr optab [(ashift "ashl") 516 (ashiftrt "ashr") 517 (lshiftrt "lshr")]) 518 519;; <insn> expands to the name of the insn that implements a particular code. 520(define_code_attr insn [(ashift "sll") 521 (ashiftrt "sra") 522 (lshiftrt "srl")]) 523 524;; <fcond> is the c.cond.fmt condition associated with a particular code. 525(define_code_attr fcond [(unordered "un") 526 (uneq "ueq") 527 (unlt "ult") 528 (unle "ule") 529 (eq "eq") 530 (lt "lt") 531 (le "le")]) 532 533;; Similar, but for swapped conditions. 534(define_code_attr swapped_fcond [(ge "le") 535 (gt "lt") 536 (unge "ule") 537 (ungt "ult")]) 538 539;; ......................... 540;; 541;; Branch, call and jump delay slots 542;; 543;; ......................... 544 545(define_delay (and (eq_attr "type" "branch") 546 (eq (symbol_ref "TARGET_MIPS16") (const_int 0))) 547 [(eq_attr "can_delay" "yes") 548 (nil) 549 (and (eq_attr "branch_likely" "yes") 550 (eq_attr "can_delay" "yes"))]) 551 552(define_delay (eq_attr "type" "jump") 553 [(eq_attr "can_delay" "yes") 554 (nil) 555 (nil)]) 556 557(define_delay (and (eq_attr "type" "call") 558 (eq_attr "jal_macro" "no")) 559 [(eq_attr "can_delay" "yes") 560 (nil) 561 (nil)]) 562 563;; Pipeline descriptions. 564;; 565;; generic.md provides a fallback for processors without a specific 566;; pipeline description. It is derived from the old define_function_unit 567;; version and uses the "alu" and "imuldiv" units declared below. 568;; 569;; Some of the processor-specific files are also derived from old 570;; define_function_unit descriptions and simply override the parts of 571;; generic.md that don't apply. The other processor-specific files 572;; are self-contained. 573(define_automaton "alu,imuldiv") 574 575(define_cpu_unit "alu" "alu") 576(define_cpu_unit "imuldiv" "imuldiv") 577 578(include "4k.md") 579(include "5k.md") 580(include "24k.md") 581(include "3000.md") 582(include "4000.md") 583(include "4100.md") 584(include "4130.md") 585(include "4300.md") 586(include "4600.md") 587(include "5000.md") 588(include "5400.md") 589(include "5500.md") 590(include "6000.md") 591(include "7000.md") 592(include "9000.md") 593(include "sb1.md") 594(include "sr71k.md") 595(include "generic.md") 596 597;; 598;; .................... 599;; 600;; CONDITIONAL TRAPS 601;; 602;; .................... 603;; 604 605(define_insn "trap" 606 [(trap_if (const_int 1) (const_int 0))] 607 "" 608{ 609 if (ISA_HAS_COND_TRAP) 610 return "teq\t$0,$0"; 611 else if (TARGET_MIPS16) 612 return "break 0"; 613 else 614 return "break"; 615} 616 [(set_attr "type" "trap")]) 617 618(define_expand "conditional_trap" 619 [(trap_if (match_operator 0 "comparison_operator" 620 [(match_dup 2) (match_dup 3)]) 621 (match_operand 1 "const_int_operand"))] 622 "ISA_HAS_COND_TRAP" 623{ 624 if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT 625 && operands[1] == const0_rtx) 626 { 627 mips_gen_conditional_trap (operands); 628 DONE; 629 } 630 else 631 FAIL; 632}) 633 634(define_insn "*conditional_trap<mode>" 635 [(trap_if (match_operator:GPR 0 "trap_comparison_operator" 636 [(match_operand:GPR 1 "reg_or_0_operand" "dJ") 637 (match_operand:GPR 2 "arith_operand" "dI")]) 638 (const_int 0))] 639 "ISA_HAS_COND_TRAP" 640 "t%C0\t%z1,%2" 641 [(set_attr "type" "trap")]) 642 643;; 644;; .................... 645;; 646;; ADDITION 647;; 648;; .................... 649;; 650 651(define_insn "add<mode>3" 652 [(set (match_operand:ANYF 0 "register_operand" "=f") 653 (plus:ANYF (match_operand:ANYF 1 "register_operand" "f") 654 (match_operand:ANYF 2 "register_operand" "f")))] 655 "" 656 "add.<fmt>\t%0,%1,%2" 657 [(set_attr "type" "fadd") 658 (set_attr "mode" "<UNITMODE>")]) 659 660(define_expand "add<mode>3" 661 [(set (match_operand:GPR 0 "register_operand") 662 (plus:GPR (match_operand:GPR 1 "register_operand") 663 (match_operand:GPR 2 "arith_operand")))] 664 "") 665 666(define_insn "*add<mode>3" 667 [(set (match_operand:GPR 0 "register_operand" "=d,d") 668 (plus:GPR (match_operand:GPR 1 "register_operand" "d,d") 669 (match_operand:GPR 2 "arith_operand" "d,Q")))] 670 "!TARGET_MIPS16" 671 "@ 672 <d>addu\t%0,%1,%2 673 <d>addiu\t%0,%1,%2" 674 [(set_attr "type" "arith") 675 (set_attr "mode" "<MODE>")]) 676 677;; We need to recognize MIPS16 stack pointer additions explicitly, since 678;; we don't have a constraint for $sp. These insns will be generated by 679;; the save_restore_insns functions. 680 681(define_insn "*add<mode>3_sp1" 682 [(set (reg:GPR 29) 683 (plus:GPR (reg:GPR 29) 684 (match_operand:GPR 0 "const_arith_operand" "")))] 685 "TARGET_MIPS16" 686 "<d>addiu\t%$,%$,%0" 687 [(set_attr "type" "arith") 688 (set_attr "mode" "<MODE>") 689 (set (attr "length") (if_then_else (match_operand 0 "m16_simm8_8") 690 (const_int 4) 691 (const_int 8)))]) 692 693(define_insn "*add<mode>3_sp2" 694 [(set (match_operand:GPR 0 "register_operand" "=d") 695 (plus:GPR (reg:GPR 29) 696 (match_operand:GPR 1 "const_arith_operand" "")))] 697 "TARGET_MIPS16" 698 "<d>addiu\t%0,%$,%1" 699 [(set_attr "type" "arith") 700 (set_attr "mode" "<MODE>") 701 (set (attr "length") (if_then_else (match_operand 1 "m16_uimm<si8_di5>_4") 702 (const_int 4) 703 (const_int 8)))]) 704 705(define_insn "*add<mode>3_mips16" 706 [(set (match_operand:GPR 0 "register_operand" "=d,d,d") 707 (plus:GPR (match_operand:GPR 1 "register_operand" "0,d,d") 708 (match_operand:GPR 2 "arith_operand" "Q,O,d")))] 709 "TARGET_MIPS16" 710 "@ 711 <d>addiu\t%0,%2 712 <d>addiu\t%0,%1,%2 713 <d>addu\t%0,%1,%2" 714 [(set_attr "type" "arith") 715 (set_attr "mode" "<MODE>") 716 (set_attr_alternative "length" 717 [(if_then_else (match_operand 2 "m16_simm<si8_di5>_1") 718 (const_int 4) 719 (const_int 8)) 720 (if_then_else (match_operand 2 "m16_simm4_1") 721 (const_int 4) 722 (const_int 8)) 723 (const_int 4)])]) 724 725 726;; On the mips16, we can sometimes split an add of a constant which is 727;; a 4 byte instruction into two adds which are both 2 byte 728;; instructions. There are two cases: one where we are adding a 729;; constant plus a register to another register, and one where we are 730;; simply adding a constant to a register. 731 732(define_split 733 [(set (match_operand:SI 0 "register_operand") 734 (plus:SI (match_dup 0) 735 (match_operand:SI 1 "const_int_operand")))] 736 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE 737 && REG_P (operands[0]) 738 && M16_REG_P (REGNO (operands[0])) 739 && GET_CODE (operands[1]) == CONST_INT 740 && ((INTVAL (operands[1]) > 0x7f 741 && INTVAL (operands[1]) <= 0x7f + 0x7f) 742 || (INTVAL (operands[1]) < - 0x80 743 && INTVAL (operands[1]) >= - 0x80 - 0x80))" 744 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) 745 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))] 746{ 747 HOST_WIDE_INT val = INTVAL (operands[1]); 748 749 if (val >= 0) 750 { 751 operands[1] = GEN_INT (0x7f); 752 operands[2] = GEN_INT (val - 0x7f); 753 } 754 else 755 { 756 operands[1] = GEN_INT (- 0x80); 757 operands[2] = GEN_INT (val + 0x80); 758 } 759}) 760 761(define_split 762 [(set (match_operand:SI 0 "register_operand") 763 (plus:SI (match_operand:SI 1 "register_operand") 764 (match_operand:SI 2 "const_int_operand")))] 765 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE 766 && REG_P (operands[0]) 767 && M16_REG_P (REGNO (operands[0])) 768 && REG_P (operands[1]) 769 && M16_REG_P (REGNO (operands[1])) 770 && REGNO (operands[0]) != REGNO (operands[1]) 771 && GET_CODE (operands[2]) == CONST_INT 772 && ((INTVAL (operands[2]) > 0x7 773 && INTVAL (operands[2]) <= 0x7 + 0x7f) 774 || (INTVAL (operands[2]) < - 0x8 775 && INTVAL (operands[2]) >= - 0x8 - 0x80))" 776 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2))) 777 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))] 778{ 779 HOST_WIDE_INT val = INTVAL (operands[2]); 780 781 if (val >= 0) 782 { 783 operands[2] = GEN_INT (0x7); 784 operands[3] = GEN_INT (val - 0x7); 785 } 786 else 787 { 788 operands[2] = GEN_INT (- 0x8); 789 operands[3] = GEN_INT (val + 0x8); 790 } 791}) 792 793(define_split 794 [(set (match_operand:DI 0 "register_operand") 795 (plus:DI (match_dup 0) 796 (match_operand:DI 1 "const_int_operand")))] 797 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE 798 && REG_P (operands[0]) 799 && M16_REG_P (REGNO (operands[0])) 800 && GET_CODE (operands[1]) == CONST_INT 801 && ((INTVAL (operands[1]) > 0xf 802 && INTVAL (operands[1]) <= 0xf + 0xf) 803 || (INTVAL (operands[1]) < - 0x10 804 && INTVAL (operands[1]) >= - 0x10 - 0x10))" 805 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1))) 806 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))] 807{ 808 HOST_WIDE_INT val = INTVAL (operands[1]); 809 810 if (val >= 0) 811 { 812 operands[1] = GEN_INT (0xf); 813 operands[2] = GEN_INT (val - 0xf); 814 } 815 else 816 { 817 operands[1] = GEN_INT (- 0x10); 818 operands[2] = GEN_INT (val + 0x10); 819 } 820}) 821 822(define_split 823 [(set (match_operand:DI 0 "register_operand") 824 (plus:DI (match_operand:DI 1 "register_operand") 825 (match_operand:DI 2 "const_int_operand")))] 826 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE 827 && REG_P (operands[0]) 828 && M16_REG_P (REGNO (operands[0])) 829 && REG_P (operands[1]) 830 && M16_REG_P (REGNO (operands[1])) 831 && REGNO (operands[0]) != REGNO (operands[1]) 832 && GET_CODE (operands[2]) == CONST_INT 833 && ((INTVAL (operands[2]) > 0x7 834 && INTVAL (operands[2]) <= 0x7 + 0xf) 835 || (INTVAL (operands[2]) < - 0x8 836 && INTVAL (operands[2]) >= - 0x8 - 0x10))" 837 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2))) 838 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] 839{ 840 HOST_WIDE_INT val = INTVAL (operands[2]); 841 842 if (val >= 0) 843 { 844 operands[2] = GEN_INT (0x7); 845 operands[3] = GEN_INT (val - 0x7); 846 } 847 else 848 { 849 operands[2] = GEN_INT (- 0x8); 850 operands[3] = GEN_INT (val + 0x8); 851 } 852}) 853 854(define_insn "*addsi3_extended" 855 [(set (match_operand:DI 0 "register_operand" "=d,d") 856 (sign_extend:DI 857 (plus:SI (match_operand:SI 1 "register_operand" "d,d") 858 (match_operand:SI 2 "arith_operand" "d,Q"))))] 859 "TARGET_64BIT && !TARGET_MIPS16" 860 "@ 861 addu\t%0,%1,%2 862 addiu\t%0,%1,%2" 863 [(set_attr "type" "arith") 864 (set_attr "mode" "SI")]) 865 866;; Split this insn so that the addiu splitters can have a crack at it. 867;; Use a conservative length estimate until the split. 868(define_insn_and_split "*addsi3_extended_mips16" 869 [(set (match_operand:DI 0 "register_operand" "=d,d,d") 870 (sign_extend:DI 871 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d") 872 (match_operand:SI 2 "arith_operand" "Q,O,d"))))] 873 "TARGET_64BIT && TARGET_MIPS16" 874 "#" 875 "&& reload_completed" 876 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))] 877 { operands[3] = gen_lowpart (SImode, operands[0]); } 878 [(set_attr "type" "arith") 879 (set_attr "mode" "SI") 880 (set_attr "extended_mips16" "yes")]) 881 882;; 883;; .................... 884;; 885;; SUBTRACTION 886;; 887;; .................... 888;; 889 890(define_insn "sub<mode>3" 891 [(set (match_operand:ANYF 0 "register_operand" "=f") 892 (minus:ANYF (match_operand:ANYF 1 "register_operand" "f") 893 (match_operand:ANYF 2 "register_operand" "f")))] 894 "" 895 "sub.<fmt>\t%0,%1,%2" 896 [(set_attr "type" "fadd") 897 (set_attr "mode" "<UNITMODE>")]) 898 899(define_insn "sub<mode>3" 900 [(set (match_operand:GPR 0 "register_operand" "=d") 901 (minus:GPR (match_operand:GPR 1 "register_operand" "d") 902 (match_operand:GPR 2 "register_operand" "d")))] 903 "" 904 "<d>subu\t%0,%1,%2" 905 [(set_attr "type" "arith") 906 (set_attr "mode" "<MODE>")]) 907 908(define_insn "*subsi3_extended" 909 [(set (match_operand:DI 0 "register_operand" "=d") 910 (sign_extend:DI 911 (minus:SI (match_operand:SI 1 "register_operand" "d") 912 (match_operand:SI 2 "register_operand" "d"))))] 913 "TARGET_64BIT" 914 "subu\t%0,%1,%2" 915 [(set_attr "type" "arith") 916 (set_attr "mode" "DI")]) 917 918;; 919;; .................... 920;; 921;; MULTIPLICATION 922;; 923;; .................... 924;; 925 926(define_expand "mul<mode>3" 927 [(set (match_operand:SCALARF 0 "register_operand") 928 (mult:SCALARF (match_operand:SCALARF 1 "register_operand") 929 (match_operand:SCALARF 2 "register_operand")))] 930 "" 931 "") 932 933(define_insn "*mul<mode>3" 934 [(set (match_operand:SCALARF 0 "register_operand" "=f") 935 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f") 936 (match_operand:SCALARF 2 "register_operand" "f")))] 937 "!TARGET_4300_MUL_FIX" 938 "mul.<fmt>\t%0,%1,%2" 939 [(set_attr "type" "fmul") 940 (set_attr "mode" "<MODE>")]) 941 942;; Early VR4300 silicon has a CPU bug where multiplies with certain 943;; operands may corrupt immediately following multiplies. This is a 944;; simple fix to insert NOPs. 945 946(define_insn "*mul<mode>3_r4300" 947 [(set (match_operand:SCALARF 0 "register_operand" "=f") 948 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f") 949 (match_operand:SCALARF 2 "register_operand" "f")))] 950 "TARGET_4300_MUL_FIX" 951 "mul.<fmt>\t%0,%1,%2\;nop" 952 [(set_attr "type" "fmul") 953 (set_attr "mode" "<MODE>") 954 (set_attr "length" "8")]) 955 956(define_insn "mulv2sf3" 957 [(set (match_operand:V2SF 0 "register_operand" "=f") 958 (mult:V2SF (match_operand:V2SF 1 "register_operand" "f") 959 (match_operand:V2SF 2 "register_operand" "f")))] 960 "TARGET_PAIRED_SINGLE_FLOAT" 961 "mul.ps\t%0,%1,%2" 962 [(set_attr "type" "fmul") 963 (set_attr "mode" "SF")]) 964 965;; The original R4000 has a cpu bug. If a double-word or a variable 966;; shift executes while an integer multiplication is in progress, the 967;; shift may give an incorrect result. Avoid this by keeping the mflo 968;; with the mult on the R4000. 969;; 970;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0" 971;; (also valid for MIPS R4000MC processors): 972;; 973;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to 974;; this errata description. 975;; The following code sequence causes the R4000 to incorrectly 976;; execute the Double Shift Right Arithmetic 32 (dsra32) 977;; instruction. If the dsra32 instruction is executed during an 978;; integer multiply, the dsra32 will only shift by the amount in 979;; specified in the instruction rather than the amount plus 32 980;; bits. 981;; instruction 1: mult rs,rt integer multiply 982;; instruction 2-12: dsra32 rd,rt,rs doubleword shift 983;; right arithmetic + 32 984;; Workaround: A dsra32 instruction placed after an integer 985;; multiply should not be one of the 11 instructions after the 986;; multiply instruction." 987;; 988;; and: 989;; 990;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by 991;; the following description. 992;; All extended shifts (shift by n+32) and variable shifts (32 and 993;; 64-bit versions) may produce incorrect results under the 994;; following conditions: 995;; 1) An integer multiply is currently executing 996;; 2) These types of shift instructions are executed immediately 997;; following an integer divide instruction. 998;; Workaround: 999;; 1) Make sure no integer multiply is running wihen these 1000;; instruction are executed. If this cannot be predicted at 1001;; compile time, then insert a "mfhi" to R0 instruction 1002;; immediately after the integer multiply instruction. This 1003;; will cause the integer multiply to complete before the shift 1004;; is executed. 1005;; 2) Separate integer divide and these two classes of shift 1006;; instructions by another instruction or a noop." 1007;; 1008;; These processors have PRId values of 0x00004220 and 0x00004300, 1009;; respectively. 1010 1011(define_expand "mul<mode>3" 1012 [(set (match_operand:GPR 0 "register_operand") 1013 (mult:GPR (match_operand:GPR 1 "register_operand") 1014 (match_operand:GPR 2 "register_operand")))] 1015 "" 1016{ 1017 if (GENERATE_MULT3_<MODE>) 1018 emit_insn (gen_mul<mode>3_mult3 (operands[0], operands[1], operands[2])); 1019 else if (!TARGET_FIX_R4000) 1020 emit_insn (gen_mul<mode>3_internal (operands[0], operands[1], 1021 operands[2])); 1022 else 1023 emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2])); 1024 DONE; 1025}) 1026 1027(define_insn "mulsi3_mult3" 1028 [(set (match_operand:SI 0 "register_operand" "=d,l") 1029 (mult:SI (match_operand:SI 1 "register_operand" "d,d") 1030 (match_operand:SI 2 "register_operand" "d,d"))) 1031 (clobber (match_scratch:SI 3 "=h,h")) 1032 (clobber (match_scratch:SI 4 "=l,X"))] 1033 "GENERATE_MULT3_SI" 1034{ 1035 if (which_alternative == 1) 1036 return "mult\t%1,%2"; 1037 if (TARGET_MAD 1038 || TARGET_MIPS5400 1039 || TARGET_MIPS5500 1040 || TARGET_MIPS7000 1041 || TARGET_MIPS9000 1042 || ISA_MIPS32 1043 || ISA_MIPS32R2 1044 || ISA_MIPS64) 1045 return "mul\t%0,%1,%2"; 1046 return "mult\t%0,%1,%2"; 1047} 1048 [(set_attr "type" "imul3,imul") 1049 (set_attr "mode" "SI")]) 1050 1051(define_insn "muldi3_mult3" 1052 [(set (match_operand:DI 0 "register_operand" "=d") 1053 (mult:DI (match_operand:DI 1 "register_operand" "d") 1054 (match_operand:DI 2 "register_operand" "d"))) 1055 (clobber (match_scratch:DI 3 "=h")) 1056 (clobber (match_scratch:DI 4 "=l"))] 1057 "TARGET_64BIT && GENERATE_MULT3_DI" 1058 "dmult\t%0,%1,%2" 1059 [(set_attr "type" "imul3") 1060 (set_attr "mode" "DI")]) 1061 1062;; If a register gets allocated to LO, and we spill to memory, the reload 1063;; will include a move from LO to a GPR. Merge it into the multiplication 1064;; if it can set the GPR directly. 1065;; 1066;; Operand 0: LO 1067;; Operand 1: GPR (1st multiplication operand) 1068;; Operand 2: GPR (2nd multiplication operand) 1069;; Operand 3: HI 1070;; Operand 4: GPR (destination) 1071(define_peephole2 1072 [(parallel 1073 [(set (match_operand:SI 0 "register_operand") 1074 (mult:SI (match_operand:SI 1 "register_operand") 1075 (match_operand:SI 2 "register_operand"))) 1076 (clobber (match_operand:SI 3 "register_operand")) 1077 (clobber (scratch:SI))]) 1078 (set (match_operand:SI 4 "register_operand") 1079 (unspec [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))] 1080 "GENERATE_MULT3_SI && peep2_reg_dead_p (2, operands[0])" 1081 [(parallel 1082 [(set (match_dup 4) 1083 (mult:SI (match_dup 1) 1084 (match_dup 2))) 1085 (clobber (match_dup 3)) 1086 (clobber (match_dup 0))])]) 1087 1088(define_insn "mul<mode>3_internal" 1089 [(set (match_operand:GPR 0 "register_operand" "=l") 1090 (mult:GPR (match_operand:GPR 1 "register_operand" "d") 1091 (match_operand:GPR 2 "register_operand" "d"))) 1092 (clobber (match_scratch:GPR 3 "=h"))] 1093 "!TARGET_FIX_R4000" 1094 "<d>mult\t%1,%2" 1095 [(set_attr "type" "imul") 1096 (set_attr "mode" "<MODE>")]) 1097 1098(define_insn "mul<mode>3_r4000" 1099 [(set (match_operand:GPR 0 "register_operand" "=d") 1100 (mult:GPR (match_operand:GPR 1 "register_operand" "d") 1101 (match_operand:GPR 2 "register_operand" "d"))) 1102 (clobber (match_scratch:GPR 3 "=h")) 1103 (clobber (match_scratch:GPR 4 "=l"))] 1104 "TARGET_FIX_R4000" 1105 "<d>mult\t%1,%2\;mflo\t%0" 1106 [(set_attr "type" "imul") 1107 (set_attr "mode" "<MODE>") 1108 (set_attr "length" "8")]) 1109 1110;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead 1111;; of "mult; mflo". They have the same latency, but the first form gives 1112;; us an extra cycle to compute the operands. 1113 1114;; Operand 0: LO 1115;; Operand 1: GPR (1st multiplication operand) 1116;; Operand 2: GPR (2nd multiplication operand) 1117;; Operand 3: HI 1118;; Operand 4: GPR (destination) 1119(define_peephole2 1120 [(parallel 1121 [(set (match_operand:SI 0 "register_operand") 1122 (mult:SI (match_operand:SI 1 "register_operand") 1123 (match_operand:SI 2 "register_operand"))) 1124 (clobber (match_operand:SI 3 "register_operand"))]) 1125 (set (match_operand:SI 4 "register_operand") 1126 (unspec:SI [(match_dup 0) (match_dup 3)] UNSPEC_MFHILO))] 1127 "ISA_HAS_MACC && !GENERATE_MULT3_SI" 1128 [(set (match_dup 0) 1129 (const_int 0)) 1130 (parallel 1131 [(set (match_dup 0) 1132 (plus:SI (mult:SI (match_dup 1) 1133 (match_dup 2)) 1134 (match_dup 0))) 1135 (set (match_dup 4) 1136 (plus:SI (mult:SI (match_dup 1) 1137 (match_dup 2)) 1138 (match_dup 0))) 1139 (clobber (match_dup 3))])]) 1140 1141;; Multiply-accumulate patterns 1142 1143;; For processors that can copy the output to a general register: 1144;; 1145;; The all-d alternative is needed because the combiner will find this 1146;; pattern and then register alloc/reload will move registers around to 1147;; make them fit, and we don't want to trigger unnecessary loads to LO. 1148;; 1149;; The last alternative should be made slightly less desirable, but adding 1150;; "?" to the constraint is too strong, and causes values to be loaded into 1151;; LO even when that's more costly. For now, using "*d" mostly does the 1152;; trick. 1153(define_insn "*mul_acc_si" 1154 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d") 1155 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d") 1156 (match_operand:SI 2 "register_operand" "d,d,d")) 1157 (match_operand:SI 3 "register_operand" "0,l,*d"))) 1158 (clobber (match_scratch:SI 4 "=h,h,h")) 1159 (clobber (match_scratch:SI 5 "=X,3,l")) 1160 (clobber (match_scratch:SI 6 "=X,X,&d"))] 1161 "(TARGET_MIPS3900 1162 || ISA_HAS_MADD_MSUB) 1163 && !TARGET_MIPS16" 1164{ 1165 static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" }; 1166 if (which_alternative == 2) 1167 return "#"; 1168 if (ISA_HAS_MADD_MSUB && which_alternative != 0) 1169 return "#"; 1170 return madd[which_alternative]; 1171} 1172 [(set_attr "type" "imadd,imadd,multi") 1173 (set_attr "mode" "SI") 1174 (set_attr "length" "4,4,8")]) 1175 1176;; Split the above insn if we failed to get LO allocated. 1177(define_split 1178 [(set (match_operand:SI 0 "register_operand") 1179 (plus:SI (mult:SI (match_operand:SI 1 "register_operand") 1180 (match_operand:SI 2 "register_operand")) 1181 (match_operand:SI 3 "register_operand"))) 1182 (clobber (match_scratch:SI 4)) 1183 (clobber (match_scratch:SI 5)) 1184 (clobber (match_scratch:SI 6))] 1185 "reload_completed && !TARGET_DEBUG_D_MODE 1186 && GP_REG_P (true_regnum (operands[0])) 1187 && GP_REG_P (true_regnum (operands[3]))" 1188 [(parallel [(set (match_dup 6) 1189 (mult:SI (match_dup 1) (match_dup 2))) 1190 (clobber (match_dup 4)) 1191 (clobber (match_dup 5))]) 1192 (set (match_dup 0) (plus:SI (match_dup 6) (match_dup 3)))] 1193 "") 1194 1195;; Splitter to copy result of MADD to a general register 1196(define_split 1197 [(set (match_operand:SI 0 "register_operand") 1198 (plus:SI (mult:SI (match_operand:SI 1 "register_operand") 1199 (match_operand:SI 2 "register_operand")) 1200 (match_operand:SI 3 "register_operand"))) 1201 (clobber (match_scratch:SI 4)) 1202 (clobber (match_scratch:SI 5)) 1203 (clobber (match_scratch:SI 6))] 1204 "reload_completed && !TARGET_DEBUG_D_MODE 1205 && GP_REG_P (true_regnum (operands[0])) 1206 && true_regnum (operands[3]) == LO_REGNUM" 1207 [(parallel [(set (match_dup 3) 1208 (plus:SI (mult:SI (match_dup 1) (match_dup 2)) 1209 (match_dup 3))) 1210 (clobber (match_dup 4)) 1211 (clobber (match_dup 5)) 1212 (clobber (match_dup 6))]) 1213 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))] 1214 "") 1215 1216(define_insn "*macc" 1217 [(set (match_operand:SI 0 "register_operand" "=l,d") 1218 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d") 1219 (match_operand:SI 2 "register_operand" "d,d")) 1220 (match_operand:SI 3 "register_operand" "0,l"))) 1221 (clobber (match_scratch:SI 4 "=h,h")) 1222 (clobber (match_scratch:SI 5 "=X,3"))] 1223 "ISA_HAS_MACC" 1224{ 1225 if (which_alternative == 1) 1226 return "macc\t%0,%1,%2"; 1227 else if (TARGET_MIPS5500) 1228 return "madd\t%1,%2"; 1229 else 1230 /* The VR4130 assumes that there is a two-cycle latency between a macc 1231 that "writes" to $0 and an instruction that reads from it. We avoid 1232 this by assigning to $1 instead. */ 1233 return "%[macc\t%@,%1,%2%]"; 1234} 1235 [(set_attr "type" "imadd") 1236 (set_attr "mode" "SI")]) 1237 1238(define_insn "*msac" 1239 [(set (match_operand:SI 0 "register_operand" "=l,d") 1240 (minus:SI (match_operand:SI 1 "register_operand" "0,l") 1241 (mult:SI (match_operand:SI 2 "register_operand" "d,d") 1242 (match_operand:SI 3 "register_operand" "d,d")))) 1243 (clobber (match_scratch:SI 4 "=h,h")) 1244 (clobber (match_scratch:SI 5 "=X,1"))] 1245 "ISA_HAS_MSAC" 1246{ 1247 if (which_alternative == 1) 1248 return "msac\t%0,%2,%3"; 1249 else if (TARGET_MIPS5500) 1250 return "msub\t%2,%3"; 1251 else 1252 return "msac\t$0,%2,%3"; 1253} 1254 [(set_attr "type" "imadd") 1255 (set_attr "mode" "SI")]) 1256 1257;; An msac-like instruction implemented using negation and a macc. 1258(define_insn_and_split "*msac_using_macc" 1259 [(set (match_operand:SI 0 "register_operand" "=l,d") 1260 (minus:SI (match_operand:SI 1 "register_operand" "0,l") 1261 (mult:SI (match_operand:SI 2 "register_operand" "d,d") 1262 (match_operand:SI 3 "register_operand" "d,d")))) 1263 (clobber (match_scratch:SI 4 "=h,h")) 1264 (clobber (match_scratch:SI 5 "=X,1")) 1265 (clobber (match_scratch:SI 6 "=d,d"))] 1266 "ISA_HAS_MACC && !ISA_HAS_MSAC" 1267 "#" 1268 "&& reload_completed" 1269 [(set (match_dup 6) 1270 (neg:SI (match_dup 3))) 1271 (parallel 1272 [(set (match_dup 0) 1273 (plus:SI (mult:SI (match_dup 2) 1274 (match_dup 6)) 1275 (match_dup 1))) 1276 (clobber (match_dup 4)) 1277 (clobber (match_dup 5))])] 1278 "" 1279 [(set_attr "type" "imadd") 1280 (set_attr "length" "8")]) 1281 1282;; Patterns generated by the define_peephole2 below. 1283 1284(define_insn "*macc2" 1285 [(set (match_operand:SI 0 "register_operand" "=l") 1286 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d") 1287 (match_operand:SI 2 "register_operand" "d")) 1288 (match_dup 0))) 1289 (set (match_operand:SI 3 "register_operand" "=d") 1290 (plus:SI (mult:SI (match_dup 1) 1291 (match_dup 2)) 1292 (match_dup 0))) 1293 (clobber (match_scratch:SI 4 "=h"))] 1294 "ISA_HAS_MACC && reload_completed" 1295 "macc\t%3,%1,%2" 1296 [(set_attr "type" "imadd") 1297 (set_attr "mode" "SI")]) 1298 1299(define_insn "*msac2" 1300 [(set (match_operand:SI 0 "register_operand" "=l") 1301 (minus:SI (match_dup 0) 1302 (mult:SI (match_operand:SI 1 "register_operand" "d") 1303 (match_operand:SI 2 "register_operand" "d")))) 1304 (set (match_operand:SI 3 "register_operand" "=d") 1305 (minus:SI (match_dup 0) 1306 (mult:SI (match_dup 1) 1307 (match_dup 2)))) 1308 (clobber (match_scratch:SI 4 "=h"))] 1309 "ISA_HAS_MSAC && reload_completed" 1310 "msac\t%3,%1,%2" 1311 [(set_attr "type" "imadd") 1312 (set_attr "mode" "SI")]) 1313 1314;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2> 1315;; Similarly msac. 1316;; 1317;; Operand 0: LO 1318;; Operand 1: macc/msac 1319;; Operand 2: HI 1320;; Operand 3: GPR (destination) 1321(define_peephole2 1322 [(parallel 1323 [(set (match_operand:SI 0 "register_operand") 1324 (match_operand:SI 1 "macc_msac_operand")) 1325 (clobber (match_operand:SI 2 "register_operand")) 1326 (clobber (scratch:SI))]) 1327 (set (match_operand:SI 3 "register_operand") 1328 (unspec:SI [(match_dup 0) (match_dup 2)] UNSPEC_MFHILO))] 1329 "" 1330 [(parallel [(set (match_dup 0) 1331 (match_dup 1)) 1332 (set (match_dup 3) 1333 (match_dup 1)) 1334 (clobber (match_dup 2))])] 1335 "") 1336 1337;; When we have a three-address multiplication instruction, it should 1338;; be faster to do a separate multiply and add, rather than moving 1339;; something into LO in order to use a macc instruction. 1340;; 1341;; This peephole needs a scratch register to cater for the case when one 1342;; of the multiplication operands is the same as the destination. 1343;; 1344;; Operand 0: GPR (scratch) 1345;; Operand 1: LO 1346;; Operand 2: GPR (addend) 1347;; Operand 3: GPR (destination) 1348;; Operand 4: macc/msac 1349;; Operand 5: HI 1350;; Operand 6: new multiplication 1351;; Operand 7: new addition/subtraction 1352(define_peephole2 1353 [(match_scratch:SI 0 "d") 1354 (set (match_operand:SI 1 "register_operand") 1355 (match_operand:SI 2 "register_operand")) 1356 (match_dup 0) 1357 (parallel 1358 [(set (match_operand:SI 3 "register_operand") 1359 (match_operand:SI 4 "macc_msac_operand")) 1360 (clobber (match_operand:SI 5 "register_operand")) 1361 (clobber (match_dup 1))])] 1362 "GENERATE_MULT3_SI 1363 && true_regnum (operands[1]) == LO_REGNUM 1364 && peep2_reg_dead_p (2, operands[1]) 1365 && GP_REG_P (true_regnum (operands[3]))" 1366 [(parallel [(set (match_dup 0) 1367 (match_dup 6)) 1368 (clobber (match_dup 5)) 1369 (clobber (match_dup 1))]) 1370 (set (match_dup 3) 1371 (match_dup 7))] 1372{ 1373 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1); 1374 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode, 1375 operands[2], operands[0]); 1376}) 1377 1378;; Same as above, except LO is the initial target of the macc. 1379;; 1380;; Operand 0: GPR (scratch) 1381;; Operand 1: LO 1382;; Operand 2: GPR (addend) 1383;; Operand 3: macc/msac 1384;; Operand 4: HI 1385;; Operand 5: GPR (destination) 1386;; Operand 6: new multiplication 1387;; Operand 7: new addition/subtraction 1388(define_peephole2 1389 [(match_scratch:SI 0 "d") 1390 (set (match_operand:SI 1 "register_operand") 1391 (match_operand:SI 2 "register_operand")) 1392 (match_dup 0) 1393 (parallel 1394 [(set (match_dup 1) 1395 (match_operand:SI 3 "macc_msac_operand")) 1396 (clobber (match_operand:SI 4 "register_operand")) 1397 (clobber (scratch:SI))]) 1398 (match_dup 0) 1399 (set (match_operand:SI 5 "register_operand") 1400 (unspec:SI [(match_dup 1) (match_dup 4)] UNSPEC_MFHILO))] 1401 "GENERATE_MULT3_SI && peep2_reg_dead_p (3, operands[1])" 1402 [(parallel [(set (match_dup 0) 1403 (match_dup 6)) 1404 (clobber (match_dup 4)) 1405 (clobber (match_dup 1))]) 1406 (set (match_dup 5) 1407 (match_dup 7))] 1408{ 1409 operands[6] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1); 1410 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode, 1411 operands[2], operands[0]); 1412}) 1413 1414(define_insn "*mul_sub_si" 1415 [(set (match_operand:SI 0 "register_operand" "=l,*d,*d") 1416 (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d") 1417 (mult:SI (match_operand:SI 2 "register_operand" "d,d,d") 1418 (match_operand:SI 3 "register_operand" "d,d,d")))) 1419 (clobber (match_scratch:SI 4 "=h,h,h")) 1420 (clobber (match_scratch:SI 5 "=X,1,l")) 1421 (clobber (match_scratch:SI 6 "=X,X,&d"))] 1422 "ISA_HAS_MADD_MSUB" 1423 "@ 1424 msub\t%2,%3 1425 # 1426 #" 1427 [(set_attr "type" "imadd,multi,multi") 1428 (set_attr "mode" "SI") 1429 (set_attr "length" "4,8,8")]) 1430 1431;; Split the above insn if we failed to get LO allocated. 1432(define_split 1433 [(set (match_operand:SI 0 "register_operand") 1434 (minus:SI (match_operand:SI 1 "register_operand") 1435 (mult:SI (match_operand:SI 2 "register_operand") 1436 (match_operand:SI 3 "register_operand")))) 1437 (clobber (match_scratch:SI 4)) 1438 (clobber (match_scratch:SI 5)) 1439 (clobber (match_scratch:SI 6))] 1440 "reload_completed && !TARGET_DEBUG_D_MODE 1441 && GP_REG_P (true_regnum (operands[0])) 1442 && GP_REG_P (true_regnum (operands[1]))" 1443 [(parallel [(set (match_dup 6) 1444 (mult:SI (match_dup 2) (match_dup 3))) 1445 (clobber (match_dup 4)) 1446 (clobber (match_dup 5))]) 1447 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 6)))] 1448 "") 1449 1450;; Splitter to copy result of MSUB to a general register 1451(define_split 1452 [(set (match_operand:SI 0 "register_operand") 1453 (minus:SI (match_operand:SI 1 "register_operand") 1454 (mult:SI (match_operand:SI 2 "register_operand") 1455 (match_operand:SI 3 "register_operand")))) 1456 (clobber (match_scratch:SI 4)) 1457 (clobber (match_scratch:SI 5)) 1458 (clobber (match_scratch:SI 6))] 1459 "reload_completed && !TARGET_DEBUG_D_MODE 1460 && GP_REG_P (true_regnum (operands[0])) 1461 && true_regnum (operands[1]) == LO_REGNUM" 1462 [(parallel [(set (match_dup 1) 1463 (minus:SI (match_dup 1) 1464 (mult:SI (match_dup 2) (match_dup 3)))) 1465 (clobber (match_dup 4)) 1466 (clobber (match_dup 5)) 1467 (clobber (match_dup 6))]) 1468 (set (match_dup 0) (unspec:SI [(match_dup 5) (match_dup 4)] UNSPEC_MFHILO))] 1469 "") 1470 1471(define_insn "*muls" 1472 [(set (match_operand:SI 0 "register_operand" "=l,d") 1473 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d") 1474 (match_operand:SI 2 "register_operand" "d,d")))) 1475 (clobber (match_scratch:SI 3 "=h,h")) 1476 (clobber (match_scratch:SI 4 "=X,l"))] 1477 "ISA_HAS_MULS" 1478 "@ 1479 muls\t$0,%1,%2 1480 muls\t%0,%1,%2" 1481 [(set_attr "type" "imul,imul3") 1482 (set_attr "mode" "SI")]) 1483 1484;; ??? We could define a mulditi3 pattern when TARGET_64BIT. 1485 1486(define_expand "<u>mulsidi3" 1487 [(parallel 1488 [(set (match_operand:DI 0 "register_operand") 1489 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand")) 1490 (any_extend:DI (match_operand:SI 2 "register_operand")))) 1491 (clobber (scratch:DI)) 1492 (clobber (scratch:DI)) 1493 (clobber (scratch:DI))])] 1494 "!TARGET_64BIT || !TARGET_FIX_R4000" 1495{ 1496 if (!TARGET_64BIT) 1497 { 1498 if (!TARGET_FIX_R4000) 1499 emit_insn (gen_<u>mulsidi3_32bit_internal (operands[0], operands[1], 1500 operands[2])); 1501 else 1502 emit_insn (gen_<u>mulsidi3_32bit_r4000 (operands[0], operands[1], 1503 operands[2])); 1504 DONE; 1505 } 1506}) 1507 1508(define_insn "<u>mulsidi3_32bit_internal" 1509 [(set (match_operand:DI 0 "register_operand" "=x") 1510 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) 1511 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))] 1512 "!TARGET_64BIT && !TARGET_FIX_R4000" 1513 "mult<u>\t%1,%2" 1514 [(set_attr "type" "imul") 1515 (set_attr "mode" "SI")]) 1516 1517(define_insn "<u>mulsidi3_32bit_r4000" 1518 [(set (match_operand:DI 0 "register_operand" "=d") 1519 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) 1520 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))) 1521 (clobber (match_scratch:DI 3 "=x"))] 1522 "!TARGET_64BIT && TARGET_FIX_R4000" 1523 "mult<u>\t%1,%2\;mflo\t%L0;mfhi\t%M0" 1524 [(set_attr "type" "imul") 1525 (set_attr "mode" "SI") 1526 (set_attr "length" "12")]) 1527 1528(define_insn_and_split "*<u>mulsidi3_64bit" 1529 [(set (match_operand:DI 0 "register_operand" "=d") 1530 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) 1531 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))) 1532 (clobber (match_scratch:DI 3 "=l")) 1533 (clobber (match_scratch:DI 4 "=h")) 1534 (clobber (match_scratch:DI 5 "=d"))] 1535 "TARGET_64BIT && !TARGET_FIX_R4000" 1536 "#" 1537 "&& reload_completed" 1538 [(parallel 1539 [(set (match_dup 3) 1540 (sign_extend:DI 1541 (mult:SI (match_dup 1) 1542 (match_dup 2)))) 1543 (set (match_dup 4) 1544 (ashiftrt:DI 1545 (mult:DI (any_extend:DI (match_dup 1)) 1546 (any_extend:DI (match_dup 2))) 1547 (const_int 32)))]) 1548 1549 ;; OP5 <- LO, OP0 <- HI 1550 (set (match_dup 5) (unspec:DI [(match_dup 3) (match_dup 4)] UNSPEC_MFHILO)) 1551 (set (match_dup 0) (unspec:DI [(match_dup 4) (match_dup 3)] UNSPEC_MFHILO)) 1552 1553 ;; Zero-extend OP5. 1554 (set (match_dup 5) 1555 (ashift:DI (match_dup 5) 1556 (const_int 32))) 1557 (set (match_dup 5) 1558 (lshiftrt:DI (match_dup 5) 1559 (const_int 32))) 1560 1561 ;; Shift OP0 into place. 1562 (set (match_dup 0) 1563 (ashift:DI (match_dup 0) 1564 (const_int 32))) 1565 1566 ;; OR the two halves together 1567 (set (match_dup 0) 1568 (ior:DI (match_dup 0) 1569 (match_dup 5)))] 1570 "" 1571 [(set_attr "type" "imul") 1572 (set_attr "mode" "SI") 1573 (set_attr "length" "24")]) 1574 1575(define_insn "*<u>mulsidi3_64bit_parts" 1576 [(set (match_operand:DI 0 "register_operand" "=l") 1577 (sign_extend:DI 1578 (mult:SI (match_operand:SI 2 "register_operand" "d") 1579 (match_operand:SI 3 "register_operand" "d")))) 1580 (set (match_operand:DI 1 "register_operand" "=h") 1581 (ashiftrt:DI 1582 (mult:DI (any_extend:DI (match_dup 2)) 1583 (any_extend:DI (match_dup 3))) 1584 (const_int 32)))] 1585 "TARGET_64BIT && !TARGET_FIX_R4000" 1586 "mult<u>\t%2,%3" 1587 [(set_attr "type" "imul") 1588 (set_attr "mode" "SI")]) 1589 1590;; Widening multiply with negation. 1591(define_insn "*muls<u>_di" 1592 [(set (match_operand:DI 0 "register_operand" "=x") 1593 (neg:DI 1594 (mult:DI 1595 (any_extend:DI (match_operand:SI 1 "register_operand" "d")) 1596 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))] 1597 "!TARGET_64BIT && ISA_HAS_MULS" 1598 "muls<u>\t$0,%1,%2" 1599 [(set_attr "type" "imul") 1600 (set_attr "mode" "SI")]) 1601 1602(define_insn "*msac<u>_di" 1603 [(set (match_operand:DI 0 "register_operand" "=x") 1604 (minus:DI 1605 (match_operand:DI 3 "register_operand" "0") 1606 (mult:DI 1607 (any_extend:DI (match_operand:SI 1 "register_operand" "d")) 1608 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))] 1609 "!TARGET_64BIT && ISA_HAS_MSAC" 1610{ 1611 if (TARGET_MIPS5500) 1612 return "msub<u>\t%1,%2"; 1613 else 1614 return "msac<u>\t$0,%1,%2"; 1615} 1616 [(set_attr "type" "imadd") 1617 (set_attr "mode" "SI")]) 1618 1619;; _highpart patterns 1620 1621(define_expand "<su>mulsi3_highpart" 1622 [(set (match_operand:SI 0 "register_operand") 1623 (truncate:SI 1624 (lshiftrt:DI 1625 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand")) 1626 (any_extend:DI (match_operand:SI 2 "register_operand"))) 1627 (const_int 32))))] 1628 "ISA_HAS_MULHI || !TARGET_FIX_R4000" 1629{ 1630 if (ISA_HAS_MULHI) 1631 emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0], 1632 operands[1], 1633 operands[2])); 1634 else 1635 emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1], 1636 operands[2])); 1637 DONE; 1638}) 1639 1640(define_insn "<su>mulsi3_highpart_internal" 1641 [(set (match_operand:SI 0 "register_operand" "=h") 1642 (truncate:SI 1643 (lshiftrt:DI 1644 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) 1645 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))) 1646 (const_int 32)))) 1647 (clobber (match_scratch:SI 3 "=l"))] 1648 "!ISA_HAS_MULHI && !TARGET_FIX_R4000" 1649 "mult<u>\t%1,%2" 1650 [(set_attr "type" "imul") 1651 (set_attr "mode" "SI")]) 1652 1653(define_insn "<su>mulsi3_highpart_mulhi_internal" 1654 [(set (match_operand:SI 0 "register_operand" "=h,d") 1655 (truncate:SI 1656 (lshiftrt:DI 1657 (mult:DI 1658 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d")) 1659 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d"))) 1660 (const_int 32)))) 1661 (clobber (match_scratch:SI 3 "=l,l")) 1662 (clobber (match_scratch:SI 4 "=X,h"))] 1663 "ISA_HAS_MULHI" 1664 "@ 1665 mult<u>\t%1,%2 1666 mulhi<u>\t%0,%1,%2" 1667 [(set_attr "type" "imul,imul3") 1668 (set_attr "mode" "SI")]) 1669 1670(define_insn "*<su>mulsi3_highpart_neg_mulhi_internal" 1671 [(set (match_operand:SI 0 "register_operand" "=h,d") 1672 (truncate:SI 1673 (lshiftrt:DI 1674 (neg:DI 1675 (mult:DI 1676 (any_extend:DI (match_operand:SI 1 "register_operand" "d,d")) 1677 (any_extend:DI (match_operand:SI 2 "register_operand" "d,d")))) 1678 (const_int 32)))) 1679 (clobber (match_scratch:SI 3 "=l,l")) 1680 (clobber (match_scratch:SI 4 "=X,h"))] 1681 "ISA_HAS_MULHI" 1682 "@ 1683 mulshi<u>\t%.,%1,%2 1684 mulshi<u>\t%0,%1,%2" 1685 [(set_attr "type" "imul,imul3") 1686 (set_attr "mode" "SI")]) 1687 1688;; Disable unsigned multiplication for -mfix-vr4120. This is for VR4120 1689;; errata MD(0), which says that dmultu does not always produce the 1690;; correct result. 1691(define_insn "<su>muldi3_highpart" 1692 [(set (match_operand:DI 0 "register_operand" "=h") 1693 (truncate:DI 1694 (lshiftrt:TI 1695 (mult:TI 1696 (any_extend:TI (match_operand:DI 1 "register_operand" "d")) 1697 (any_extend:TI (match_operand:DI 2 "register_operand" "d"))) 1698 (const_int 64)))) 1699 (clobber (match_scratch:DI 3 "=l"))] 1700 "TARGET_64BIT && !TARGET_FIX_R4000 1701 && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)" 1702 "dmult<u>\t%1,%2" 1703 [(set_attr "type" "imul") 1704 (set_attr "mode" "DI")]) 1705 1706;; The R4650 supports a 32 bit multiply/ 64 bit accumulate 1707;; instruction. The HI/LO registers are used as a 64 bit accumulator. 1708 1709(define_insn "madsi" 1710 [(set (match_operand:SI 0 "register_operand" "+l") 1711 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d") 1712 (match_operand:SI 2 "register_operand" "d")) 1713 (match_dup 0))) 1714 (clobber (match_scratch:SI 3 "=h"))] 1715 "TARGET_MAD" 1716 "mad\t%1,%2" 1717 [(set_attr "type" "imadd") 1718 (set_attr "mode" "SI")]) 1719 1720(define_insn "*<su>mul_acc_di" 1721 [(set (match_operand:DI 0 "register_operand" "=x") 1722 (plus:DI 1723 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) 1724 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))) 1725 (match_operand:DI 3 "register_operand" "0")))] 1726 "(TARGET_MAD || ISA_HAS_MACC) 1727 && !TARGET_64BIT" 1728{ 1729 if (TARGET_MAD) 1730 return "mad<u>\t%1,%2"; 1731 else if (TARGET_MIPS5500) 1732 return "madd<u>\t%1,%2"; 1733 else 1734 /* See comment in *macc. */ 1735 return "%[macc<u>\t%@,%1,%2%]"; 1736} 1737 [(set_attr "type" "imadd") 1738 (set_attr "mode" "SI")]) 1739 1740;; Floating point multiply accumulate instructions. 1741 1742(define_insn "*madd<mode>" 1743 [(set (match_operand:ANYF 0 "register_operand" "=f") 1744 (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") 1745 (match_operand:ANYF 2 "register_operand" "f")) 1746 (match_operand:ANYF 3 "register_operand" "f")))] 1747 "ISA_HAS_FP4 && TARGET_FUSED_MADD" 1748 "madd.<fmt>\t%0,%3,%1,%2" 1749 [(set_attr "type" "fmadd") 1750 (set_attr "mode" "<UNITMODE>")]) 1751 1752(define_insn "*msub<mode>" 1753 [(set (match_operand:ANYF 0 "register_operand" "=f") 1754 (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") 1755 (match_operand:ANYF 2 "register_operand" "f")) 1756 (match_operand:ANYF 3 "register_operand" "f")))] 1757 "ISA_HAS_FP4 && TARGET_FUSED_MADD" 1758 "msub.<fmt>\t%0,%3,%1,%2" 1759 [(set_attr "type" "fmadd") 1760 (set_attr "mode" "<UNITMODE>")]) 1761 1762(define_insn "*nmadd<mode>" 1763 [(set (match_operand:ANYF 0 "register_operand" "=f") 1764 (neg:ANYF (plus:ANYF 1765 (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") 1766 (match_operand:ANYF 2 "register_operand" "f")) 1767 (match_operand:ANYF 3 "register_operand" "f"))))] 1768 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD 1769 && HONOR_SIGNED_ZEROS (<MODE>mode) 1770 && !HONOR_NANS (<MODE>mode)" 1771 "nmadd.<fmt>\t%0,%3,%1,%2" 1772 [(set_attr "type" "fmadd") 1773 (set_attr "mode" "<UNITMODE>")]) 1774 1775(define_insn "*nmadd<mode>_fastmath" 1776 [(set (match_operand:ANYF 0 "register_operand" "=f") 1777 (minus:ANYF 1778 (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) 1779 (match_operand:ANYF 2 "register_operand" "f")) 1780 (match_operand:ANYF 3 "register_operand" "f")))] 1781 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD 1782 && !HONOR_SIGNED_ZEROS (<MODE>mode) 1783 && !HONOR_NANS (<MODE>mode)" 1784 "nmadd.<fmt>\t%0,%3,%1,%2" 1785 [(set_attr "type" "fmadd") 1786 (set_attr "mode" "<UNITMODE>")]) 1787 1788(define_insn "*nmsub<mode>" 1789 [(set (match_operand:ANYF 0 "register_operand" "=f") 1790 (neg:ANYF (minus:ANYF 1791 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") 1792 (match_operand:ANYF 3 "register_operand" "f")) 1793 (match_operand:ANYF 1 "register_operand" "f"))))] 1794 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD 1795 && HONOR_SIGNED_ZEROS (<MODE>mode) 1796 && !HONOR_NANS (<MODE>mode)" 1797 "nmsub.<fmt>\t%0,%1,%2,%3" 1798 [(set_attr "type" "fmadd") 1799 (set_attr "mode" "<UNITMODE>")]) 1800 1801(define_insn "*nmsub<mode>_fastmath" 1802 [(set (match_operand:ANYF 0 "register_operand" "=f") 1803 (minus:ANYF 1804 (match_operand:ANYF 1 "register_operand" "f") 1805 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") 1806 (match_operand:ANYF 3 "register_operand" "f"))))] 1807 "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD 1808 && !HONOR_SIGNED_ZEROS (<MODE>mode) 1809 && !HONOR_NANS (<MODE>mode)" 1810 "nmsub.<fmt>\t%0,%1,%2,%3" 1811 [(set_attr "type" "fmadd") 1812 (set_attr "mode" "<UNITMODE>")]) 1813 1814;; 1815;; .................... 1816;; 1817;; DIVISION and REMAINDER 1818;; 1819;; .................... 1820;; 1821 1822(define_expand "div<mode>3" 1823 [(set (match_operand:ANYF 0 "register_operand") 1824 (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand") 1825 (match_operand:ANYF 2 "register_operand")))] 1826 "<divide_condition>" 1827{ 1828 if (const_1_operand (operands[1], <MODE>mode)) 1829 if (!(ISA_HAS_FP4 && flag_unsafe_math_optimizations)) 1830 operands[1] = force_reg (<MODE>mode, operands[1]); 1831}) 1832 1833;; These patterns work around the early SB-1 rev2 core "F1" erratum: 1834;; 1835;; If an mfc1 or dmfc1 happens to access the floating point register 1836;; file at the same time a long latency operation (div, sqrt, recip, 1837;; sqrt) iterates an intermediate result back through the floating 1838;; point register file bypass, then instead returning the correct 1839;; register value the mfc1 or dmfc1 operation returns the intermediate 1840;; result of the long latency operation. 1841;; 1842;; The workaround is to insert an unconditional 'mov' from/to the 1843;; long latency op destination register. 1844 1845(define_insn "*div<mode>3" 1846 [(set (match_operand:ANYF 0 "register_operand" "=f") 1847 (div:ANYF (match_operand:ANYF 1 "register_operand" "f") 1848 (match_operand:ANYF 2 "register_operand" "f")))] 1849 "<divide_condition>" 1850{ 1851 if (TARGET_FIX_SB1) 1852 return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0"; 1853 else 1854 return "div.<fmt>\t%0,%1,%2"; 1855} 1856 [(set_attr "type" "fdiv") 1857 (set_attr "mode" "<UNITMODE>") 1858 (set (attr "length") 1859 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) 1860 (const_int 8) 1861 (const_int 4)))]) 1862 1863(define_insn "*recip<mode>3" 1864 [(set (match_operand:ANYF 0 "register_operand" "=f") 1865 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") 1866 (match_operand:ANYF 2 "register_operand" "f")))] 1867 "<recip_condition> && flag_unsafe_math_optimizations" 1868{ 1869 if (TARGET_FIX_SB1) 1870 return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0"; 1871 else 1872 return "recip.<fmt>\t%0,%2"; 1873} 1874 [(set_attr "type" "frdiv") 1875 (set_attr "mode" "<UNITMODE>") 1876 (set (attr "length") 1877 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) 1878 (const_int 8) 1879 (const_int 4)))]) 1880 1881;; VR4120 errata MD(A1): signed division instructions do not work correctly 1882;; with negative operands. We use special libgcc functions instead. 1883(define_insn "divmod<mode>4" 1884 [(set (match_operand:GPR 0 "register_operand" "=l") 1885 (div:GPR (match_operand:GPR 1 "register_operand" "d") 1886 (match_operand:GPR 2 "register_operand" "d"))) 1887 (set (match_operand:GPR 3 "register_operand" "=h") 1888 (mod:GPR (match_dup 1) 1889 (match_dup 2)))] 1890 "!TARGET_FIX_VR4120" 1891 { return mips_output_division ("<d>div\t$0,%1,%2", operands); } 1892 [(set_attr "type" "idiv") 1893 (set_attr "mode" "<MODE>")]) 1894 1895(define_insn "udivmod<mode>4" 1896 [(set (match_operand:GPR 0 "register_operand" "=l") 1897 (udiv:GPR (match_operand:GPR 1 "register_operand" "d") 1898 (match_operand:GPR 2 "register_operand" "d"))) 1899 (set (match_operand:GPR 3 "register_operand" "=h") 1900 (umod:GPR (match_dup 1) 1901 (match_dup 2)))] 1902 "" 1903 { return mips_output_division ("<d>divu\t$0,%1,%2", operands); } 1904 [(set_attr "type" "idiv") 1905 (set_attr "mode" "<MODE>")]) 1906 1907;; 1908;; .................... 1909;; 1910;; SQUARE ROOT 1911;; 1912;; .................... 1913 1914;; These patterns work around the early SB-1 rev2 core "F1" erratum (see 1915;; "*div[sd]f3" comment for details). 1916 1917(define_insn "sqrt<mode>2" 1918 [(set (match_operand:ANYF 0 "register_operand" "=f") 1919 (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))] 1920 "<sqrt_condition>" 1921{ 1922 if (TARGET_FIX_SB1) 1923 return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0"; 1924 else 1925 return "sqrt.<fmt>\t%0,%1"; 1926} 1927 [(set_attr "type" "fsqrt") 1928 (set_attr "mode" "<UNITMODE>") 1929 (set (attr "length") 1930 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) 1931 (const_int 8) 1932 (const_int 4)))]) 1933 1934(define_insn "*rsqrt<mode>a" 1935 [(set (match_operand:ANYF 0 "register_operand" "=f") 1936 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") 1937 (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))] 1938 "<recip_condition> && flag_unsafe_math_optimizations" 1939{ 1940 if (TARGET_FIX_SB1) 1941 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0"; 1942 else 1943 return "rsqrt.<fmt>\t%0,%2"; 1944} 1945 [(set_attr "type" "frsqrt") 1946 (set_attr "mode" "<UNITMODE>") 1947 (set (attr "length") 1948 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) 1949 (const_int 8) 1950 (const_int 4)))]) 1951 1952(define_insn "*rsqrt<mode>b" 1953 [(set (match_operand:ANYF 0 "register_operand" "=f") 1954 (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") 1955 (match_operand:ANYF 2 "register_operand" "f"))))] 1956 "<recip_condition> && flag_unsafe_math_optimizations" 1957{ 1958 if (TARGET_FIX_SB1) 1959 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0"; 1960 else 1961 return "rsqrt.<fmt>\t%0,%2"; 1962} 1963 [(set_attr "type" "frsqrt") 1964 (set_attr "mode" "<UNITMODE>") 1965 (set (attr "length") 1966 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) 1967 (const_int 8) 1968 (const_int 4)))]) 1969 1970;; 1971;; .................... 1972;; 1973;; ABSOLUTE VALUE 1974;; 1975;; .................... 1976 1977;; Do not use the integer abs macro instruction, since that signals an 1978;; exception on -2147483648 (sigh). 1979 1980;; abs.fmt is an arithmetic instruction and treats all NaN inputs as 1981;; invalid; it does not clear their sign bits. We therefore can't use 1982;; abs.fmt if the signs of NaNs matter. 1983 1984(define_insn "abs<mode>2" 1985 [(set (match_operand:ANYF 0 "register_operand" "=f") 1986 (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))] 1987 "!HONOR_NANS (<MODE>mode)" 1988 "abs.<fmt>\t%0,%1" 1989 [(set_attr "type" "fabs") 1990 (set_attr "mode" "<UNITMODE>")]) 1991 1992;; 1993;; ................... 1994;; 1995;; Count leading zeroes. 1996;; 1997;; ................... 1998;; 1999 2000(define_insn "clz<mode>2" 2001 [(set (match_operand:GPR 0 "register_operand" "=d") 2002 (clz:GPR (match_operand:GPR 1 "register_operand" "d")))] 2003 "ISA_HAS_CLZ_CLO" 2004 "<d>clz\t%0,%1" 2005 [(set_attr "type" "clz") 2006 (set_attr "mode" "<MODE>")]) 2007 2008;; 2009;; .................... 2010;; 2011;; NEGATION and ONE'S COMPLEMENT 2012;; 2013;; .................... 2014 2015(define_insn "negsi2" 2016 [(set (match_operand:SI 0 "register_operand" "=d") 2017 (neg:SI (match_operand:SI 1 "register_operand" "d")))] 2018 "" 2019{ 2020 if (TARGET_MIPS16) 2021 return "neg\t%0,%1"; 2022 else 2023 return "subu\t%0,%.,%1"; 2024} 2025 [(set_attr "type" "arith") 2026 (set_attr "mode" "SI")]) 2027 2028(define_insn "negdi2" 2029 [(set (match_operand:DI 0 "register_operand" "=d") 2030 (neg:DI (match_operand:DI 1 "register_operand" "d")))] 2031 "TARGET_64BIT && !TARGET_MIPS16" 2032 "dsubu\t%0,%.,%1" 2033 [(set_attr "type" "arith") 2034 (set_attr "mode" "DI")]) 2035 2036;; neg.fmt is an arithmetic instruction and treats all NaN inputs as 2037;; invalid; it does not flip their sign bit. We therefore can't use 2038;; neg.fmt if the signs of NaNs matter. 2039 2040(define_insn "neg<mode>2" 2041 [(set (match_operand:ANYF 0 "register_operand" "=f") 2042 (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))] 2043 "!HONOR_NANS (<MODE>mode)" 2044 "neg.<fmt>\t%0,%1" 2045 [(set_attr "type" "fneg") 2046 (set_attr "mode" "<UNITMODE>")]) 2047 2048(define_insn "one_cmpl<mode>2" 2049 [(set (match_operand:GPR 0 "register_operand" "=d") 2050 (not:GPR (match_operand:GPR 1 "register_operand" "d")))] 2051 "" 2052{ 2053 if (TARGET_MIPS16) 2054 return "not\t%0,%1"; 2055 else 2056 return "nor\t%0,%.,%1"; 2057} 2058 [(set_attr "type" "arith") 2059 (set_attr "mode" "<MODE>")]) 2060 2061;; 2062;; .................... 2063;; 2064;; LOGICAL 2065;; 2066;; .................... 2067;; 2068 2069;; Many of these instructions use trivial define_expands, because we 2070;; want to use a different set of constraints when TARGET_MIPS16. 2071 2072(define_expand "and<mode>3" 2073 [(set (match_operand:GPR 0 "register_operand") 2074 (and:GPR (match_operand:GPR 1 "register_operand") 2075 (match_operand:GPR 2 "uns_arith_operand")))] 2076 "" 2077{ 2078 if (TARGET_MIPS16) 2079 operands[2] = force_reg (<MODE>mode, operands[2]); 2080}) 2081 2082(define_insn "*and<mode>3" 2083 [(set (match_operand:GPR 0 "register_operand" "=d,d") 2084 (and:GPR (match_operand:GPR 1 "register_operand" "%d,d") 2085 (match_operand:GPR 2 "uns_arith_operand" "d,K")))] 2086 "!TARGET_MIPS16" 2087 "@ 2088 and\t%0,%1,%2 2089 andi\t%0,%1,%x2" 2090 [(set_attr "type" "arith") 2091 (set_attr "mode" "<MODE>")]) 2092 2093(define_insn "*and<mode>3_mips16" 2094 [(set (match_operand:GPR 0 "register_operand" "=d") 2095 (and:GPR (match_operand:GPR 1 "register_operand" "%0") 2096 (match_operand:GPR 2 "register_operand" "d")))] 2097 "TARGET_MIPS16" 2098 "and\t%0,%2" 2099 [(set_attr "type" "arith") 2100 (set_attr "mode" "<MODE>")]) 2101 2102(define_expand "ior<mode>3" 2103 [(set (match_operand:GPR 0 "register_operand") 2104 (ior:GPR (match_operand:GPR 1 "register_operand") 2105 (match_operand:GPR 2 "uns_arith_operand")))] 2106 "" 2107{ 2108 if (TARGET_MIPS16) 2109 operands[2] = force_reg (<MODE>mode, operands[2]); 2110}) 2111 2112(define_insn "*ior<mode>3" 2113 [(set (match_operand:GPR 0 "register_operand" "=d,d") 2114 (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d") 2115 (match_operand:GPR 2 "uns_arith_operand" "d,K")))] 2116 "!TARGET_MIPS16" 2117 "@ 2118 or\t%0,%1,%2 2119 ori\t%0,%1,%x2" 2120 [(set_attr "type" "arith") 2121 (set_attr "mode" "<MODE>")]) 2122 2123(define_insn "*ior<mode>3_mips16" 2124 [(set (match_operand:GPR 0 "register_operand" "=d") 2125 (ior:GPR (match_operand:GPR 1 "register_operand" "%0") 2126 (match_operand:GPR 2 "register_operand" "d")))] 2127 "TARGET_MIPS16" 2128 "or\t%0,%2" 2129 [(set_attr "type" "arith") 2130 (set_attr "mode" "<MODE>")]) 2131 2132(define_expand "xor<mode>3" 2133 [(set (match_operand:GPR 0 "register_operand") 2134 (xor:GPR (match_operand:GPR 1 "register_operand") 2135 (match_operand:GPR 2 "uns_arith_operand")))] 2136 "" 2137 "") 2138 2139(define_insn "" 2140 [(set (match_operand:GPR 0 "register_operand" "=d,d") 2141 (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d") 2142 (match_operand:GPR 2 "uns_arith_operand" "d,K")))] 2143 "!TARGET_MIPS16" 2144 "@ 2145 xor\t%0,%1,%2 2146 xori\t%0,%1,%x2" 2147 [(set_attr "type" "arith") 2148 (set_attr "mode" "<MODE>")]) 2149 2150(define_insn "" 2151 [(set (match_operand:GPR 0 "register_operand" "=d,t,t") 2152 (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d") 2153 (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))] 2154 "TARGET_MIPS16" 2155 "@ 2156 xor\t%0,%2 2157 cmpi\t%1,%2 2158 cmp\t%1,%2" 2159 [(set_attr "type" "arith") 2160 (set_attr "mode" "<MODE>") 2161 (set_attr_alternative "length" 2162 [(const_int 4) 2163 (if_then_else (match_operand:VOID 2 "m16_uimm8_1") 2164 (const_int 4) 2165 (const_int 8)) 2166 (const_int 4)])]) 2167 2168(define_insn "*nor<mode>3" 2169 [(set (match_operand:GPR 0 "register_operand" "=d") 2170 (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d")) 2171 (not:GPR (match_operand:GPR 2 "register_operand" "d"))))] 2172 "!TARGET_MIPS16" 2173 "nor\t%0,%1,%2" 2174 [(set_attr "type" "arith") 2175 (set_attr "mode" "<MODE>")]) 2176 2177;; 2178;; .................... 2179;; 2180;; TRUNCATION 2181;; 2182;; .................... 2183 2184 2185 2186(define_insn "truncdfsf2" 2187 [(set (match_operand:SF 0 "register_operand" "=f") 2188 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))] 2189 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 2190 "cvt.s.d\t%0,%1" 2191 [(set_attr "type" "fcvt") 2192 (set_attr "cnv_mode" "D2S") 2193 (set_attr "mode" "SF")]) 2194 2195;; Integer truncation patterns. Truncating SImode values to smaller 2196;; modes is a no-op, as it is for most other GCC ports. Truncating 2197;; DImode values to SImode is not a no-op for TARGET_64BIT since we 2198;; need to make sure that the lower 32 bits are properly sign-extended 2199;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes 2200;; smaller than SImode is equivalent to two separate truncations: 2201;; 2202;; A B 2203;; DI ---> HI == DI ---> SI ---> HI 2204;; DI ---> QI == DI ---> SI ---> QI 2205;; 2206;; Step A needs a real instruction but step B does not. 2207 2208(define_insn "truncdisi2" 2209 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m") 2210 (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))] 2211 "TARGET_64BIT" 2212 "@ 2213 sll\t%0,%1,0 2214 sw\t%1,%0" 2215 [(set_attr "type" "shift,store") 2216 (set_attr "mode" "SI") 2217 (set_attr "extended_mips16" "yes,*")]) 2218 2219(define_insn "truncdihi2" 2220 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m") 2221 (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))] 2222 "TARGET_64BIT" 2223 "@ 2224 sll\t%0,%1,0 2225 sh\t%1,%0" 2226 [(set_attr "type" "shift,store") 2227 (set_attr "mode" "SI") 2228 (set_attr "extended_mips16" "yes,*")]) 2229 2230(define_insn "truncdiqi2" 2231 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m") 2232 (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))] 2233 "TARGET_64BIT" 2234 "@ 2235 sll\t%0,%1,0 2236 sb\t%1,%0" 2237 [(set_attr "type" "shift,store") 2238 (set_attr "mode" "SI") 2239 (set_attr "extended_mips16" "yes,*")]) 2240 2241;; Combiner patterns to optimize shift/truncate combinations. 2242 2243(define_insn "" 2244 [(set (match_operand:SI 0 "register_operand" "=d") 2245 (truncate:SI 2246 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") 2247 (match_operand:DI 2 "const_arith_operand" ""))))] 2248 "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32" 2249 "dsra\t%0,%1,%2" 2250 [(set_attr "type" "shift") 2251 (set_attr "mode" "SI")]) 2252 2253(define_insn "" 2254 [(set (match_operand:SI 0 "register_operand" "=d") 2255 (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") 2256 (const_int 32))))] 2257 "TARGET_64BIT && !TARGET_MIPS16" 2258 "dsra\t%0,%1,32" 2259 [(set_attr "type" "shift") 2260 (set_attr "mode" "SI")]) 2261 2262 2263;; Combiner patterns for truncate/sign_extend combinations. They use 2264;; the shift/truncate patterns above. 2265 2266(define_insn_and_split "" 2267 [(set (match_operand:SI 0 "register_operand" "=d") 2268 (sign_extend:SI 2269 (truncate:HI (match_operand:DI 1 "register_operand" "d"))))] 2270 "TARGET_64BIT && !TARGET_MIPS16" 2271 "#" 2272 "&& reload_completed" 2273 [(set (match_dup 2) 2274 (ashift:DI (match_dup 1) 2275 (const_int 48))) 2276 (set (match_dup 0) 2277 (truncate:SI (ashiftrt:DI (match_dup 2) 2278 (const_int 48))))] 2279 { operands[2] = gen_lowpart (DImode, operands[0]); }) 2280 2281(define_insn_and_split "" 2282 [(set (match_operand:SI 0 "register_operand" "=d") 2283 (sign_extend:SI 2284 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))] 2285 "TARGET_64BIT && !TARGET_MIPS16" 2286 "#" 2287 "&& reload_completed" 2288 [(set (match_dup 2) 2289 (ashift:DI (match_dup 1) 2290 (const_int 56))) 2291 (set (match_dup 0) 2292 (truncate:SI (ashiftrt:DI (match_dup 2) 2293 (const_int 56))))] 2294 { operands[2] = gen_lowpart (DImode, operands[0]); }) 2295 2296 2297;; Combiner patterns to optimize truncate/zero_extend combinations. 2298 2299(define_insn "" 2300 [(set (match_operand:SI 0 "register_operand" "=d") 2301 (zero_extend:SI (truncate:HI 2302 (match_operand:DI 1 "register_operand" "d"))))] 2303 "TARGET_64BIT && !TARGET_MIPS16" 2304 "andi\t%0,%1,0xffff" 2305 [(set_attr "type" "arith") 2306 (set_attr "mode" "SI")]) 2307 2308(define_insn "" 2309 [(set (match_operand:SI 0 "register_operand" "=d") 2310 (zero_extend:SI (truncate:QI 2311 (match_operand:DI 1 "register_operand" "d"))))] 2312 "TARGET_64BIT && !TARGET_MIPS16" 2313 "andi\t%0,%1,0xff" 2314 [(set_attr "type" "arith") 2315 (set_attr "mode" "SI")]) 2316 2317(define_insn "" 2318 [(set (match_operand:HI 0 "register_operand" "=d") 2319 (zero_extend:HI (truncate:QI 2320 (match_operand:DI 1 "register_operand" "d"))))] 2321 "TARGET_64BIT && !TARGET_MIPS16" 2322 "andi\t%0,%1,0xff" 2323 [(set_attr "type" "arith") 2324 (set_attr "mode" "HI")]) 2325 2326;; 2327;; .................... 2328;; 2329;; ZERO EXTENSION 2330;; 2331;; .................... 2332 2333;; Extension insns. 2334 2335(define_insn_and_split "zero_extendsidi2" 2336 [(set (match_operand:DI 0 "register_operand" "=d,d") 2337 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))] 2338 "TARGET_64BIT" 2339 "@ 2340 # 2341 lwu\t%0,%1" 2342 "&& reload_completed && REG_P (operands[1])" 2343 [(set (match_dup 0) 2344 (ashift:DI (match_dup 1) (const_int 32))) 2345 (set (match_dup 0) 2346 (lshiftrt:DI (match_dup 0) (const_int 32)))] 2347 { operands[1] = gen_lowpart (DImode, operands[1]); } 2348 [(set_attr "type" "multi,load") 2349 (set_attr "mode" "DI") 2350 (set_attr "length" "8,*")]) 2351 2352;; Combine is not allowed to convert this insn into a zero_extendsidi2 2353;; because of TRULY_NOOP_TRUNCATION. 2354 2355(define_insn_and_split "*clear_upper32" 2356 [(set (match_operand:DI 0 "register_operand" "=d,d") 2357 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o") 2358 (const_int 4294967295)))] 2359 "TARGET_64BIT" 2360{ 2361 if (which_alternative == 0) 2362 return "#"; 2363 2364 operands[1] = gen_lowpart (SImode, operands[1]); 2365 return "lwu\t%0,%1"; 2366} 2367 "&& reload_completed && REG_P (operands[1])" 2368 [(set (match_dup 0) 2369 (ashift:DI (match_dup 1) (const_int 32))) 2370 (set (match_dup 0) 2371 (lshiftrt:DI (match_dup 0) (const_int 32)))] 2372 "" 2373 [(set_attr "type" "multi,load") 2374 (set_attr "mode" "DI") 2375 (set_attr "length" "8,*")]) 2376 2377(define_expand "zero_extend<SHORT:mode><GPR:mode>2" 2378 [(set (match_operand:GPR 0 "register_operand") 2379 (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))] 2380 "" 2381{ 2382 if (TARGET_MIPS16 && !GENERATE_MIPS16E 2383 && !memory_operand (operands[1], <SHORT:MODE>mode)) 2384 { 2385 emit_insn (gen_and<GPR:mode>3 (operands[0], 2386 gen_lowpart (<GPR:MODE>mode, operands[1]), 2387 force_reg (<GPR:MODE>mode, 2388 GEN_INT (<SHORT:mask>)))); 2389 DONE; 2390 } 2391}) 2392 2393(define_insn "*zero_extend<SHORT:mode><GPR:mode>2" 2394 [(set (match_operand:GPR 0 "register_operand" "=d,d") 2395 (zero_extend:GPR 2396 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))] 2397 "!TARGET_MIPS16" 2398 "@ 2399 andi\t%0,%1,<SHORT:mask> 2400 l<SHORT:size>u\t%0,%1" 2401 [(set_attr "type" "arith,load") 2402 (set_attr "mode" "<GPR:MODE>")]) 2403 2404(define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e" 2405 [(set (match_operand:GPR 0 "register_operand" "=d") 2406 (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))] 2407 "GENERATE_MIPS16E" 2408 "ze<SHORT:size>\t%0" 2409 [(set_attr "type" "arith") 2410 (set_attr "mode" "<GPR:MODE>")]) 2411 2412(define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16" 2413 [(set (match_operand:GPR 0 "register_operand" "=d") 2414 (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))] 2415 "TARGET_MIPS16" 2416 "l<SHORT:size>u\t%0,%1" 2417 [(set_attr "type" "load") 2418 (set_attr "mode" "<GPR:MODE>")]) 2419 2420(define_expand "zero_extendqihi2" 2421 [(set (match_operand:HI 0 "register_operand") 2422 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))] 2423 "" 2424{ 2425 if (TARGET_MIPS16 && !memory_operand (operands[1], QImode)) 2426 { 2427 emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]), 2428 operands[1])); 2429 DONE; 2430 } 2431}) 2432 2433(define_insn "*zero_extendqihi2" 2434 [(set (match_operand:HI 0 "register_operand" "=d,d") 2435 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] 2436 "!TARGET_MIPS16" 2437 "@ 2438 andi\t%0,%1,0x00ff 2439 lbu\t%0,%1" 2440 [(set_attr "type" "arith,load") 2441 (set_attr "mode" "HI")]) 2442 2443(define_insn "*zero_extendqihi2_mips16" 2444 [(set (match_operand:HI 0 "register_operand" "=d") 2445 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))] 2446 "TARGET_MIPS16" 2447 "lbu\t%0,%1" 2448 [(set_attr "type" "load") 2449 (set_attr "mode" "HI")]) 2450 2451;; 2452;; .................... 2453;; 2454;; SIGN EXTENSION 2455;; 2456;; .................... 2457 2458;; Extension insns. 2459;; Those for integer source operand are ordered widest source type first. 2460 2461;; When TARGET_64BIT, all SImode integer registers should already be in 2462;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can 2463;; therefore get rid of register->register instructions if we constrain 2464;; the source to be in the same register as the destination. 2465;; 2466;; The register alternative has type "arith" so that the pre-reload 2467;; scheduler will treat it as a move. This reflects what happens if 2468;; the register alternative needs a reload. 2469(define_insn_and_split "extendsidi2" 2470 [(set (match_operand:DI 0 "register_operand" "=d,d") 2471 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))] 2472 "TARGET_64BIT" 2473 "@ 2474 # 2475 lw\t%0,%1" 2476 "&& reload_completed && register_operand (operands[1], VOIDmode)" 2477 [(const_int 0)] 2478{ 2479 emit_note (NOTE_INSN_DELETED); 2480 DONE; 2481} 2482 [(set_attr "type" "arith,load") 2483 (set_attr "mode" "DI")]) 2484 2485(define_expand "extend<SHORT:mode><GPR:mode>2" 2486 [(set (match_operand:GPR 0 "register_operand") 2487 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))] 2488 "") 2489 2490(define_insn "*extend<SHORT:mode><GPR:mode>2_mips16e" 2491 [(set (match_operand:GPR 0 "register_operand" "=d,d") 2492 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))] 2493 "GENERATE_MIPS16E" 2494 "@ 2495 se<SHORT:size>\t%0 2496 l<SHORT:size>\t%0,%1" 2497 [(set_attr "type" "arith,load") 2498 (set_attr "mode" "<GPR:MODE>")]) 2499 2500(define_insn_and_split "*extend<SHORT:mode><GPR:mode>2" 2501 [(set (match_operand:GPR 0 "register_operand" "=d,d") 2502 (sign_extend:GPR 2503 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))] 2504 "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E" 2505 "@ 2506 # 2507 l<SHORT:size>\t%0,%1" 2508 "&& reload_completed && REG_P (operands[1])" 2509 [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2))) 2510 (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))] 2511{ 2512 operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]); 2513 operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode) 2514 - GET_MODE_BITSIZE (<SHORT:MODE>mode)); 2515} 2516 [(set_attr "type" "arith,load") 2517 (set_attr "mode" "<GPR:MODE>") 2518 (set_attr "length" "8,*")]) 2519 2520(define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>" 2521 [(set (match_operand:GPR 0 "register_operand" "=d,d") 2522 (sign_extend:GPR 2523 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))] 2524 "ISA_HAS_SEB_SEH" 2525 "@ 2526 se<SHORT:size>\t%0,%1 2527 l<SHORT:size>\t%0,%1" 2528 [(set_attr "type" "arith,load") 2529 (set_attr "mode" "<GPR:MODE>")]) 2530 2531;; This pattern generates the same code as extendqisi2; split it into 2532;; that form after reload. 2533(define_insn_and_split "extendqihi2" 2534 [(set (match_operand:HI 0 "register_operand" "=d,d") 2535 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] 2536 "" 2537 "#" 2538 "reload_completed" 2539 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))] 2540 { operands[0] = gen_lowpart (SImode, operands[0]); } 2541 [(set_attr "type" "arith,load") 2542 (set_attr "mode" "SI") 2543 (set_attr "length" "8,*")]) 2544 2545(define_insn "extendsfdf2" 2546 [(set (match_operand:DF 0 "register_operand" "=f") 2547 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))] 2548 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 2549 "cvt.d.s\t%0,%1" 2550 [(set_attr "type" "fcvt") 2551 (set_attr "cnv_mode" "S2D") 2552 (set_attr "mode" "DF")]) 2553 2554;; 2555;; .................... 2556;; 2557;; CONVERSIONS 2558;; 2559;; .................... 2560 2561(define_expand "fix_truncdfsi2" 2562 [(set (match_operand:SI 0 "register_operand") 2563 (fix:SI (match_operand:DF 1 "register_operand")))] 2564 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 2565{ 2566 if (!ISA_HAS_TRUNC_W) 2567 { 2568 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1])); 2569 DONE; 2570 } 2571}) 2572 2573(define_insn "fix_truncdfsi2_insn" 2574 [(set (match_operand:SI 0 "register_operand" "=f") 2575 (fix:SI (match_operand:DF 1 "register_operand" "f")))] 2576 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W" 2577 "trunc.w.d %0,%1" 2578 [(set_attr "type" "fcvt") 2579 (set_attr "mode" "DF") 2580 (set_attr "cnv_mode" "D2I") 2581 (set_attr "length" "4")]) 2582 2583(define_insn "fix_truncdfsi2_macro" 2584 [(set (match_operand:SI 0 "register_operand" "=f") 2585 (fix:SI (match_operand:DF 1 "register_operand" "f"))) 2586 (clobber (match_scratch:DF 2 "=d"))] 2587 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W" 2588{ 2589 if (set_nomacro) 2590 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro"; 2591 else 2592 return "trunc.w.d %0,%1,%2"; 2593} 2594 [(set_attr "type" "fcvt") 2595 (set_attr "mode" "DF") 2596 (set_attr "cnv_mode" "D2I") 2597 (set_attr "length" "36")]) 2598 2599(define_expand "fix_truncsfsi2" 2600 [(set (match_operand:SI 0 "register_operand") 2601 (fix:SI (match_operand:SF 1 "register_operand")))] 2602 "TARGET_HARD_FLOAT" 2603{ 2604 if (!ISA_HAS_TRUNC_W) 2605 { 2606 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1])); 2607 DONE; 2608 } 2609}) 2610 2611(define_insn "fix_truncsfsi2_insn" 2612 [(set (match_operand:SI 0 "register_operand" "=f") 2613 (fix:SI (match_operand:SF 1 "register_operand" "f")))] 2614 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W" 2615 "trunc.w.s %0,%1" 2616 [(set_attr "type" "fcvt") 2617 (set_attr "mode" "SF") 2618 (set_attr "cnv_mode" "S2I") 2619 (set_attr "length" "4")]) 2620 2621(define_insn "fix_truncsfsi2_macro" 2622 [(set (match_operand:SI 0 "register_operand" "=f") 2623 (fix:SI (match_operand:SF 1 "register_operand" "f"))) 2624 (clobber (match_scratch:SF 2 "=d"))] 2625 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W" 2626{ 2627 if (set_nomacro) 2628 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro"; 2629 else 2630 return "trunc.w.s %0,%1,%2"; 2631} 2632 [(set_attr "type" "fcvt") 2633 (set_attr "mode" "SF") 2634 (set_attr "cnv_mode" "S2I") 2635 (set_attr "length" "36")]) 2636 2637 2638(define_insn "fix_truncdfdi2" 2639 [(set (match_operand:DI 0 "register_operand" "=f") 2640 (fix:DI (match_operand:DF 1 "register_operand" "f")))] 2641 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT" 2642 "trunc.l.d %0,%1" 2643 [(set_attr "type" "fcvt") 2644 (set_attr "mode" "DF") 2645 (set_attr "cnv_mode" "D2I") 2646 (set_attr "length" "4")]) 2647 2648 2649(define_insn "fix_truncsfdi2" 2650 [(set (match_operand:DI 0 "register_operand" "=f") 2651 (fix:DI (match_operand:SF 1 "register_operand" "f")))] 2652 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT" 2653 "trunc.l.s %0,%1" 2654 [(set_attr "type" "fcvt") 2655 (set_attr "mode" "SF") 2656 (set_attr "cnv_mode" "S2I") 2657 (set_attr "length" "4")]) 2658 2659 2660(define_insn "floatsidf2" 2661 [(set (match_operand:DF 0 "register_operand" "=f") 2662 (float:DF (match_operand:SI 1 "register_operand" "f")))] 2663 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 2664 "cvt.d.w\t%0,%1" 2665 [(set_attr "type" "fcvt") 2666 (set_attr "mode" "DF") 2667 (set_attr "cnv_mode" "I2D") 2668 (set_attr "length" "4")]) 2669 2670 2671(define_insn "floatdidf2" 2672 [(set (match_operand:DF 0 "register_operand" "=f") 2673 (float:DF (match_operand:DI 1 "register_operand" "f")))] 2674 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT" 2675 "cvt.d.l\t%0,%1" 2676 [(set_attr "type" "fcvt") 2677 (set_attr "mode" "DF") 2678 (set_attr "cnv_mode" "I2D") 2679 (set_attr "length" "4")]) 2680 2681 2682(define_insn "floatsisf2" 2683 [(set (match_operand:SF 0 "register_operand" "=f") 2684 (float:SF (match_operand:SI 1 "register_operand" "f")))] 2685 "TARGET_HARD_FLOAT" 2686 "cvt.s.w\t%0,%1" 2687 [(set_attr "type" "fcvt") 2688 (set_attr "mode" "SF") 2689 (set_attr "cnv_mode" "I2S") 2690 (set_attr "length" "4")]) 2691 2692 2693(define_insn "floatdisf2" 2694 [(set (match_operand:SF 0 "register_operand" "=f") 2695 (float:SF (match_operand:DI 1 "register_operand" "f")))] 2696 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT" 2697 "cvt.s.l\t%0,%1" 2698 [(set_attr "type" "fcvt") 2699 (set_attr "mode" "SF") 2700 (set_attr "cnv_mode" "I2S") 2701 (set_attr "length" "4")]) 2702 2703 2704(define_expand "fixuns_truncdfsi2" 2705 [(set (match_operand:SI 0 "register_operand") 2706 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))] 2707 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 2708{ 2709 rtx reg1 = gen_reg_rtx (DFmode); 2710 rtx reg2 = gen_reg_rtx (DFmode); 2711 rtx reg3 = gen_reg_rtx (SImode); 2712 rtx label1 = gen_label_rtx (); 2713 rtx label2 = gen_label_rtx (); 2714 REAL_VALUE_TYPE offset; 2715 2716 real_2expN (&offset, 31); 2717 2718 if (reg1) /* Turn off complaints about unreached code. */ 2719 { 2720 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode)); 2721 do_pending_stack_adjust (); 2722 2723 emit_insn (gen_cmpdf (operands[1], reg1)); 2724 emit_jump_insn (gen_bge (label1)); 2725 2726 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1])); 2727 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, 2728 gen_rtx_LABEL_REF (VOIDmode, label2))); 2729 emit_barrier (); 2730 2731 emit_label (label1); 2732 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1)); 2733 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode 2734 (BITMASK_HIGH, SImode))); 2735 2736 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2)); 2737 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3)); 2738 2739 emit_label (label2); 2740 2741 /* Allow REG_NOTES to be set on last insn (labels don't have enough 2742 fields, and can't be used for REG_NOTES anyway). */ 2743 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); 2744 DONE; 2745 } 2746}) 2747 2748 2749(define_expand "fixuns_truncdfdi2" 2750 [(set (match_operand:DI 0 "register_operand") 2751 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))] 2752 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT" 2753{ 2754 rtx reg1 = gen_reg_rtx (DFmode); 2755 rtx reg2 = gen_reg_rtx (DFmode); 2756 rtx reg3 = gen_reg_rtx (DImode); 2757 rtx label1 = gen_label_rtx (); 2758 rtx label2 = gen_label_rtx (); 2759 REAL_VALUE_TYPE offset; 2760 2761 real_2expN (&offset, 63); 2762 2763 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode)); 2764 do_pending_stack_adjust (); 2765 2766 emit_insn (gen_cmpdf (operands[1], reg1)); 2767 emit_jump_insn (gen_bge (label1)); 2768 2769 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1])); 2770 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, 2771 gen_rtx_LABEL_REF (VOIDmode, label2))); 2772 emit_barrier (); 2773 2774 emit_label (label1); 2775 emit_move_insn (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1)); 2776 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH)); 2777 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32))); 2778 2779 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2)); 2780 emit_insn (gen_iordi3 (operands[0], operands[0], reg3)); 2781 2782 emit_label (label2); 2783 2784 /* Allow REG_NOTES to be set on last insn (labels don't have enough 2785 fields, and can't be used for REG_NOTES anyway). */ 2786 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); 2787 DONE; 2788}) 2789 2790 2791(define_expand "fixuns_truncsfsi2" 2792 [(set (match_operand:SI 0 "register_operand") 2793 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))] 2794 "TARGET_HARD_FLOAT" 2795{ 2796 rtx reg1 = gen_reg_rtx (SFmode); 2797 rtx reg2 = gen_reg_rtx (SFmode); 2798 rtx reg3 = gen_reg_rtx (SImode); 2799 rtx label1 = gen_label_rtx (); 2800 rtx label2 = gen_label_rtx (); 2801 REAL_VALUE_TYPE offset; 2802 2803 real_2expN (&offset, 31); 2804 2805 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode)); 2806 do_pending_stack_adjust (); 2807 2808 emit_insn (gen_cmpsf (operands[1], reg1)); 2809 emit_jump_insn (gen_bge (label1)); 2810 2811 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1])); 2812 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, 2813 gen_rtx_LABEL_REF (VOIDmode, label2))); 2814 emit_barrier (); 2815 2816 emit_label (label1); 2817 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1)); 2818 emit_move_insn (reg3, GEN_INT (trunc_int_for_mode 2819 (BITMASK_HIGH, SImode))); 2820 2821 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2)); 2822 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3)); 2823 2824 emit_label (label2); 2825 2826 /* Allow REG_NOTES to be set on last insn (labels don't have enough 2827 fields, and can't be used for REG_NOTES anyway). */ 2828 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); 2829 DONE; 2830}) 2831 2832 2833(define_expand "fixuns_truncsfdi2" 2834 [(set (match_operand:DI 0 "register_operand") 2835 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))] 2836 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT" 2837{ 2838 rtx reg1 = gen_reg_rtx (SFmode); 2839 rtx reg2 = gen_reg_rtx (SFmode); 2840 rtx reg3 = gen_reg_rtx (DImode); 2841 rtx label1 = gen_label_rtx (); 2842 rtx label2 = gen_label_rtx (); 2843 REAL_VALUE_TYPE offset; 2844 2845 real_2expN (&offset, 63); 2846 2847 emit_move_insn (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode)); 2848 do_pending_stack_adjust (); 2849 2850 emit_insn (gen_cmpsf (operands[1], reg1)); 2851 emit_jump_insn (gen_bge (label1)); 2852 2853 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1])); 2854 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, 2855 gen_rtx_LABEL_REF (VOIDmode, label2))); 2856 emit_barrier (); 2857 2858 emit_label (label1); 2859 emit_move_insn (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1)); 2860 emit_move_insn (reg3, GEN_INT (BITMASK_HIGH)); 2861 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32))); 2862 2863 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2)); 2864 emit_insn (gen_iordi3 (operands[0], operands[0], reg3)); 2865 2866 emit_label (label2); 2867 2868 /* Allow REG_NOTES to be set on last insn (labels don't have enough 2869 fields, and can't be used for REG_NOTES anyway). */ 2870 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); 2871 DONE; 2872}) 2873 2874;; 2875;; .................... 2876;; 2877;; DATA MOVEMENT 2878;; 2879;; .................... 2880 2881;; Bit field extract patterns which use lwl/lwr or ldl/ldr. 2882 2883(define_expand "extv" 2884 [(set (match_operand 0 "register_operand") 2885 (sign_extract (match_operand:QI 1 "memory_operand") 2886 (match_operand 2 "immediate_operand") 2887 (match_operand 3 "immediate_operand")))] 2888 "!TARGET_MIPS16" 2889{ 2890 if (mips_expand_unaligned_load (operands[0], operands[1], 2891 INTVAL (operands[2]), 2892 INTVAL (operands[3]))) 2893 DONE; 2894 else 2895 FAIL; 2896}) 2897 2898(define_expand "extzv" 2899 [(set (match_operand 0 "register_operand") 2900 (zero_extract (match_operand 1 "nonimmediate_operand") 2901 (match_operand 2 "immediate_operand") 2902 (match_operand 3 "immediate_operand")))] 2903 "!TARGET_MIPS16" 2904{ 2905 if (mips_expand_unaligned_load (operands[0], operands[1], 2906 INTVAL (operands[2]), 2907 INTVAL (operands[3]))) 2908 DONE; 2909 else if (mips_use_ins_ext_p (operands[1], operands[2], operands[3])) 2910 { 2911 if (GET_MODE (operands[0]) == DImode) 2912 emit_insn (gen_extzvdi (operands[0], operands[1], operands[2], 2913 operands[3])); 2914 else 2915 emit_insn (gen_extzvsi (operands[0], operands[1], operands[2], 2916 operands[3])); 2917 DONE; 2918 } 2919 else 2920 FAIL; 2921}) 2922 2923(define_insn "extzv<mode>" 2924 [(set (match_operand:GPR 0 "register_operand" "=d") 2925 (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d") 2926 (match_operand:SI 2 "immediate_operand" "I") 2927 (match_operand:SI 3 "immediate_operand" "I")))] 2928 "mips_use_ins_ext_p (operands[1], operands[2], operands[3])" 2929 "<d>ext\t%0,%1,%3,%2" 2930 [(set_attr "type" "arith") 2931 (set_attr "mode" "<MODE>")]) 2932 2933 2934(define_expand "insv" 2935 [(set (zero_extract (match_operand 0 "nonimmediate_operand") 2936 (match_operand 1 "immediate_operand") 2937 (match_operand 2 "immediate_operand")) 2938 (match_operand 3 "reg_or_0_operand"))] 2939 "!TARGET_MIPS16" 2940{ 2941 if (mips_expand_unaligned_store (operands[0], operands[3], 2942 INTVAL (operands[1]), 2943 INTVAL (operands[2]))) 2944 DONE; 2945 else if (mips_use_ins_ext_p (operands[0], operands[1], operands[2])) 2946 { 2947 if (GET_MODE (operands[0]) == DImode) 2948 emit_insn (gen_insvdi (operands[0], operands[1], operands[2], 2949 operands[3])); 2950 else 2951 emit_insn (gen_insvsi (operands[0], operands[1], operands[2], 2952 operands[3])); 2953 DONE; 2954 } 2955 else 2956 FAIL; 2957}) 2958 2959(define_insn "insv<mode>" 2960 [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d") 2961 (match_operand:SI 1 "immediate_operand" "I") 2962 (match_operand:SI 2 "immediate_operand" "I")) 2963 (match_operand:GPR 3 "reg_or_0_operand" "dJ"))] 2964 "mips_use_ins_ext_p (operands[0], operands[1], operands[2])" 2965 "<d>ins\t%0,%z3,%2,%1" 2966 [(set_attr "type" "arith") 2967 (set_attr "mode" "<MODE>")]) 2968 2969;; Unaligned word moves generated by the bit field patterns. 2970;; 2971;; As far as the rtl is concerned, both the left-part and right-part 2972;; instructions can access the whole field. However, the real operand 2973;; refers to just the first or the last byte (depending on endianness). 2974;; We therefore use two memory operands to each instruction, one to 2975;; describe the rtl effect and one to use in the assembly output. 2976;; 2977;; Operands 0 and 1 are the rtl-level target and source respectively. 2978;; This allows us to use the standard length calculations for the "load" 2979;; and "store" type attributes. 2980 2981(define_insn "mov_<load>l" 2982 [(set (match_operand:GPR 0 "register_operand" "=d") 2983 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m") 2984 (match_operand:QI 2 "memory_operand" "m")] 2985 UNSPEC_LOAD_LEFT))] 2986 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])" 2987 "<load>l\t%0,%2" 2988 [(set_attr "type" "load") 2989 (set_attr "mode" "<MODE>")]) 2990 2991(define_insn "mov_<load>r" 2992 [(set (match_operand:GPR 0 "register_operand" "=d") 2993 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m") 2994 (match_operand:QI 2 "memory_operand" "m") 2995 (match_operand:GPR 3 "register_operand" "0")] 2996 UNSPEC_LOAD_RIGHT))] 2997 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])" 2998 "<load>r\t%0,%2" 2999 [(set_attr "type" "load") 3000 (set_attr "mode" "<MODE>")]) 3001 3002(define_insn "mov_<store>l" 3003 [(set (match_operand:BLK 0 "memory_operand" "=m") 3004 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ") 3005 (match_operand:QI 2 "memory_operand" "m")] 3006 UNSPEC_STORE_LEFT))] 3007 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])" 3008 "<store>l\t%z1,%2" 3009 [(set_attr "type" "store") 3010 (set_attr "mode" "<MODE>")]) 3011 3012(define_insn "mov_<store>r" 3013 [(set (match_operand:BLK 0 "memory_operand" "+m") 3014 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ") 3015 (match_operand:QI 2 "memory_operand" "m") 3016 (match_dup 0)] 3017 UNSPEC_STORE_RIGHT))] 3018 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])" 3019 "<store>r\t%z1,%2" 3020 [(set_attr "type" "store") 3021 (set_attr "mode" "<MODE>")]) 3022 3023;; An instruction to calculate the high part of a 64-bit SYMBOL_GENERAL. 3024;; The required value is: 3025;; 3026;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16) 3027;; 3028;; which translates to: 3029;; 3030;; lui op0,%highest(op1) 3031;; daddiu op0,op0,%higher(op1) 3032;; dsll op0,op0,16 3033;; daddiu op0,op0,%hi(op1) 3034;; dsll op0,op0,16 3035;; 3036;; The split is deferred until after flow2 to allow the peephole2 below 3037;; to take effect. 3038(define_insn_and_split "*lea_high64" 3039 [(set (match_operand:DI 0 "register_operand" "=d") 3040 (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))] 3041 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS" 3042 "#" 3043 "&& flow2_completed" 3044 [(set (match_dup 0) (high:DI (match_dup 2))) 3045 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2))) 3046 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16))) 3047 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3))) 3048 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))] 3049{ 3050 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH); 3051 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID); 3052} 3053 [(set_attr "length" "20")]) 3054 3055;; Use a scratch register to reduce the latency of the above pattern 3056;; on superscalar machines. The optimized sequence is: 3057;; 3058;; lui op1,%highest(op2) 3059;; lui op0,%hi(op2) 3060;; daddiu op1,op1,%higher(op2) 3061;; dsll32 op1,op1,0 3062;; daddu op1,op1,op0 3063(define_peephole2 3064 [(set (match_operand:DI 1 "register_operand") 3065 (high:DI (match_operand:DI 2 "general_symbolic_operand"))) 3066 (match_scratch:DI 0 "d")] 3067 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS" 3068 [(set (match_dup 1) (high:DI (match_dup 3))) 3069 (set (match_dup 0) (high:DI (match_dup 4))) 3070 (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3))) 3071 (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32))) 3072 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))] 3073{ 3074 operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH); 3075 operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW); 3076}) 3077 3078;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit 3079;; SYMBOL_GENERAL X will take 6 cycles. This next pattern allows combine 3080;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only 3081;; used once. We can then use the sequence: 3082;; 3083;; lui op0,%highest(op1) 3084;; lui op2,%hi(op1) 3085;; daddiu op0,op0,%higher(op1) 3086;; daddiu op2,op2,%lo(op1) 3087;; dsll32 op0,op0,0 3088;; daddu op0,op0,op2 3089;; 3090;; which takes 4 cycles on most superscalar targets. 3091(define_insn_and_split "*lea64" 3092 [(set (match_operand:DI 0 "register_operand" "=d") 3093 (match_operand:DI 1 "general_symbolic_operand" "")) 3094 (clobber (match_scratch:DI 2 "=&d"))] 3095 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected" 3096 "#" 3097 "&& reload_completed" 3098 [(set (match_dup 0) (high:DI (match_dup 3))) 3099 (set (match_dup 2) (high:DI (match_dup 4))) 3100 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3))) 3101 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4))) 3102 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32))) 3103 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))] 3104{ 3105 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH); 3106 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW); 3107} 3108 [(set_attr "length" "24")]) 3109 3110;; Insns to fetch a global symbol from a big GOT. 3111 3112(define_insn_and_split "*xgot_hi<mode>" 3113 [(set (match_operand:P 0 "register_operand" "=d") 3114 (high:P (match_operand:P 1 "global_got_operand" "")))] 3115 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT" 3116 "#" 3117 "&& reload_completed" 3118 [(set (match_dup 0) (high:P (match_dup 2))) 3119 (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))] 3120{ 3121 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL); 3122 operands[3] = pic_offset_table_rtx; 3123} 3124 [(set_attr "got" "xgot_high") 3125 (set_attr "mode" "<MODE>")]) 3126 3127(define_insn_and_split "*xgot_lo<mode>" 3128 [(set (match_operand:P 0 "register_operand" "=d") 3129 (lo_sum:P (match_operand:P 1 "register_operand" "d") 3130 (match_operand:P 2 "global_got_operand" "")))] 3131 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT" 3132 "#" 3133 "&& reload_completed" 3134 [(set (match_dup 0) 3135 (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))] 3136 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_GLOBAL); } 3137 [(set_attr "got" "load") 3138 (set_attr "mode" "<MODE>")]) 3139 3140;; Insns to fetch a global symbol from a normal GOT. 3141 3142(define_insn_and_split "*got_disp<mode>" 3143 [(set (match_operand:P 0 "register_operand" "=d") 3144 (match_operand:P 1 "global_got_operand" ""))] 3145 "TARGET_EXPLICIT_RELOCS && !TARGET_XGOT" 3146 "#" 3147 "&& reload_completed" 3148 [(set (match_dup 0) 3149 (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))] 3150{ 3151 operands[2] = pic_offset_table_rtx; 3152 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_GLOBAL); 3153} 3154 [(set_attr "got" "load") 3155 (set_attr "mode" "<MODE>")]) 3156 3157;; Insns for loading the high part of a local symbol. 3158 3159(define_insn_and_split "*got_page<mode>" 3160 [(set (match_operand:P 0 "register_operand" "=d") 3161 (high:P (match_operand:P 1 "local_got_operand" "")))] 3162 "TARGET_EXPLICIT_RELOCS" 3163 "#" 3164 "&& reload_completed" 3165 [(set (match_dup 0) 3166 (unspec:P [(match_dup 2) (match_dup 3)] UNSPEC_LOAD_GOT))] 3167{ 3168 operands[2] = pic_offset_table_rtx; 3169 operands[3] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_PAGE); 3170} 3171 [(set_attr "got" "load") 3172 (set_attr "mode" "<MODE>")]) 3173 3174;; Lower-level instructions for loading an address from the GOT. 3175;; We could use MEMs, but an unspec gives more optimization 3176;; opportunities. 3177 3178(define_insn "load_got<mode>" 3179 [(set (match_operand:P 0 "register_operand" "=d") 3180 (unspec:P [(match_operand:P 1 "register_operand" "d") 3181 (match_operand:P 2 "immediate_operand" "")] 3182 UNSPEC_LOAD_GOT))] 3183 "" 3184 "<load>\t%0,%R2(%1)" 3185 [(set_attr "type" "load") 3186 (set_attr "mode" "<MODE>") 3187 (set_attr "length" "4")]) 3188 3189;; Instructions for adding the low 16 bits of an address to a register. 3190;; Operand 2 is the address: print_operand works out which relocation 3191;; should be applied. 3192 3193(define_insn "*low<mode>" 3194 [(set (match_operand:P 0 "register_operand" "=d") 3195 (lo_sum:P (match_operand:P 1 "register_operand" "d") 3196 (match_operand:P 2 "immediate_operand" "")))] 3197 "!TARGET_MIPS16" 3198 "<d>addiu\t%0,%1,%R2" 3199 [(set_attr "type" "arith") 3200 (set_attr "mode" "<MODE>")]) 3201 3202(define_insn "*low<mode>_mips16" 3203 [(set (match_operand:P 0 "register_operand" "=d") 3204 (lo_sum:P (match_operand:P 1 "register_operand" "0") 3205 (match_operand:P 2 "immediate_operand" "")))] 3206 "TARGET_MIPS16" 3207 "<d>addiu\t%0,%R2" 3208 [(set_attr "type" "arith") 3209 (set_attr "mode" "<MODE>") 3210 (set_attr "length" "8")]) 3211 3212;; Allow combine to split complex const_int load sequences, using operand 2 3213;; to store the intermediate results. See move_operand for details. 3214(define_split 3215 [(set (match_operand:GPR 0 "register_operand") 3216 (match_operand:GPR 1 "splittable_const_int_operand")) 3217 (clobber (match_operand:GPR 2 "register_operand"))] 3218 "" 3219 [(const_int 0)] 3220{ 3221 mips_move_integer (operands[0], operands[2], INTVAL (operands[1])); 3222 DONE; 3223}) 3224 3225;; Likewise, for symbolic operands. 3226(define_split 3227 [(set (match_operand:P 0 "register_operand") 3228 (match_operand:P 1 "splittable_symbolic_operand")) 3229 (clobber (match_operand:P 2 "register_operand"))] 3230 "" 3231 [(set (match_dup 0) (match_dup 1))] 3232 { operands[1] = mips_split_symbol (operands[2], operands[1]); }) 3233 3234;; 64-bit integer moves 3235 3236;; Unlike most other insns, the move insns can't be split with 3237;; different predicates, because register spilling and other parts of 3238;; the compiler, have memoized the insn number already. 3239 3240(define_expand "movdi" 3241 [(set (match_operand:DI 0 "") 3242 (match_operand:DI 1 ""))] 3243 "" 3244{ 3245 if (mips_legitimize_move (DImode, operands[0], operands[1])) 3246 DONE; 3247}) 3248 3249;; For mips16, we need a special case to handle storing $31 into 3250;; memory, since we don't have a constraint to match $31. This 3251;; instruction can be generated by save_restore_insns. 3252 3253(define_insn "*mov<mode>_ra" 3254 [(set (match_operand:GPR 0 "stack_operand" "=m") 3255 (reg:GPR 31))] 3256 "TARGET_MIPS16" 3257 "<store>\t$31,%0" 3258 [(set_attr "type" "store") 3259 (set_attr "mode" "<MODE>")]) 3260 3261(define_insn "*movdi_32bit" 3262 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*B*C*D,*B*C*D,*d,*m") 3263 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))] 3264 "!TARGET_64BIT && !TARGET_MIPS16 3265 && (register_operand (operands[0], DImode) 3266 || reg_or_0_operand (operands[1], DImode))" 3267 { return mips_output_move (operands[0], operands[1]); } 3268 [(set_attr "type" "arith,arith,load,store,mthilo,mfhilo,xfer,load,xfer,store") 3269 (set_attr "mode" "DI") 3270 (set_attr "length" "8,16,*,*,8,8,8,*,8,*")]) 3271 3272(define_insn "*movdi_32bit_mips16" 3273 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d") 3274 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))] 3275 "!TARGET_64BIT && TARGET_MIPS16 3276 && (register_operand (operands[0], DImode) 3277 || register_operand (operands[1], DImode))" 3278 { return mips_output_move (operands[0], operands[1]); } 3279 [(set_attr "type" "arith,arith,arith,arith,arith,load,store,mfhilo") 3280 (set_attr "mode" "DI") 3281 (set_attr "length" "8,8,8,8,12,*,*,8")]) 3282 3283(define_insn "*movdi_64bit" 3284 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*B*C*D,*B*C*D,*d,*m") 3285 (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J*d,*d,*m,*B*C*D,*B*C*D"))] 3286 "TARGET_64BIT && !TARGET_MIPS16 3287 && (register_operand (operands[0], DImode) 3288 || reg_or_0_operand (operands[1], DImode))" 3289 { return mips_output_move (operands[0], operands[1]); } 3290 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,mthilo,xfer,load,xfer,store") 3291 (set_attr "mode" "DI") 3292 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,8,*,8,*")]) 3293 3294(define_insn "*movdi_64bit_mips16" 3295 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m") 3296 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d"))] 3297 "TARGET_64BIT && TARGET_MIPS16 3298 && (register_operand (operands[0], DImode) 3299 || register_operand (operands[1], DImode))" 3300 { return mips_output_move (operands[0], operands[1]); } 3301 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store") 3302 (set_attr "mode" "DI") 3303 (set_attr_alternative "length" 3304 [(const_int 4) 3305 (const_int 4) 3306 (const_int 4) 3307 (if_then_else (match_operand:VOID 1 "m16_uimm8_1") 3308 (const_int 4) 3309 (const_int 8)) 3310 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1") 3311 (const_int 8) 3312 (const_int 12)) 3313 (const_string "*") 3314 (const_string "*") 3315 (const_string "*")])]) 3316 3317 3318;; On the mips16, we can split ld $r,N($r) into an add and a load, 3319;; when the original load is a 4 byte instruction but the add and the 3320;; load are 2 2 byte instructions. 3321 3322(define_split 3323 [(set (match_operand:DI 0 "register_operand") 3324 (mem:DI (plus:DI (match_dup 0) 3325 (match_operand:DI 1 "const_int_operand"))))] 3326 "TARGET_64BIT && TARGET_MIPS16 && reload_completed 3327 && !TARGET_DEBUG_D_MODE 3328 && REG_P (operands[0]) 3329 && M16_REG_P (REGNO (operands[0])) 3330 && GET_CODE (operands[1]) == CONST_INT 3331 && ((INTVAL (operands[1]) < 0 3332 && INTVAL (operands[1]) >= -0x10) 3333 || (INTVAL (operands[1]) >= 32 * 8 3334 && INTVAL (operands[1]) <= 31 * 8 + 0x8) 3335 || (INTVAL (operands[1]) >= 0 3336 && INTVAL (operands[1]) < 32 * 8 3337 && (INTVAL (operands[1]) & 7) != 0))" 3338 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1))) 3339 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))] 3340{ 3341 HOST_WIDE_INT val = INTVAL (operands[1]); 3342 3343 if (val < 0) 3344 operands[2] = const0_rtx; 3345 else if (val >= 32 * 8) 3346 { 3347 int off = val & 7; 3348 3349 operands[1] = GEN_INT (0x8 + off); 3350 operands[2] = GEN_INT (val - off - 0x8); 3351 } 3352 else 3353 { 3354 int off = val & 7; 3355 3356 operands[1] = GEN_INT (off); 3357 operands[2] = GEN_INT (val - off); 3358 } 3359}) 3360 3361;; 32-bit Integer moves 3362 3363;; Unlike most other insns, the move insns can't be split with 3364;; different predicates, because register spilling and other parts of 3365;; the compiler, have memoized the insn number already. 3366 3367(define_expand "movsi" 3368 [(set (match_operand:SI 0 "") 3369 (match_operand:SI 1 ""))] 3370 "" 3371{ 3372 if (mips_legitimize_move (SImode, operands[0], operands[1])) 3373 DONE; 3374}) 3375 3376;; The difference between these two is whether or not ints are allowed 3377;; in FP registers (off by default, use -mdebugh to enable). 3378 3379(define_insn "*movsi_internal" 3380 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*a,*d,*B*C*D,*B*C*D,*d,*m") 3381 (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,*J*d,*A,*d,*m,*B*C*D,*B*C*D"))] 3382 "!TARGET_MIPS16 3383 && (register_operand (operands[0], SImode) 3384 || reg_or_0_operand (operands[1], SImode))" 3385 { return mips_output_move (operands[0], operands[1]); } 3386 [(set_attr "type" "arith,const,const,load,store,fmove,xfer,fpload,xfer,fpstore,xfer,xfer,mthilo,mfhilo,xfer,load,xfer,store") 3387 (set_attr "mode" "SI") 3388 (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,*,4,*")]) 3389 3390(define_insn "*movsi_mips16" 3391 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m") 3392 (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d"))] 3393 "TARGET_MIPS16 3394 && (register_operand (operands[0], SImode) 3395 || register_operand (operands[1], SImode))" 3396 { return mips_output_move (operands[0], operands[1]); } 3397 [(set_attr "type" "arith,arith,arith,arith,arith,const,load,store") 3398 (set_attr "mode" "SI") 3399 (set_attr_alternative "length" 3400 [(const_int 4) 3401 (const_int 4) 3402 (const_int 4) 3403 (if_then_else (match_operand:VOID 1 "m16_uimm8_1") 3404 (const_int 4) 3405 (const_int 8)) 3406 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1") 3407 (const_int 8) 3408 (const_int 12)) 3409 (const_string "*") 3410 (const_string "*") 3411 (const_string "*")])]) 3412 3413;; On the mips16, we can split lw $r,N($r) into an add and a load, 3414;; when the original load is a 4 byte instruction but the add and the 3415;; load are 2 2 byte instructions. 3416 3417(define_split 3418 [(set (match_operand:SI 0 "register_operand") 3419 (mem:SI (plus:SI (match_dup 0) 3420 (match_operand:SI 1 "const_int_operand"))))] 3421 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE 3422 && REG_P (operands[0]) 3423 && M16_REG_P (REGNO (operands[0])) 3424 && GET_CODE (operands[1]) == CONST_INT 3425 && ((INTVAL (operands[1]) < 0 3426 && INTVAL (operands[1]) >= -0x80) 3427 || (INTVAL (operands[1]) >= 32 * 4 3428 && INTVAL (operands[1]) <= 31 * 4 + 0x7c) 3429 || (INTVAL (operands[1]) >= 0 3430 && INTVAL (operands[1]) < 32 * 4 3431 && (INTVAL (operands[1]) & 3) != 0))" 3432 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) 3433 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))] 3434{ 3435 HOST_WIDE_INT val = INTVAL (operands[1]); 3436 3437 if (val < 0) 3438 operands[2] = const0_rtx; 3439 else if (val >= 32 * 4) 3440 { 3441 int off = val & 3; 3442 3443 operands[1] = GEN_INT (0x7c + off); 3444 operands[2] = GEN_INT (val - off - 0x7c); 3445 } 3446 else 3447 { 3448 int off = val & 3; 3449 3450 operands[1] = GEN_INT (off); 3451 operands[2] = GEN_INT (val - off); 3452 } 3453}) 3454 3455;; On the mips16, we can split a load of certain constants into a load 3456;; and an add. This turns a 4 byte instruction into 2 2 byte 3457;; instructions. 3458 3459(define_split 3460 [(set (match_operand:SI 0 "register_operand") 3461 (match_operand:SI 1 "const_int_operand"))] 3462 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE 3463 && REG_P (operands[0]) 3464 && M16_REG_P (REGNO (operands[0])) 3465 && GET_CODE (operands[1]) == CONST_INT 3466 && INTVAL (operands[1]) >= 0x100 3467 && INTVAL (operands[1]) <= 0xff + 0x7f" 3468 [(set (match_dup 0) (match_dup 1)) 3469 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))] 3470{ 3471 int val = INTVAL (operands[1]); 3472 3473 operands[1] = GEN_INT (0xff); 3474 operands[2] = GEN_INT (val - 0xff); 3475}) 3476 3477;; This insn handles moving CCmode values. It's really just a 3478;; slightly simplified copy of movsi_internal2, with additional cases 3479;; to move a condition register to a general register and to move 3480;; between the general registers and the floating point registers. 3481 3482(define_insn "movcc" 3483 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m") 3484 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))] 3485 "ISA_HAS_8CC && TARGET_HARD_FLOAT" 3486 { return mips_output_move (operands[0], operands[1]); } 3487 [(set_attr "type" "xfer,arith,load,store,xfer,xfer,fmove,fpload,fpstore") 3488 (set_attr "mode" "SI") 3489 (set_attr "length" "8,4,*,*,4,4,4,*,*")]) 3490 3491;; Reload condition code registers. reload_incc and reload_outcc 3492;; both handle moves from arbitrary operands into condition code 3493;; registers. reload_incc handles the more common case in which 3494;; a source operand is constrained to be in a condition-code 3495;; register, but has not been allocated to one. 3496;; 3497;; Sometimes, such as in movcc, we have a CCmode destination whose 3498;; constraints do not include 'z'. reload_outcc handles the case 3499;; when such an operand is allocated to a condition-code register. 3500;; 3501;; Note that reloads from a condition code register to some 3502;; other location can be done using ordinary moves. Moving 3503;; into a GPR takes a single movcc, moving elsewhere takes 3504;; two. We can leave these cases to the generic reload code. 3505(define_expand "reload_incc" 3506 [(set (match_operand:CC 0 "fcc_reload_operand" "=z") 3507 (match_operand:CC 1 "general_operand" "")) 3508 (clobber (match_operand:TF 2 "register_operand" "=&f"))] 3509 "ISA_HAS_8CC && TARGET_HARD_FLOAT" 3510{ 3511 mips_emit_fcc_reload (operands[0], operands[1], operands[2]); 3512 DONE; 3513}) 3514 3515(define_expand "reload_outcc" 3516 [(set (match_operand:CC 0 "fcc_reload_operand" "=z") 3517 (match_operand:CC 1 "register_operand" "")) 3518 (clobber (match_operand:TF 2 "register_operand" "=&f"))] 3519 "ISA_HAS_8CC && TARGET_HARD_FLOAT" 3520{ 3521 mips_emit_fcc_reload (operands[0], operands[1], operands[2]); 3522 DONE; 3523}) 3524 3525;; MIPS4 supports loading and storing a floating point register from 3526;; the sum of two general registers. We use two versions for each of 3527;; these four instructions: one where the two general registers are 3528;; SImode, and one where they are DImode. This is because general 3529;; registers will be in SImode when they hold 32 bit values, but, 3530;; since the 32 bit values are always sign extended, the [ls][wd]xc1 3531;; instructions will still work correctly. 3532 3533;; ??? Perhaps it would be better to support these instructions by 3534;; modifying GO_IF_LEGITIMATE_ADDRESS and friends. However, since 3535;; these instructions can only be used to load and store floating 3536;; point registers, that would probably cause trouble in reload. 3537 3538(define_insn "*<ANYF:loadx>_<P:mode>" 3539 [(set (match_operand:ANYF 0 "register_operand" "=f") 3540 (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d") 3541 (match_operand:P 2 "register_operand" "d"))))] 3542 "ISA_HAS_FP4" 3543 "<ANYF:loadx>\t%0,%1(%2)" 3544 [(set_attr "type" "fpidxload") 3545 (set_attr "mode" "<ANYF:UNITMODE>")]) 3546 3547(define_insn "*<ANYF:storex>_<P:mode>" 3548 [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d") 3549 (match_operand:P 2 "register_operand" "d"))) 3550 (match_operand:ANYF 0 "register_operand" "f"))] 3551 "ISA_HAS_FP4" 3552 "<ANYF:storex>\t%0,%1(%2)" 3553 [(set_attr "type" "fpidxstore") 3554 (set_attr "mode" "<ANYF:UNITMODE>")]) 3555 3556;; 16-bit Integer moves 3557 3558;; Unlike most other insns, the move insns can't be split with 3559;; different predicates, because register spilling and other parts of 3560;; the compiler, have memoized the insn number already. 3561;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND. 3562 3563(define_expand "movhi" 3564 [(set (match_operand:HI 0 "") 3565 (match_operand:HI 1 ""))] 3566 "" 3567{ 3568 if (mips_legitimize_move (HImode, operands[0], operands[1])) 3569 DONE; 3570}) 3571 3572(define_insn "*movhi_internal" 3573 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x") 3574 (match_operand:HI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))] 3575 "!TARGET_MIPS16 3576 && (register_operand (operands[0], HImode) 3577 || reg_or_0_operand (operands[1], HImode))" 3578 "@ 3579 move\t%0,%1 3580 li\t%0,%1 3581 lhu\t%0,%1 3582 sh\t%z1,%0 3583 mfc1\t%0,%1 3584 mtc1\t%1,%0 3585 mov.s\t%0,%1 3586 mt%0\t%1" 3587 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo") 3588 (set_attr "mode" "HI") 3589 (set_attr "length" "4,4,*,*,4,4,4,4")]) 3590 3591(define_insn "*movhi_mips16" 3592 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m") 3593 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d"))] 3594 "TARGET_MIPS16 3595 && (register_operand (operands[0], HImode) 3596 || register_operand (operands[1], HImode))" 3597 "@ 3598 move\t%0,%1 3599 move\t%0,%1 3600 move\t%0,%1 3601 li\t%0,%1 3602 # 3603 lhu\t%0,%1 3604 sh\t%1,%0" 3605 [(set_attr "type" "arith,arith,arith,arith,arith,load,store") 3606 (set_attr "mode" "HI") 3607 (set_attr_alternative "length" 3608 [(const_int 4) 3609 (const_int 4) 3610 (const_int 4) 3611 (if_then_else (match_operand:VOID 1 "m16_uimm8_1") 3612 (const_int 4) 3613 (const_int 8)) 3614 (if_then_else (match_operand:VOID 1 "m16_nuimm8_1") 3615 (const_int 8) 3616 (const_int 12)) 3617 (const_string "*") 3618 (const_string "*")])]) 3619 3620 3621;; On the mips16, we can split lh $r,N($r) into an add and a load, 3622;; when the original load is a 4 byte instruction but the add and the 3623;; load are 2 2 byte instructions. 3624 3625(define_split 3626 [(set (match_operand:HI 0 "register_operand") 3627 (mem:HI (plus:SI (match_dup 0) 3628 (match_operand:SI 1 "const_int_operand"))))] 3629 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE 3630 && REG_P (operands[0]) 3631 && M16_REG_P (REGNO (operands[0])) 3632 && GET_CODE (operands[1]) == CONST_INT 3633 && ((INTVAL (operands[1]) < 0 3634 && INTVAL (operands[1]) >= -0x80) 3635 || (INTVAL (operands[1]) >= 32 * 2 3636 && INTVAL (operands[1]) <= 31 * 2 + 0x7e) 3637 || (INTVAL (operands[1]) >= 0 3638 && INTVAL (operands[1]) < 32 * 2 3639 && (INTVAL (operands[1]) & 1) != 0))" 3640 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) 3641 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))] 3642{ 3643 HOST_WIDE_INT val = INTVAL (operands[1]); 3644 3645 if (val < 0) 3646 operands[2] = const0_rtx; 3647 else if (val >= 32 * 2) 3648 { 3649 int off = val & 1; 3650 3651 operands[1] = GEN_INT (0x7e + off); 3652 operands[2] = GEN_INT (val - off - 0x7e); 3653 } 3654 else 3655 { 3656 int off = val & 1; 3657 3658 operands[1] = GEN_INT (off); 3659 operands[2] = GEN_INT (val - off); 3660 } 3661}) 3662 3663;; 8-bit Integer moves 3664 3665;; Unlike most other insns, the move insns can't be split with 3666;; different predicates, because register spilling and other parts of 3667;; the compiler, have memoized the insn number already. 3668;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND. 3669 3670(define_expand "movqi" 3671 [(set (match_operand:QI 0 "") 3672 (match_operand:QI 1 ""))] 3673 "" 3674{ 3675 if (mips_legitimize_move (QImode, operands[0], operands[1])) 3676 DONE; 3677}) 3678 3679(define_insn "*movqi_internal" 3680 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*f,*x") 3681 (match_operand:QI 1 "move_operand" "d,I,m,dJ,*f,*d,*f,*d"))] 3682 "!TARGET_MIPS16 3683 && (register_operand (operands[0], QImode) 3684 || reg_or_0_operand (operands[1], QImode))" 3685 "@ 3686 move\t%0,%1 3687 li\t%0,%1 3688 lbu\t%0,%1 3689 sb\t%z1,%0 3690 mfc1\t%0,%1 3691 mtc1\t%1,%0 3692 mov.s\t%0,%1 3693 mt%0\t%1" 3694 [(set_attr "type" "arith,arith,load,store,xfer,xfer,fmove,mthilo") 3695 (set_attr "mode" "QI") 3696 (set_attr "length" "4,4,*,*,4,4,4,4")]) 3697 3698(define_insn "*movqi_mips16" 3699 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m") 3700 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d"))] 3701 "TARGET_MIPS16 3702 && (register_operand (operands[0], QImode) 3703 || register_operand (operands[1], QImode))" 3704 "@ 3705 move\t%0,%1 3706 move\t%0,%1 3707 move\t%0,%1 3708 li\t%0,%1 3709 # 3710 lbu\t%0,%1 3711 sb\t%1,%0" 3712 [(set_attr "type" "arith,arith,arith,arith,arith,load,store") 3713 (set_attr "mode" "QI") 3714 (set_attr "length" "4,4,4,4,8,*,*")]) 3715 3716;; On the mips16, we can split lb $r,N($r) into an add and a load, 3717;; when the original load is a 4 byte instruction but the add and the 3718;; load are 2 2 byte instructions. 3719 3720(define_split 3721 [(set (match_operand:QI 0 "register_operand") 3722 (mem:QI (plus:SI (match_dup 0) 3723 (match_operand:SI 1 "const_int_operand"))))] 3724 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE 3725 && REG_P (operands[0]) 3726 && M16_REG_P (REGNO (operands[0])) 3727 && GET_CODE (operands[1]) == CONST_INT 3728 && ((INTVAL (operands[1]) < 0 3729 && INTVAL (operands[1]) >= -0x80) 3730 || (INTVAL (operands[1]) >= 32 3731 && INTVAL (operands[1]) <= 31 + 0x7f))" 3732 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) 3733 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))] 3734{ 3735 HOST_WIDE_INT val = INTVAL (operands[1]); 3736 3737 if (val < 0) 3738 operands[2] = const0_rtx; 3739 else 3740 { 3741 operands[1] = GEN_INT (0x7f); 3742 operands[2] = GEN_INT (val - 0x7f); 3743 } 3744}) 3745 3746;; 32-bit floating point moves 3747 3748(define_expand "movsf" 3749 [(set (match_operand:SF 0 "") 3750 (match_operand:SF 1 ""))] 3751 "" 3752{ 3753 if (mips_legitimize_move (SFmode, operands[0], operands[1])) 3754 DONE; 3755}) 3756 3757(define_insn "*movsf_hardfloat" 3758 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m") 3759 (match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))] 3760 "TARGET_HARD_FLOAT 3761 && (register_operand (operands[0], SFmode) 3762 || reg_or_0_operand (operands[1], SFmode))" 3763 { return mips_output_move (operands[0], operands[1]); } 3764 [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store") 3765 (set_attr "mode" "SF") 3766 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")]) 3767 3768(define_insn "*movsf_softfloat" 3769 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m") 3770 (match_operand:SF 1 "move_operand" "Gd,m,d"))] 3771 "TARGET_SOFT_FLOAT && !TARGET_MIPS16 3772 && (register_operand (operands[0], SFmode) 3773 || reg_or_0_operand (operands[1], SFmode))" 3774 { return mips_output_move (operands[0], operands[1]); } 3775 [(set_attr "type" "arith,load,store") 3776 (set_attr "mode" "SF") 3777 (set_attr "length" "4,*,*")]) 3778 3779(define_insn "*movsf_mips16" 3780 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m") 3781 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))] 3782 "TARGET_MIPS16 3783 && (register_operand (operands[0], SFmode) 3784 || register_operand (operands[1], SFmode))" 3785 { return mips_output_move (operands[0], operands[1]); } 3786 [(set_attr "type" "arith,arith,arith,load,store") 3787 (set_attr "mode" "SF") 3788 (set_attr "length" "4,4,4,*,*")]) 3789 3790 3791;; 64-bit floating point moves 3792 3793(define_expand "movdf" 3794 [(set (match_operand:DF 0 "") 3795 (match_operand:DF 1 ""))] 3796 "" 3797{ 3798 if (mips_legitimize_move (DFmode, operands[0], operands[1])) 3799 DONE; 3800}) 3801 3802(define_insn "*movdf_hardfloat_64bit" 3803 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m") 3804 (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))] 3805 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT 3806 && (register_operand (operands[0], DFmode) 3807 || reg_or_0_operand (operands[1], DFmode))" 3808 { return mips_output_move (operands[0], operands[1]); } 3809 [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store") 3810 (set_attr "mode" "DF") 3811 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")]) 3812 3813(define_insn "*movdf_hardfloat_32bit" 3814 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m") 3815 (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))] 3816 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT 3817 && (register_operand (operands[0], DFmode) 3818 || reg_or_0_operand (operands[1], DFmode))" 3819 { return mips_output_move (operands[0], operands[1]); } 3820 [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store") 3821 (set_attr "mode" "DF") 3822 (set_attr "length" "4,8,*,*,*,8,8,8,*,*")]) 3823 3824(define_insn "*movdf_softfloat" 3825 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f") 3826 (match_operand:DF 1 "move_operand" "dG,m,dG,f,d,f"))] 3827 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16 3828 && (register_operand (operands[0], DFmode) 3829 || reg_or_0_operand (operands[1], DFmode))" 3830 { return mips_output_move (operands[0], operands[1]); } 3831 [(set_attr "type" "arith,load,store,xfer,xfer,fmove") 3832 (set_attr "mode" "DF") 3833 (set_attr "length" "8,*,*,4,4,4")]) 3834 3835(define_insn "*movdf_mips16" 3836 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m") 3837 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))] 3838 "TARGET_MIPS16 3839 && (register_operand (operands[0], DFmode) 3840 || register_operand (operands[1], DFmode))" 3841 { return mips_output_move (operands[0], operands[1]); } 3842 [(set_attr "type" "arith,arith,arith,load,store") 3843 (set_attr "mode" "DF") 3844 (set_attr "length" "8,8,8,*,*")]) 3845 3846(define_split 3847 [(set (match_operand:DI 0 "nonimmediate_operand") 3848 (match_operand:DI 1 "move_operand"))] 3849 "reload_completed && !TARGET_64BIT 3850 && mips_split_64bit_move_p (operands[0], operands[1])" 3851 [(const_int 0)] 3852{ 3853 mips_split_64bit_move (operands[0], operands[1]); 3854 DONE; 3855}) 3856 3857(define_split 3858 [(set (match_operand:DF 0 "nonimmediate_operand") 3859 (match_operand:DF 1 "move_operand"))] 3860 "reload_completed && !TARGET_64BIT 3861 && mips_split_64bit_move_p (operands[0], operands[1])" 3862 [(const_int 0)] 3863{ 3864 mips_split_64bit_move (operands[0], operands[1]); 3865 DONE; 3866}) 3867 3868;; When generating mips16 code, split moves of negative constants into 3869;; a positive "li" followed by a negation. 3870(define_split 3871 [(set (match_operand 0 "register_operand") 3872 (match_operand 1 "const_int_operand"))] 3873 "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0" 3874 [(set (match_dup 2) 3875 (match_dup 3)) 3876 (set (match_dup 2) 3877 (neg:SI (match_dup 2)))] 3878{ 3879 operands[2] = gen_lowpart (SImode, operands[0]); 3880 operands[3] = GEN_INT (-INTVAL (operands[1])); 3881}) 3882 3883;; 64-bit paired-single floating point moves 3884 3885(define_expand "movv2sf" 3886 [(set (match_operand:V2SF 0) 3887 (match_operand:V2SF 1))] 3888 "TARGET_PAIRED_SINGLE_FLOAT" 3889{ 3890 if (mips_legitimize_move (V2SFmode, operands[0], operands[1])) 3891 DONE; 3892}) 3893 3894(define_insn "movv2sf_hardfloat_64bit" 3895 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m") 3896 (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))] 3897 "TARGET_PAIRED_SINGLE_FLOAT 3898 && TARGET_64BIT 3899 && (register_operand (operands[0], V2SFmode) 3900 || reg_or_0_operand (operands[1], V2SFmode))" 3901 { return mips_output_move (operands[0], operands[1]); } 3902 [(set_attr "type" "fmove,xfer,fpload,fpstore,store,xfer,xfer,arith,load,store") 3903 (set_attr "mode" "SF") 3904 (set_attr "length" "4,4,*,*,*,4,4,4,*,*")]) 3905 3906;; The HI and LO registers are not truly independent. If we move an mthi 3907;; instruction before an mflo instruction, it will make the result of the 3908;; mflo unpredictable. The same goes for mtlo and mfhi. 3909;; 3910;; We cope with this by making the mflo and mfhi patterns use both HI and LO. 3911;; Operand 1 is the register we want, operand 2 is the other one. 3912;; 3913;; When generating VR4120 or VR4130 code, we use macc{,hi} and 3914;; dmacc{,hi} instead of mfhi and mflo. This avoids both the normal 3915;; MIPS III hi/lo hazards and the errata related to -mfix-vr4130. 3916 3917(define_expand "mfhilo_<mode>" 3918 [(set (match_operand:GPR 0 "register_operand") 3919 (unspec:GPR [(match_operand:GPR 1 "register_operand") 3920 (match_operand:GPR 2 "register_operand")] 3921 UNSPEC_MFHILO))]) 3922 3923(define_insn "*mfhilo_<mode>" 3924 [(set (match_operand:GPR 0 "register_operand" "=d,d") 3925 (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l") 3926 (match_operand:GPR 2 "register_operand" "l,h")] 3927 UNSPEC_MFHILO))] 3928 "!ISA_HAS_MACCHI" 3929 "mf%1\t%0" 3930 [(set_attr "type" "mfhilo") 3931 (set_attr "mode" "<MODE>")]) 3932 3933(define_insn "*mfhilo_<mode>_macc" 3934 [(set (match_operand:GPR 0 "register_operand" "=d,d") 3935 (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l") 3936 (match_operand:GPR 2 "register_operand" "l,h")] 3937 UNSPEC_MFHILO))] 3938 "ISA_HAS_MACCHI" 3939{ 3940 if (REGNO (operands[1]) == HI_REGNUM) 3941 return "<d>macchi\t%0,%.,%."; 3942 else 3943 return "<d>macc\t%0,%.,%."; 3944} 3945 [(set_attr "type" "mfhilo") 3946 (set_attr "mode" "<MODE>")]) 3947 3948;; Patterns for loading or storing part of a paired floating point 3949;; register. We need them because odd-numbered floating-point registers 3950;; are not fully independent: see mips_split_64bit_move. 3951 3952;; Load the low word of operand 0 with operand 1. 3953(define_insn "load_df_low" 3954 [(set (match_operand:DF 0 "register_operand" "=f,f") 3955 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")] 3956 UNSPEC_LOAD_DF_LOW))] 3957 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT" 3958{ 3959 operands[0] = mips_subword (operands[0], 0); 3960 return mips_output_move (operands[0], operands[1]); 3961} 3962 [(set_attr "type" "xfer,fpload") 3963 (set_attr "mode" "SF")]) 3964 3965;; Load the high word of operand 0 from operand 1, preserving the value 3966;; in the low word. 3967(define_insn "load_df_high" 3968 [(set (match_operand:DF 0 "register_operand" "=f,f") 3969 (unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m") 3970 (match_operand:DF 2 "register_operand" "0,0")] 3971 UNSPEC_LOAD_DF_HIGH))] 3972 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT" 3973{ 3974 operands[0] = mips_subword (operands[0], 1); 3975 return mips_output_move (operands[0], operands[1]); 3976} 3977 [(set_attr "type" "xfer,fpload") 3978 (set_attr "mode" "SF")]) 3979 3980;; Store the high word of operand 1 in operand 0. The corresponding 3981;; low-word move is done in the normal way. 3982(define_insn "store_df_high" 3983 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m") 3984 (unspec:SI [(match_operand:DF 1 "register_operand" "f,f")] 3985 UNSPEC_STORE_DF_HIGH))] 3986 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT" 3987{ 3988 operands[1] = mips_subword (operands[1], 1); 3989 return mips_output_move (operands[0], operands[1]); 3990} 3991 [(set_attr "type" "xfer,fpstore") 3992 (set_attr "mode" "SF")]) 3993 3994;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset 3995;; of _gp from the start of this function. Operand 1 is the incoming 3996;; function address. 3997(define_insn_and_split "loadgp" 3998 [(unspec_volatile [(match_operand 0 "" "") 3999 (match_operand 1 "register_operand" "")] UNSPEC_LOADGP)] 4000 "mips_current_loadgp_style () == LOADGP_NEWABI" 4001 "#" 4002 "" 4003 [(set (match_dup 2) (match_dup 3)) 4004 (set (match_dup 2) (match_dup 4)) 4005 (set (match_dup 2) (match_dup 5))] 4006{ 4007 operands[2] = pic_offset_table_rtx; 4008 operands[3] = gen_rtx_HIGH (Pmode, operands[0]); 4009 operands[4] = gen_rtx_PLUS (Pmode, operands[2], operands[1]); 4010 operands[5] = gen_rtx_LO_SUM (Pmode, operands[2], operands[0]); 4011} 4012 [(set_attr "length" "12")]) 4013 4014;; Likewise, for -mno-shared code. Operand 0 is the __gnu_local_gp symbol. 4015(define_insn_and_split "loadgp_noshared" 4016 [(unspec_volatile [(match_operand 0 "" "")] UNSPEC_LOADGP)] 4017 "mips_current_loadgp_style () == LOADGP_ABSOLUTE" 4018 "#" 4019 "" 4020 [(const_int 0)] 4021{ 4022 emit_move_insn (pic_offset_table_rtx, operands[0]); 4023 DONE; 4024} 4025 [(set_attr "length" "8")]) 4026 4027;; The use of gp is hidden when not using explicit relocations. 4028;; This blockage instruction prevents the gp load from being 4029;; scheduled after an implicit use of gp. It also prevents 4030;; the load from being deleted as dead. 4031(define_insn "loadgp_blockage" 4032 [(unspec_volatile [(reg:DI 28)] UNSPEC_BLOCKAGE)] 4033 "" 4034 "" 4035 [(set_attr "type" "unknown") 4036 (set_attr "mode" "none") 4037 (set_attr "length" "0")]) 4038 4039;; Emit a .cprestore directive, which normally expands to a single store 4040;; instruction. Note that we continue to use .cprestore for explicit reloc 4041;; code so that jals inside inline asms will work correctly. 4042(define_insn "cprestore" 4043 [(unspec_volatile [(match_operand 0 "const_int_operand" "I,i")] 4044 UNSPEC_CPRESTORE)] 4045 "" 4046{ 4047 if (set_nomacro && which_alternative == 1) 4048 return ".set\tmacro\;.cprestore\t%0\;.set\tnomacro"; 4049 else 4050 return ".cprestore\t%0"; 4051} 4052 [(set_attr "type" "store") 4053 (set_attr "length" "4,12")]) 4054 4055;; Block moves, see mips.c for more details. 4056;; Argument 0 is the destination 4057;; Argument 1 is the source 4058;; Argument 2 is the length 4059;; Argument 3 is the alignment 4060 4061(define_expand "movmemsi" 4062 [(parallel [(set (match_operand:BLK 0 "general_operand") 4063 (match_operand:BLK 1 "general_operand")) 4064 (use (match_operand:SI 2 "")) 4065 (use (match_operand:SI 3 "const_int_operand"))])] 4066 "!TARGET_MIPS16 && !TARGET_MEMCPY" 4067{ 4068 if (mips_expand_block_move (operands[0], operands[1], operands[2])) 4069 DONE; 4070 else 4071 FAIL; 4072}) 4073 4074;; 4075;; .................... 4076;; 4077;; SHIFTS 4078;; 4079;; .................... 4080 4081(define_expand "<optab><mode>3" 4082 [(set (match_operand:GPR 0 "register_operand") 4083 (any_shift:GPR (match_operand:GPR 1 "register_operand") 4084 (match_operand:SI 2 "arith_operand")))] 4085 "" 4086{ 4087 /* On the mips16, a shift of more than 8 is a four byte instruction, 4088 so, for a shift between 8 and 16, it is just as fast to do two 4089 shifts of 8 or less. If there is a lot of shifting going on, we 4090 may win in CSE. Otherwise combine will put the shifts back 4091 together again. This can be called by function_arg, so we must 4092 be careful not to allocate a new register if we've reached the 4093 reload pass. */ 4094 if (TARGET_MIPS16 4095 && optimize 4096 && GET_CODE (operands[2]) == CONST_INT 4097 && INTVAL (operands[2]) > 8 4098 && INTVAL (operands[2]) <= 16 4099 && !reload_in_progress 4100 && !reload_completed) 4101 { 4102 rtx temp = gen_reg_rtx (<MODE>mode); 4103 4104 emit_insn (gen_<optab><mode>3 (temp, operands[1], GEN_INT (8))); 4105 emit_insn (gen_<optab><mode>3 (operands[0], temp, 4106 GEN_INT (INTVAL (operands[2]) - 8))); 4107 DONE; 4108 } 4109}) 4110 4111(define_insn "*<optab><mode>3" 4112 [(set (match_operand:GPR 0 "register_operand" "=d") 4113 (any_shift:GPR (match_operand:GPR 1 "register_operand" "d") 4114 (match_operand:SI 2 "arith_operand" "dI")))] 4115 "!TARGET_MIPS16" 4116{ 4117 if (GET_CODE (operands[2]) == CONST_INT) 4118 operands[2] = GEN_INT (INTVAL (operands[2]) 4119 & (GET_MODE_BITSIZE (<MODE>mode) - 1)); 4120 4121 return "<d><insn>\t%0,%1,%2"; 4122} 4123 [(set_attr "type" "shift") 4124 (set_attr "mode" "<MODE>")]) 4125 4126(define_insn "*<optab>si3_extend" 4127 [(set (match_operand:DI 0 "register_operand" "=d") 4128 (sign_extend:DI 4129 (any_shift:SI (match_operand:SI 1 "register_operand" "d") 4130 (match_operand:SI 2 "arith_operand" "dI"))))] 4131 "TARGET_64BIT && !TARGET_MIPS16" 4132{ 4133 if (GET_CODE (operands[2]) == CONST_INT) 4134 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); 4135 4136 return "<insn>\t%0,%1,%2"; 4137} 4138 [(set_attr "type" "shift") 4139 (set_attr "mode" "SI")]) 4140 4141(define_insn "*<optab>si3_mips16" 4142 [(set (match_operand:SI 0 "register_operand" "=d,d") 4143 (any_shift:SI (match_operand:SI 1 "register_operand" "0,d") 4144 (match_operand:SI 2 "arith_operand" "d,I")))] 4145 "TARGET_MIPS16" 4146{ 4147 if (which_alternative == 0) 4148 return "<insn>\t%0,%2"; 4149 4150 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); 4151 return "<insn>\t%0,%1,%2"; 4152} 4153 [(set_attr "type" "shift") 4154 (set_attr "mode" "SI") 4155 (set_attr_alternative "length" 4156 [(const_int 4) 4157 (if_then_else (match_operand 2 "m16_uimm3_b") 4158 (const_int 4) 4159 (const_int 8))])]) 4160 4161;; We need separate DImode MIPS16 patterns because of the irregularity 4162;; of right shifts. 4163(define_insn "*ashldi3_mips16" 4164 [(set (match_operand:DI 0 "register_operand" "=d,d") 4165 (ashift:DI (match_operand:DI 1 "register_operand" "0,d") 4166 (match_operand:SI 2 "arith_operand" "d,I")))] 4167 "TARGET_64BIT && TARGET_MIPS16" 4168{ 4169 if (which_alternative == 0) 4170 return "dsll\t%0,%2"; 4171 4172 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); 4173 return "dsll\t%0,%1,%2"; 4174} 4175 [(set_attr "type" "shift") 4176 (set_attr "mode" "DI") 4177 (set_attr_alternative "length" 4178 [(const_int 4) 4179 (if_then_else (match_operand 2 "m16_uimm3_b") 4180 (const_int 4) 4181 (const_int 8))])]) 4182 4183(define_insn "*ashrdi3_mips16" 4184 [(set (match_operand:DI 0 "register_operand" "=d,d") 4185 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0") 4186 (match_operand:SI 2 "arith_operand" "d,I")))] 4187 "TARGET_64BIT && TARGET_MIPS16" 4188{ 4189 if (GET_CODE (operands[2]) == CONST_INT) 4190 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); 4191 4192 return "dsra\t%0,%2"; 4193} 4194 [(set_attr "type" "shift") 4195 (set_attr "mode" "DI") 4196 (set_attr_alternative "length" 4197 [(const_int 4) 4198 (if_then_else (match_operand 2 "m16_uimm3_b") 4199 (const_int 4) 4200 (const_int 8))])]) 4201 4202(define_insn "*lshrdi3_mips16" 4203 [(set (match_operand:DI 0 "register_operand" "=d,d") 4204 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0") 4205 (match_operand:SI 2 "arith_operand" "d,I")))] 4206 "TARGET_64BIT && TARGET_MIPS16" 4207{ 4208 if (GET_CODE (operands[2]) == CONST_INT) 4209 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); 4210 4211 return "dsrl\t%0,%2"; 4212} 4213 [(set_attr "type" "shift") 4214 (set_attr "mode" "DI") 4215 (set_attr_alternative "length" 4216 [(const_int 4) 4217 (if_then_else (match_operand 2 "m16_uimm3_b") 4218 (const_int 4) 4219 (const_int 8))])]) 4220 4221;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts. 4222 4223(define_split 4224 [(set (match_operand:GPR 0 "register_operand") 4225 (any_shift:GPR (match_operand:GPR 1 "register_operand") 4226 (match_operand:GPR 2 "const_int_operand")))] 4227 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE 4228 && GET_CODE (operands[2]) == CONST_INT 4229 && INTVAL (operands[2]) > 8 4230 && INTVAL (operands[2]) <= 16" 4231 [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8))) 4232 (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))] 4233 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); }) 4234 4235;; If we load a byte on the mips16 as a bitfield, the resulting 4236;; sequence of instructions is too complicated for combine, because it 4237;; involves four instructions: a load, a shift, a constant load into a 4238;; register, and an and (the key problem here is that the mips16 does 4239;; not have and immediate). We recognize a shift of a load in order 4240;; to make it simple enough for combine to understand. 4241;; 4242;; The length here is the worst case: the length of the split version 4243;; will be more accurate. 4244(define_insn_and_split "" 4245 [(set (match_operand:SI 0 "register_operand" "=d") 4246 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") 4247 (match_operand:SI 2 "immediate_operand" "I")))] 4248 "TARGET_MIPS16" 4249 "#" 4250 "" 4251 [(set (match_dup 0) (match_dup 1)) 4252 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))] 4253 "" 4254 [(set_attr "type" "load") 4255 (set_attr "mode" "SI") 4256 (set_attr "length" "16")]) 4257 4258(define_insn "rotr<mode>3" 4259 [(set (match_operand:GPR 0 "register_operand" "=d") 4260 (rotatert:GPR (match_operand:GPR 1 "register_operand" "d") 4261 (match_operand:SI 2 "arith_operand" "dI")))] 4262 "ISA_HAS_ROTR_<MODE>" 4263{ 4264 if (GET_CODE (operands[2]) == CONST_INT) 4265 gcc_assert (INTVAL (operands[2]) >= 0 4266 && INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)); 4267 4268 return "<d>ror\t%0,%1,%2"; 4269} 4270 [(set_attr "type" "shift") 4271 (set_attr "mode" "<MODE>")]) 4272 4273;; 4274;; .................... 4275;; 4276;; COMPARISONS 4277;; 4278;; .................... 4279 4280;; Flow here is rather complex: 4281;; 4282;; 1) The cmp{si,di,sf,df} routine is called. It deposits the arguments 4283;; into cmp_operands[] but generates no RTL. 4284;; 4285;; 2) The appropriate branch define_expand is called, which then 4286;; creates the appropriate RTL for the comparison and branch. 4287;; Different CC modes are used, based on what type of branch is 4288;; done, so that we can constrain things appropriately. There 4289;; are assumptions in the rest of GCC that break if we fold the 4290;; operands into the branches for integer operations, and use cc0 4291;; for floating point, so we use the fp status register instead. 4292;; If needed, an appropriate temporary is created to hold the 4293;; of the integer compare. 4294 4295(define_expand "cmp<mode>" 4296 [(set (cc0) 4297 (compare:CC (match_operand:GPR 0 "register_operand") 4298 (match_operand:GPR 1 "nonmemory_operand")))] 4299 "" 4300{ 4301 cmp_operands[0] = operands[0]; 4302 cmp_operands[1] = operands[1]; 4303 DONE; 4304}) 4305 4306(define_expand "cmp<mode>" 4307 [(set (cc0) 4308 (compare:CC (match_operand:SCALARF 0 "register_operand") 4309 (match_operand:SCALARF 1 "register_operand")))] 4310 "" 4311{ 4312 cmp_operands[0] = operands[0]; 4313 cmp_operands[1] = operands[1]; 4314 DONE; 4315}) 4316 4317;; 4318;; .................... 4319;; 4320;; CONDITIONAL BRANCHES 4321;; 4322;; .................... 4323 4324;; Conditional branches on floating-point equality tests. 4325 4326(define_insn "*branch_fp" 4327 [(set (pc) 4328 (if_then_else 4329 (match_operator 0 "equality_operator" 4330 [(match_operand:CC 2 "register_operand" "z") 4331 (const_int 0)]) 4332 (label_ref (match_operand 1 "" "")) 4333 (pc)))] 4334 "TARGET_HARD_FLOAT" 4335{ 4336 return mips_output_conditional_branch (insn, operands, 4337 MIPS_BRANCH ("b%F0", "%Z2%1"), 4338 MIPS_BRANCH ("b%W0", "%Z2%1")); 4339} 4340 [(set_attr "type" "branch") 4341 (set_attr "mode" "none")]) 4342 4343(define_insn "*branch_fp_inverted" 4344 [(set (pc) 4345 (if_then_else 4346 (match_operator 0 "equality_operator" 4347 [(match_operand:CC 2 "register_operand" "z") 4348 (const_int 0)]) 4349 (pc) 4350 (label_ref (match_operand 1 "" ""))))] 4351 "TARGET_HARD_FLOAT" 4352{ 4353 return mips_output_conditional_branch (insn, operands, 4354 MIPS_BRANCH ("b%W0", "%Z2%1"), 4355 MIPS_BRANCH ("b%F0", "%Z2%1")); 4356} 4357 [(set_attr "type" "branch") 4358 (set_attr "mode" "none")]) 4359 4360;; Conditional branches on ordered comparisons with zero. 4361 4362(define_insn "*branch_order<mode>" 4363 [(set (pc) 4364 (if_then_else 4365 (match_operator 0 "order_operator" 4366 [(match_operand:GPR 2 "register_operand" "d") 4367 (const_int 0)]) 4368 (label_ref (match_operand 1 "" "")) 4369 (pc)))] 4370 "!TARGET_MIPS16" 4371 { return mips_output_order_conditional_branch (insn, operands, false); } 4372 [(set_attr "type" "branch") 4373 (set_attr "mode" "none")]) 4374 4375(define_insn "*branch_order<mode>_inverted" 4376 [(set (pc) 4377 (if_then_else 4378 (match_operator 0 "order_operator" 4379 [(match_operand:GPR 2 "register_operand" "d") 4380 (const_int 0)]) 4381 (pc) 4382 (label_ref (match_operand 1 "" ""))))] 4383 "!TARGET_MIPS16" 4384 { return mips_output_order_conditional_branch (insn, operands, true); } 4385 [(set_attr "type" "branch") 4386 (set_attr "mode" "none")]) 4387 4388;; Conditional branch on equality comparison. 4389 4390(define_insn "*branch_equality<mode>" 4391 [(set (pc) 4392 (if_then_else 4393 (match_operator 0 "equality_operator" 4394 [(match_operand:GPR 2 "register_operand" "d") 4395 (match_operand:GPR 3 "reg_or_0_operand" "dJ")]) 4396 (label_ref (match_operand 1 "" "")) 4397 (pc)))] 4398 "!TARGET_MIPS16" 4399{ 4400 return mips_output_conditional_branch (insn, operands, 4401 MIPS_BRANCH ("b%C0", "%2,%z3,%1"), 4402 MIPS_BRANCH ("b%N0", "%2,%z3,%1")); 4403} 4404 [(set_attr "type" "branch") 4405 (set_attr "mode" "none")]) 4406 4407(define_insn "*branch_equality<mode>_inverted" 4408 [(set (pc) 4409 (if_then_else 4410 (match_operator 0 "equality_operator" 4411 [(match_operand:GPR 2 "register_operand" "d") 4412 (match_operand:GPR 3 "reg_or_0_operand" "dJ")]) 4413 (pc) 4414 (label_ref (match_operand 1 "" ""))))] 4415 "!TARGET_MIPS16" 4416{ 4417 return mips_output_conditional_branch (insn, operands, 4418 MIPS_BRANCH ("b%N0", "%2,%z3,%1"), 4419 MIPS_BRANCH ("b%C0", "%2,%z3,%1")); 4420} 4421 [(set_attr "type" "branch") 4422 (set_attr "mode" "none")]) 4423 4424;; MIPS16 branches 4425 4426(define_insn "*branch_equality<mode>_mips16" 4427 [(set (pc) 4428 (if_then_else 4429 (match_operator 0 "equality_operator" 4430 [(match_operand:GPR 1 "register_operand" "d,t") 4431 (const_int 0)]) 4432 (match_operand 2 "pc_or_label_operand" "") 4433 (match_operand 3 "pc_or_label_operand" "")))] 4434 "TARGET_MIPS16" 4435{ 4436 if (operands[2] != pc_rtx) 4437 { 4438 if (which_alternative == 0) 4439 return "b%C0z\t%1,%2"; 4440 else 4441 return "bt%C0z\t%2"; 4442 } 4443 else 4444 { 4445 if (which_alternative == 0) 4446 return "b%N0z\t%1,%3"; 4447 else 4448 return "bt%N0z\t%3"; 4449 } 4450} 4451 [(set_attr "type" "branch") 4452 (set_attr "mode" "none") 4453 (set_attr "length" "8")]) 4454 4455(define_expand "b<code>" 4456 [(set (pc) 4457 (if_then_else (any_cond:CC (cc0) 4458 (const_int 0)) 4459 (label_ref (match_operand 0 "")) 4460 (pc)))] 4461 "" 4462{ 4463 gen_conditional_branch (operands, <CODE>); 4464 DONE; 4465}) 4466 4467;; Used to implement built-in functions. 4468(define_expand "condjump" 4469 [(set (pc) 4470 (if_then_else (match_operand 0) 4471 (label_ref (match_operand 1)) 4472 (pc)))]) 4473 4474;; 4475;; .................... 4476;; 4477;; SETTING A REGISTER FROM A COMPARISON 4478;; 4479;; .................... 4480 4481(define_expand "seq" 4482 [(set (match_operand:SI 0 "register_operand") 4483 (eq:SI (match_dup 1) 4484 (match_dup 2)))] 4485 "" 4486 { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; }) 4487 4488(define_insn "*seq_<mode>" 4489 [(set (match_operand:GPR 0 "register_operand" "=d") 4490 (eq:GPR (match_operand:GPR 1 "register_operand" "d") 4491 (const_int 0)))] 4492 "!TARGET_MIPS16" 4493 "sltu\t%0,%1,1" 4494 [(set_attr "type" "slt") 4495 (set_attr "mode" "<MODE>")]) 4496 4497(define_insn "*seq_<mode>_mips16" 4498 [(set (match_operand:GPR 0 "register_operand" "=t") 4499 (eq:GPR (match_operand:GPR 1 "register_operand" "d") 4500 (const_int 0)))] 4501 "TARGET_MIPS16" 4502 "sltu\t%1,1" 4503 [(set_attr "type" "slt") 4504 (set_attr "mode" "<MODE>")]) 4505 4506;; "sne" uses sltu instructions in which the first operand is $0. 4507;; This isn't possible in mips16 code. 4508 4509(define_expand "sne" 4510 [(set (match_operand:SI 0 "register_operand") 4511 (ne:SI (match_dup 1) 4512 (match_dup 2)))] 4513 "!TARGET_MIPS16" 4514 { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; }) 4515 4516(define_insn "*sne_<mode>" 4517 [(set (match_operand:GPR 0 "register_operand" "=d") 4518 (ne:GPR (match_operand:GPR 1 "register_operand" "d") 4519 (const_int 0)))] 4520 "!TARGET_MIPS16" 4521 "sltu\t%0,%.,%1" 4522 [(set_attr "type" "slt") 4523 (set_attr "mode" "<MODE>")]) 4524 4525(define_expand "sgt" 4526 [(set (match_operand:SI 0 "register_operand") 4527 (gt:SI (match_dup 1) 4528 (match_dup 2)))] 4529 "" 4530 { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; }) 4531 4532(define_insn "*sgt_<mode>" 4533 [(set (match_operand:GPR 0 "register_operand" "=d") 4534 (gt:GPR (match_operand:GPR 1 "register_operand" "d") 4535 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))] 4536 "!TARGET_MIPS16" 4537 "slt\t%0,%z2,%1" 4538 [(set_attr "type" "slt") 4539 (set_attr "mode" "<MODE>")]) 4540 4541(define_insn "*sgt_<mode>_mips16" 4542 [(set (match_operand:GPR 0 "register_operand" "=t") 4543 (gt:GPR (match_operand:GPR 1 "register_operand" "d") 4544 (match_operand:GPR 2 "register_operand" "d")))] 4545 "TARGET_MIPS16" 4546 "slt\t%2,%1" 4547 [(set_attr "type" "slt") 4548 (set_attr "mode" "<MODE>")]) 4549 4550(define_expand "sge" 4551 [(set (match_operand:SI 0 "register_operand") 4552 (ge:SI (match_dup 1) 4553 (match_dup 2)))] 4554 "" 4555 { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; }) 4556 4557(define_insn "*sge_<mode>" 4558 [(set (match_operand:GPR 0 "register_operand" "=d") 4559 (ge:GPR (match_operand:GPR 1 "register_operand" "d") 4560 (const_int 1)))] 4561 "!TARGET_MIPS16" 4562 "slt\t%0,%.,%1" 4563 [(set_attr "type" "slt") 4564 (set_attr "mode" "<MODE>")]) 4565 4566(define_expand "slt" 4567 [(set (match_operand:SI 0 "register_operand") 4568 (lt:SI (match_dup 1) 4569 (match_dup 2)))] 4570 "" 4571 { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; }) 4572 4573(define_insn "*slt_<mode>" 4574 [(set (match_operand:GPR 0 "register_operand" "=d") 4575 (lt:GPR (match_operand:GPR 1 "register_operand" "d") 4576 (match_operand:GPR 2 "arith_operand" "dI")))] 4577 "!TARGET_MIPS16" 4578 "slt\t%0,%1,%2" 4579 [(set_attr "type" "slt") 4580 (set_attr "mode" "<MODE>")]) 4581 4582(define_insn "*slt_<mode>_mips16" 4583 [(set (match_operand:GPR 0 "register_operand" "=t,t") 4584 (lt:GPR (match_operand:GPR 1 "register_operand" "d,d") 4585 (match_operand:GPR 2 "arith_operand" "d,I")))] 4586 "TARGET_MIPS16" 4587 "slt\t%1,%2" 4588 [(set_attr "type" "slt") 4589 (set_attr "mode" "<MODE>") 4590 (set_attr_alternative "length" 4591 [(const_int 4) 4592 (if_then_else (match_operand 2 "m16_uimm8_1") 4593 (const_int 4) 4594 (const_int 8))])]) 4595 4596(define_expand "sle" 4597 [(set (match_operand:SI 0 "register_operand") 4598 (le:SI (match_dup 1) 4599 (match_dup 2)))] 4600 "" 4601 { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; }) 4602 4603(define_insn "*sle_<mode>" 4604 [(set (match_operand:GPR 0 "register_operand" "=d") 4605 (le:GPR (match_operand:GPR 1 "register_operand" "d") 4606 (match_operand:GPR 2 "sle_operand" "")))] 4607 "!TARGET_MIPS16" 4608{ 4609 operands[2] = GEN_INT (INTVAL (operands[2]) + 1); 4610 return "slt\t%0,%1,%2"; 4611} 4612 [(set_attr "type" "slt") 4613 (set_attr "mode" "<MODE>")]) 4614 4615(define_insn "*sle_<mode>_mips16" 4616 [(set (match_operand:GPR 0 "register_operand" "=t") 4617 (le:GPR (match_operand:GPR 1 "register_operand" "d") 4618 (match_operand:GPR 2 "sle_operand" "")))] 4619 "TARGET_MIPS16" 4620{ 4621 operands[2] = GEN_INT (INTVAL (operands[2]) + 1); 4622 return "slt\t%1,%2"; 4623} 4624 [(set_attr "type" "slt") 4625 (set_attr "mode" "<MODE>") 4626 (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1") 4627 (const_int 4) 4628 (const_int 8)))]) 4629 4630(define_expand "sgtu" 4631 [(set (match_operand:SI 0 "register_operand") 4632 (gtu:SI (match_dup 1) 4633 (match_dup 2)))] 4634 "" 4635 { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; }) 4636 4637(define_insn "*sgtu_<mode>" 4638 [(set (match_operand:GPR 0 "register_operand" "=d") 4639 (gtu:GPR (match_operand:GPR 1 "register_operand" "d") 4640 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))] 4641 "!TARGET_MIPS16" 4642 "sltu\t%0,%z2,%1" 4643 [(set_attr "type" "slt") 4644 (set_attr "mode" "<MODE>")]) 4645 4646(define_insn "*sgtu_<mode>_mips16" 4647 [(set (match_operand:GPR 0 "register_operand" "=t") 4648 (gtu:GPR (match_operand:GPR 1 "register_operand" "d") 4649 (match_operand:GPR 2 "register_operand" "d")))] 4650 "TARGET_MIPS16" 4651 "sltu\t%2,%1" 4652 [(set_attr "type" "slt") 4653 (set_attr "mode" "<MODE>")]) 4654 4655(define_expand "sgeu" 4656 [(set (match_operand:SI 0 "register_operand") 4657 (geu:SI (match_dup 1) 4658 (match_dup 2)))] 4659 "" 4660 { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; }) 4661 4662(define_insn "*sge_<mode>" 4663 [(set (match_operand:GPR 0 "register_operand" "=d") 4664 (geu:GPR (match_operand:GPR 1 "register_operand" "d") 4665 (const_int 1)))] 4666 "!TARGET_MIPS16" 4667 "sltu\t%0,%.,%1" 4668 [(set_attr "type" "slt") 4669 (set_attr "mode" "<MODE>")]) 4670 4671(define_expand "sltu" 4672 [(set (match_operand:SI 0 "register_operand") 4673 (ltu:SI (match_dup 1) 4674 (match_dup 2)))] 4675 "" 4676 { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; }) 4677 4678(define_insn "*sltu_<mode>" 4679 [(set (match_operand:GPR 0 "register_operand" "=d") 4680 (ltu:GPR (match_operand:GPR 1 "register_operand" "d") 4681 (match_operand:GPR 2 "arith_operand" "dI")))] 4682 "!TARGET_MIPS16" 4683 "sltu\t%0,%1,%2" 4684 [(set_attr "type" "slt") 4685 (set_attr "mode" "<MODE>")]) 4686 4687(define_insn "*sltu_<mode>_mips16" 4688 [(set (match_operand:GPR 0 "register_operand" "=t,t") 4689 (ltu:GPR (match_operand:GPR 1 "register_operand" "d,d") 4690 (match_operand:GPR 2 "arith_operand" "d,I")))] 4691 "TARGET_MIPS16" 4692 "sltu\t%1,%2" 4693 [(set_attr "type" "slt") 4694 (set_attr "mode" "<MODE>") 4695 (set_attr_alternative "length" 4696 [(const_int 4) 4697 (if_then_else (match_operand 2 "m16_uimm8_1") 4698 (const_int 4) 4699 (const_int 8))])]) 4700 4701(define_expand "sleu" 4702 [(set (match_operand:SI 0 "register_operand") 4703 (leu:SI (match_dup 1) 4704 (match_dup 2)))] 4705 "" 4706 { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; }) 4707 4708(define_insn "*sleu_<mode>" 4709 [(set (match_operand:GPR 0 "register_operand" "=d") 4710 (leu:GPR (match_operand:GPR 1 "register_operand" "d") 4711 (match_operand:GPR 2 "sleu_operand" "")))] 4712 "!TARGET_MIPS16" 4713{ 4714 operands[2] = GEN_INT (INTVAL (operands[2]) + 1); 4715 return "sltu\t%0,%1,%2"; 4716} 4717 [(set_attr "type" "slt") 4718 (set_attr "mode" "<MODE>")]) 4719 4720(define_insn "*sleu_<mode>_mips16" 4721 [(set (match_operand:GPR 0 "register_operand" "=t") 4722 (leu:GPR (match_operand:GPR 1 "register_operand" "d") 4723 (match_operand:GPR 2 "sleu_operand" "")))] 4724 "TARGET_MIPS16" 4725{ 4726 operands[2] = GEN_INT (INTVAL (operands[2]) + 1); 4727 return "sltu\t%1,%2"; 4728} 4729 [(set_attr "type" "slt") 4730 (set_attr "mode" "<MODE>") 4731 (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1") 4732 (const_int 4) 4733 (const_int 8)))]) 4734 4735;; 4736;; .................... 4737;; 4738;; FLOATING POINT COMPARISONS 4739;; 4740;; .................... 4741 4742(define_insn "s<code>_<mode>" 4743 [(set (match_operand:CC 0 "register_operand" "=z") 4744 (fcond:CC (match_operand:SCALARF 1 "register_operand" "f") 4745 (match_operand:SCALARF 2 "register_operand" "f")))] 4746 "" 4747 "c.<fcond>.<fmt>\t%Z0%1,%2" 4748 [(set_attr "type" "fcmp") 4749 (set_attr "mode" "FPSW")]) 4750 4751(define_insn "s<code>_<mode>" 4752 [(set (match_operand:CC 0 "register_operand" "=z") 4753 (swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f") 4754 (match_operand:SCALARF 2 "register_operand" "f")))] 4755 "" 4756 "c.<swapped_fcond>.<fmt>\t%Z0%2,%1" 4757 [(set_attr "type" "fcmp") 4758 (set_attr "mode" "FPSW")]) 4759 4760;; 4761;; .................... 4762;; 4763;; UNCONDITIONAL BRANCHES 4764;; 4765;; .................... 4766 4767;; Unconditional branches. 4768 4769(define_insn "jump" 4770 [(set (pc) 4771 (label_ref (match_operand 0 "" "")))] 4772 "!TARGET_MIPS16" 4773{ 4774 if (flag_pic) 4775 { 4776 if (get_attr_length (insn) <= 8) 4777 return "%*b\t%l0%/"; 4778 else 4779 { 4780 output_asm_insn (mips_output_load_label (), operands); 4781 return "%*jr\t%@%/%]"; 4782 } 4783 } 4784 else 4785 return "%*j\t%l0%/"; 4786} 4787 [(set_attr "type" "jump") 4788 (set_attr "mode" "none") 4789 (set (attr "length") 4790 ;; We can't use `j' when emitting PIC. Emit a branch if it's 4791 ;; in range, otherwise load the address of the branch target into 4792 ;; $at and then jump to it. 4793 (if_then_else 4794 (ior (eq (symbol_ref "flag_pic") (const_int 0)) 4795 (lt (abs (minus (match_dup 0) 4796 (plus (pc) (const_int 4)))) 4797 (const_int 131072))) 4798 (const_int 4) (const_int 16)))]) 4799 4800;; We need a different insn for the mips16, because a mips16 branch 4801;; does not have a delay slot. 4802 4803(define_insn "" 4804 [(set (pc) 4805 (label_ref (match_operand 0 "" "")))] 4806 "TARGET_MIPS16" 4807 "b\t%l0" 4808 [(set_attr "type" "branch") 4809 (set_attr "mode" "none") 4810 (set_attr "length" "8")]) 4811 4812(define_expand "indirect_jump" 4813 [(set (pc) (match_operand 0 "register_operand"))] 4814 "" 4815{ 4816 operands[0] = force_reg (Pmode, operands[0]); 4817 if (Pmode == SImode) 4818 emit_jump_insn (gen_indirect_jumpsi (operands[0])); 4819 else 4820 emit_jump_insn (gen_indirect_jumpdi (operands[0])); 4821 DONE; 4822}) 4823 4824(define_insn "indirect_jump<mode>" 4825 [(set (pc) (match_operand:P 0 "register_operand" "d"))] 4826 "" 4827 "%*j\t%0%/" 4828 [(set_attr "type" "jump") 4829 (set_attr "mode" "none")]) 4830 4831(define_expand "tablejump" 4832 [(set (pc) 4833 (match_operand 0 "register_operand")) 4834 (use (label_ref (match_operand 1 "")))] 4835 "" 4836{ 4837 if (TARGET_MIPS16) 4838 operands[0] = expand_binop (Pmode, add_optab, 4839 convert_to_mode (Pmode, operands[0], false), 4840 gen_rtx_LABEL_REF (Pmode, operands[1]), 4841 0, 0, OPTAB_WIDEN); 4842 else if (TARGET_GPWORD) 4843 operands[0] = expand_binop (Pmode, add_optab, operands[0], 4844 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN); 4845 4846 if (Pmode == SImode) 4847 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1])); 4848 else 4849 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1])); 4850 DONE; 4851}) 4852 4853(define_insn "tablejump<mode>" 4854 [(set (pc) 4855 (match_operand:P 0 "register_operand" "d")) 4856 (use (label_ref (match_operand 1 "" "")))] 4857 "" 4858 "%*j\t%0%/" 4859 [(set_attr "type" "jump") 4860 (set_attr "mode" "none")]) 4861 4862;; For TARGET_ABICALLS, we save the gp in the jmp_buf as well. 4863;; While it is possible to either pull it off the stack (in the 4864;; o32 case) or recalculate it given t9 and our target label, 4865;; it takes 3 or 4 insns to do so. 4866 4867(define_expand "builtin_setjmp_setup" 4868 [(use (match_operand 0 "register_operand"))] 4869 "TARGET_ABICALLS" 4870{ 4871 rtx addr; 4872 4873 addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3); 4874 emit_move_insn (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx); 4875 DONE; 4876}) 4877 4878;; Restore the gp that we saved above. Despite the earlier comment, it seems 4879;; that older code did recalculate the gp from $25. Continue to jump through 4880;; $25 for compatibility (we lose nothing by doing so). 4881 4882(define_expand "builtin_longjmp" 4883 [(use (match_operand 0 "register_operand"))] 4884 "TARGET_ABICALLS" 4885{ 4886 /* The elements of the buffer are, in order: */ 4887 int W = GET_MODE_SIZE (Pmode); 4888 rtx fp = gen_rtx_MEM (Pmode, operands[0]); 4889 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W)); 4890 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W)); 4891 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W)); 4892 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM); 4893 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx. 4894 The target is bound to be using $28 as the global pointer 4895 but the current function might not be. */ 4896 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM); 4897 4898 /* This bit is similar to expand_builtin_longjmp except that it 4899 restores $gp as well. */ 4900 emit_move_insn (hard_frame_pointer_rtx, fp); 4901 emit_move_insn (pv, lab); 4902 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX); 4903 emit_move_insn (gp, gpv); 4904 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx)); 4905 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); 4906 emit_insn (gen_rtx_USE (VOIDmode, gp)); 4907 emit_indirect_jump (pv); 4908 DONE; 4909}) 4910 4911;; 4912;; .................... 4913;; 4914;; Function prologue/epilogue 4915;; 4916;; .................... 4917;; 4918 4919(define_expand "prologue" 4920 [(const_int 1)] 4921 "" 4922{ 4923 mips_expand_prologue (); 4924 DONE; 4925}) 4926 4927;; Block any insns from being moved before this point, since the 4928;; profiling call to mcount can use various registers that aren't 4929;; saved or used to pass arguments. 4930 4931(define_insn "blockage" 4932 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)] 4933 "" 4934 "" 4935 [(set_attr "type" "unknown") 4936 (set_attr "mode" "none") 4937 (set_attr "length" "0")]) 4938 4939(define_expand "epilogue" 4940 [(const_int 2)] 4941 "" 4942{ 4943 mips_expand_epilogue (false); 4944 DONE; 4945}) 4946 4947(define_expand "sibcall_epilogue" 4948 [(const_int 2)] 4949 "" 4950{ 4951 mips_expand_epilogue (true); 4952 DONE; 4953}) 4954 4955;; Trivial return. Make it look like a normal return insn as that 4956;; allows jump optimizations to work better. 4957 4958(define_insn "return" 4959 [(return)] 4960 "mips_can_use_return_insn ()" 4961 "%*j\t$31%/" 4962 [(set_attr "type" "jump") 4963 (set_attr "mode" "none")]) 4964 4965;; Normal return. 4966 4967(define_insn "return_internal" 4968 [(return) 4969 (use (match_operand 0 "pmode_register_operand" ""))] 4970 "" 4971 "%*j\t%0%/" 4972 [(set_attr "type" "jump") 4973 (set_attr "mode" "none")]) 4974 4975;; This is used in compiling the unwind routines. 4976(define_expand "eh_return" 4977 [(use (match_operand 0 "general_operand"))] 4978 "" 4979{ 4980 enum machine_mode gpr_mode = TARGET_64BIT ? DImode : SImode; 4981 4982 if (GET_MODE (operands[0]) != gpr_mode) 4983 operands[0] = convert_to_mode (gpr_mode, operands[0], 0); 4984 if (TARGET_64BIT) 4985 emit_insn (gen_eh_set_lr_di (operands[0])); 4986 else 4987 emit_insn (gen_eh_set_lr_si (operands[0])); 4988 4989 DONE; 4990}) 4991 4992;; Clobber the return address on the stack. We can't expand this 4993;; until we know where it will be put in the stack frame. 4994 4995(define_insn "eh_set_lr_si" 4996 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN) 4997 (clobber (match_scratch:SI 1 "=&d"))] 4998 "! TARGET_64BIT" 4999 "#") 5000 5001(define_insn "eh_set_lr_di" 5002 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN) 5003 (clobber (match_scratch:DI 1 "=&d"))] 5004 "TARGET_64BIT" 5005 "#") 5006 5007(define_split 5008 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN) 5009 (clobber (match_scratch 1))] 5010 "reload_completed && !TARGET_DEBUG_D_MODE" 5011 [(const_int 0)] 5012{ 5013 mips_set_return_address (operands[0], operands[1]); 5014 DONE; 5015}) 5016 5017(define_insn_and_split "exception_receiver" 5018 [(set (reg:SI 28) 5019 (unspec_volatile:SI [(const_int 0)] UNSPEC_EH_RECEIVER))] 5020 "TARGET_ABICALLS && TARGET_OLDABI" 5021 "#" 5022 "&& reload_completed" 5023 [(const_int 0)] 5024{ 5025 mips_restore_gp (); 5026 DONE; 5027} 5028 [(set_attr "type" "load") 5029 (set_attr "length" "12")]) 5030 5031;; 5032;; .................... 5033;; 5034;; FUNCTION CALLS 5035;; 5036;; .................... 5037 5038;; Instructions to load a call address from the GOT. The address might 5039;; point to a function or to a lazy binding stub. In the latter case, 5040;; the stub will use the dynamic linker to resolve the function, which 5041;; in turn will change the GOT entry to point to the function's real 5042;; address. 5043;; 5044;; This means that every call, even pure and constant ones, can 5045;; potentially modify the GOT entry. And once a stub has been called, 5046;; we must not call it again. 5047;; 5048;; We represent this restriction using an imaginary fixed register that 5049;; acts like a GOT version number. By making the register call-clobbered, 5050;; we tell the target-independent code that the address could be changed 5051;; by any call insn. 5052(define_insn "load_call<mode>" 5053 [(set (match_operand:P 0 "register_operand" "=c") 5054 (unspec:P [(match_operand:P 1 "register_operand" "r") 5055 (match_operand:P 2 "immediate_operand" "") 5056 (reg:P FAKE_CALL_REGNO)] 5057 UNSPEC_LOAD_CALL))] 5058 "TARGET_ABICALLS" 5059 "<load>\t%0,%R2(%1)" 5060 [(set_attr "type" "load") 5061 (set_attr "mode" "<MODE>") 5062 (set_attr "length" "4")]) 5063 5064;; Sibling calls. All these patterns use jump instructions. 5065 5066;; If TARGET_SIBCALLS, call_insn_operand will only accept constant 5067;; addresses if a direct jump is acceptable. Since the 'S' constraint 5068;; is defined in terms of call_insn_operand, the same is true of the 5069;; constraints. 5070 5071;; When we use an indirect jump, we need a register that will be 5072;; preserved by the epilogue. Since TARGET_ABICALLS forces us to 5073;; use $25 for this purpose -- and $25 is never clobbered by the 5074;; epilogue -- we might as well use it for !TARGET_ABICALLS as well. 5075 5076(define_expand "sibcall" 5077 [(parallel [(call (match_operand 0 "") 5078 (match_operand 1 "")) 5079 (use (match_operand 2 "")) ;; next_arg_reg 5080 (use (match_operand 3 ""))])] ;; struct_value_size_rtx 5081 "TARGET_SIBCALLS" 5082{ 5083 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true); 5084 DONE; 5085}) 5086 5087(define_insn "sibcall_internal" 5088 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S")) 5089 (match_operand 1 "" ""))] 5090 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" 5091 { return MIPS_CALL ("j", operands, 0); } 5092 [(set_attr "type" "call")]) 5093 5094(define_expand "sibcall_value" 5095 [(parallel [(set (match_operand 0 "") 5096 (call (match_operand 1 "") 5097 (match_operand 2 ""))) 5098 (use (match_operand 3 ""))])] ;; next_arg_reg 5099 "TARGET_SIBCALLS" 5100{ 5101 mips_expand_call (operands[0], XEXP (operands[1], 0), 5102 operands[2], operands[3], true); 5103 DONE; 5104}) 5105 5106(define_insn "sibcall_value_internal" 5107 [(set (match_operand 0 "register_operand" "=df,df") 5108 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S")) 5109 (match_operand 2 "" "")))] 5110 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" 5111 { return MIPS_CALL ("j", operands, 1); } 5112 [(set_attr "type" "call")]) 5113 5114(define_insn "sibcall_value_multiple_internal" 5115 [(set (match_operand 0 "register_operand" "=df,df") 5116 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S")) 5117 (match_operand 2 "" ""))) 5118 (set (match_operand 3 "register_operand" "=df,df") 5119 (call (mem:SI (match_dup 1)) 5120 (match_dup 2)))] 5121 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" 5122 { return MIPS_CALL ("j", operands, 1); } 5123 [(set_attr "type" "call")]) 5124 5125(define_expand "call" 5126 [(parallel [(call (match_operand 0 "") 5127 (match_operand 1 "")) 5128 (use (match_operand 2 "")) ;; next_arg_reg 5129 (use (match_operand 3 ""))])] ;; struct_value_size_rtx 5130 "" 5131{ 5132 mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false); 5133 DONE; 5134}) 5135 5136;; This instruction directly corresponds to an assembly-language "jal". 5137;; There are four cases: 5138;; 5139;; - -mno-abicalls: 5140;; Both symbolic and register destinations are OK. The pattern 5141;; always expands to a single mips instruction. 5142;; 5143;; - -mabicalls/-mno-explicit-relocs: 5144;; Again, both symbolic and register destinations are OK. 5145;; The call is treated as a multi-instruction black box. 5146;; 5147;; - -mabicalls/-mexplicit-relocs with n32 or n64: 5148;; Only "jal $25" is allowed. This expands to a single "jalr $25" 5149;; instruction. 5150;; 5151;; - -mabicalls/-mexplicit-relocs with o32 or o64: 5152;; Only "jal $25" is allowed. The call is actually two instructions: 5153;; "jalr $25" followed by an insn to reload $gp. 5154;; 5155;; In the last case, we can generate the individual instructions with 5156;; a define_split. There are several things to be wary of: 5157;; 5158;; - We can't expose the load of $gp before reload. If we did, 5159;; it might get removed as dead, but reload can introduce new 5160;; uses of $gp by rematerializing constants. 5161;; 5162;; - We shouldn't restore $gp after calls that never return. 5163;; It isn't valid to insert instructions between a noreturn 5164;; call and the following barrier. 5165;; 5166;; - The splitter deliberately changes the liveness of $gp. The unsplit 5167;; instruction preserves $gp and so have no effect on its liveness. 5168;; But once we generate the separate insns, it becomes obvious that 5169;; $gp is not live on entry to the call. 5170;; 5171;; ??? The operands[2] = insn check is a hack to make the original insn 5172;; available to the splitter. 5173(define_insn_and_split "call_internal" 5174 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S")) 5175 (match_operand 1 "" "")) 5176 (clobber (reg:SI 31))] 5177 "" 5178 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0); } 5179 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)" 5180 [(const_int 0)] 5181{ 5182 emit_call_insn (gen_call_split (operands[0], operands[1])); 5183 if (!find_reg_note (operands[2], REG_NORETURN, 0)) 5184 mips_restore_gp (); 5185 DONE; 5186} 5187 [(set_attr "jal" "indirect,direct") 5188 (set_attr "extended_mips16" "no,yes")]) 5189 5190(define_insn "call_split" 5191 [(call (mem:SI (match_operand 0 "call_insn_operand" "cS")) 5192 (match_operand 1 "" "")) 5193 (clobber (reg:SI 31)) 5194 (clobber (reg:SI 28))] 5195 "TARGET_SPLIT_CALLS" 5196 { return MIPS_CALL ("jal", operands, 0); } 5197 [(set_attr "type" "call")]) 5198 5199(define_expand "call_value" 5200 [(parallel [(set (match_operand 0 "") 5201 (call (match_operand 1 "") 5202 (match_operand 2 ""))) 5203 (use (match_operand 3 ""))])] ;; next_arg_reg 5204 "" 5205{ 5206 mips_expand_call (operands[0], XEXP (operands[1], 0), 5207 operands[2], operands[3], false); 5208 DONE; 5209}) 5210 5211;; See comment for call_internal. 5212(define_insn_and_split "call_value_internal" 5213 [(set (match_operand 0 "register_operand" "=df,df") 5214 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S")) 5215 (match_operand 2 "" ""))) 5216 (clobber (reg:SI 31))] 5217 "" 5218 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); } 5219 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)" 5220 [(const_int 0)] 5221{ 5222 emit_call_insn (gen_call_value_split (operands[0], operands[1], 5223 operands[2])); 5224 if (!find_reg_note (operands[3], REG_NORETURN, 0)) 5225 mips_restore_gp (); 5226 DONE; 5227} 5228 [(set_attr "jal" "indirect,direct") 5229 (set_attr "extended_mips16" "no,yes")]) 5230 5231(define_insn "call_value_split" 5232 [(set (match_operand 0 "register_operand" "=df") 5233 (call (mem:SI (match_operand 1 "call_insn_operand" "cS")) 5234 (match_operand 2 "" ""))) 5235 (clobber (reg:SI 31)) 5236 (clobber (reg:SI 28))] 5237 "TARGET_SPLIT_CALLS" 5238 { return MIPS_CALL ("jal", operands, 1); } 5239 [(set_attr "type" "call")]) 5240 5241;; See comment for call_internal. 5242(define_insn_and_split "call_value_multiple_internal" 5243 [(set (match_operand 0 "register_operand" "=df,df") 5244 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S")) 5245 (match_operand 2 "" ""))) 5246 (set (match_operand 3 "register_operand" "=df,df") 5247 (call (mem:SI (match_dup 1)) 5248 (match_dup 2))) 5249 (clobber (reg:SI 31))] 5250 "" 5251 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1); } 5252 "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)" 5253 [(const_int 0)] 5254{ 5255 emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1], 5256 operands[2], operands[3])); 5257 if (!find_reg_note (operands[4], REG_NORETURN, 0)) 5258 mips_restore_gp (); 5259 DONE; 5260} 5261 [(set_attr "jal" "indirect,direct") 5262 (set_attr "extended_mips16" "no,yes")]) 5263 5264(define_insn "call_value_multiple_split" 5265 [(set (match_operand 0 "register_operand" "=df") 5266 (call (mem:SI (match_operand 1 "call_insn_operand" "cS")) 5267 (match_operand 2 "" ""))) 5268 (set (match_operand 3 "register_operand" "=df") 5269 (call (mem:SI (match_dup 1)) 5270 (match_dup 2))) 5271 (clobber (reg:SI 31)) 5272 (clobber (reg:SI 28))] 5273 "TARGET_SPLIT_CALLS" 5274 { return MIPS_CALL ("jal", operands, 1); } 5275 [(set_attr "type" "call")]) 5276 5277;; Call subroutine returning any type. 5278 5279(define_expand "untyped_call" 5280 [(parallel [(call (match_operand 0 "") 5281 (const_int 0)) 5282 (match_operand 1 "") 5283 (match_operand 2 "")])] 5284 "" 5285{ 5286 int i; 5287 5288 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx)); 5289 5290 for (i = 0; i < XVECLEN (operands[2], 0); i++) 5291 { 5292 rtx set = XVECEXP (operands[2], 0, i); 5293 emit_move_insn (SET_DEST (set), SET_SRC (set)); 5294 } 5295 5296 emit_insn (gen_blockage ()); 5297 DONE; 5298}) 5299 5300;; 5301;; .................... 5302;; 5303;; MISC. 5304;; 5305;; .................... 5306;; 5307 5308 5309(define_insn "prefetch" 5310 [(prefetch (match_operand:QI 0 "address_operand" "p") 5311 (match_operand 1 "const_int_operand" "n") 5312 (match_operand 2 "const_int_operand" "n"))] 5313 "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS" 5314{ 5315 operands[1] = mips_prefetch_cookie (operands[1], operands[2]); 5316 return "pref\t%1,%a0"; 5317} 5318 [(set_attr "type" "prefetch")]) 5319 5320(define_insn "*prefetch_indexed_<mode>" 5321 [(prefetch (plus:P (match_operand:P 0 "register_operand" "d") 5322 (match_operand:P 1 "register_operand" "d")) 5323 (match_operand 2 "const_int_operand" "n") 5324 (match_operand 3 "const_int_operand" "n"))] 5325 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 5326{ 5327 operands[2] = mips_prefetch_cookie (operands[2], operands[3]); 5328 return "prefx\t%2,%1(%0)"; 5329} 5330 [(set_attr "type" "prefetchx")]) 5331 5332(define_insn "nop" 5333 [(const_int 0)] 5334 "" 5335 "%(nop%)" 5336 [(set_attr "type" "nop") 5337 (set_attr "mode" "none")]) 5338 5339;; Like nop, but commented out when outside a .set noreorder block. 5340(define_insn "hazard_nop" 5341 [(const_int 1)] 5342 "" 5343 { 5344 if (set_noreorder) 5345 return "nop"; 5346 else 5347 return "#nop"; 5348 } 5349 [(set_attr "type" "nop")]) 5350 5351;; MIPS4 Conditional move instructions. 5352 5353(define_insn "*mov<GPR:mode>_on_<MOVECC:mode>" 5354 [(set (match_operand:GPR 0 "register_operand" "=d,d") 5355 (if_then_else:GPR 5356 (match_operator:MOVECC 4 "equality_operator" 5357 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>") 5358 (const_int 0)]) 5359 (match_operand:GPR 2 "reg_or_0_operand" "dJ,0") 5360 (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))] 5361 "ISA_HAS_CONDMOVE" 5362 "@ 5363 mov%T4\t%0,%z2,%1 5364 mov%t4\t%0,%z3,%1" 5365 [(set_attr "type" "condmove") 5366 (set_attr "mode" "<GPR:MODE>")]) 5367 5368(define_insn "*mov<SCALARF:mode>_on_<MOVECC:mode>" 5369 [(set (match_operand:SCALARF 0 "register_operand" "=f,f") 5370 (if_then_else:SCALARF 5371 (match_operator:MOVECC 4 "equality_operator" 5372 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>") 5373 (const_int 0)]) 5374 (match_operand:SCALARF 2 "register_operand" "f,0") 5375 (match_operand:SCALARF 3 "register_operand" "0,f")))] 5376 "ISA_HAS_CONDMOVE" 5377 "@ 5378 mov%T4.<fmt>\t%0,%2,%1 5379 mov%t4.<fmt>\t%0,%3,%1" 5380 [(set_attr "type" "condmove") 5381 (set_attr "mode" "<SCALARF:MODE>")]) 5382 5383;; These are the main define_expand's used to make conditional moves. 5384 5385(define_expand "mov<mode>cc" 5386 [(set (match_dup 4) (match_operand 1 "comparison_operator")) 5387 (set (match_operand:GPR 0 "register_operand") 5388 (if_then_else:GPR (match_dup 5) 5389 (match_operand:GPR 2 "reg_or_0_operand") 5390 (match_operand:GPR 3 "reg_or_0_operand")))] 5391 "ISA_HAS_CONDMOVE" 5392{ 5393 gen_conditional_move (operands); 5394 DONE; 5395}) 5396 5397(define_expand "mov<mode>cc" 5398 [(set (match_dup 4) (match_operand 1 "comparison_operator")) 5399 (set (match_operand:SCALARF 0 "register_operand") 5400 (if_then_else:SCALARF (match_dup 5) 5401 (match_operand:SCALARF 2 "register_operand") 5402 (match_operand:SCALARF 3 "register_operand")))] 5403 "ISA_HAS_CONDMOVE" 5404{ 5405 gen_conditional_move (operands); 5406 DONE; 5407}) 5408 5409;; 5410;; .................... 5411;; 5412;; mips16 inline constant tables 5413;; 5414;; .................... 5415;; 5416 5417(define_insn "consttable_int" 5418 [(unspec_volatile [(match_operand 0 "consttable_operand" "") 5419 (match_operand 1 "const_int_operand" "")] 5420 UNSPEC_CONSTTABLE_INT)] 5421 "TARGET_MIPS16" 5422{ 5423 assemble_integer (operands[0], INTVAL (operands[1]), 5424 BITS_PER_UNIT * INTVAL (operands[1]), 1); 5425 return ""; 5426} 5427 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))]) 5428 5429(define_insn "consttable_float" 5430 [(unspec_volatile [(match_operand 0 "consttable_operand" "")] 5431 UNSPEC_CONSTTABLE_FLOAT)] 5432 "TARGET_MIPS16" 5433{ 5434 REAL_VALUE_TYPE d; 5435 5436 gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE); 5437 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]); 5438 assemble_real (d, GET_MODE (operands[0]), 5439 GET_MODE_BITSIZE (GET_MODE (operands[0]))); 5440 return ""; 5441} 5442 [(set (attr "length") 5443 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))]) 5444 5445(define_insn "align" 5446 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)] 5447 "" 5448 ".align\t%0" 5449 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))]) 5450 5451(define_split 5452 [(match_operand 0 "small_data_pattern")] 5453 "reload_completed" 5454 [(match_dup 0)] 5455 { operands[0] = mips_rewrite_small_data (operands[0]); }) 5456 5457; Thread-Local Storage 5458 5459; The TLS base pointer is accessed via "rdhwr $v1, $29". No current 5460; MIPS architecture defines this register, and no current 5461; implementation provides it; instead, any OS which supports TLS is 5462; expected to trap and emulate this instruction. rdhwr is part of the 5463; MIPS 32r2 specification, but we use it on any architecture because 5464; we expect it to be emulated. Use .set to force the assembler to 5465; accept it. 5466 5467(define_insn "tls_get_tp_<mode>" 5468 [(set (match_operand:P 0 "register_operand" "=v") 5469 (unspec:P [(const_int 0)] 5470 UNSPEC_TLS_GET_TP))] 5471 "HAVE_AS_TLS && !TARGET_MIPS16" 5472 ".set\tpush\;.set\tmips32r2\t\;rdhwr\t%0,$29\;.set\tpop" 5473 [(set_attr "type" "unknown") 5474 ; Since rdhwr always generates a trap for now, putting it in a delay 5475 ; slot would make the kernel's emulation of it much slower. 5476 (set_attr "can_delay" "no") 5477 (set_attr "mode" "<MODE>")]) 5478 5479; The MIPS Paired-Single Floating Point and MIPS-3D Instructions. 5480 5481(include "mips-ps-3d.md") 5482 5483; The MIPS DSP Instructions. 5484 5485(include "mips-dsp.md") 5486