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, 2006, 2007, 2008, 2009, 2010 4;; Free Software Foundation, Inc. 5;; Contributed by A. Lichnewsky, lich@inria.inria.fr 6;; Changes by Michael Meissner, meissner@osf.org 7;; 64-bit r4000 support by Ian Lance Taylor, ian@cygnus.com, and 8;; Brendan Eich, brendan@microunity.com. 9 10;; This file is part of GCC. 11 12;; GCC is free software; you can redistribute it and/or modify 13;; it under the terms of the GNU General Public License as published by 14;; the Free Software Foundation; either version 3, or (at your option) 15;; any later version. 16 17;; GCC is distributed in the hope that it will be useful, 18;; but WITHOUT ANY WARRANTY; without even the implied warranty of 19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20;; GNU General Public License for more details. 21 22;; You should have received a copy of the GNU General Public License 23;; along with GCC; see the file COPYING3. If not see 24;; <http://www.gnu.org/licenses/>. 25 26(define_constants 27 [(UNSPEC_LOAD_LOW 0) 28 (UNSPEC_LOAD_HIGH 1) 29 (UNSPEC_STORE_WORD 2) 30 (UNSPEC_GET_FNADDR 3) 31 (UNSPEC_BLOCKAGE 4) 32 (UNSPEC_POTENTIAL_CPRESTORE 5) 33 (UNSPEC_CPRESTORE 6) 34 (UNSPEC_RESTORE_GP 7) 35 (UNSPEC_MOVE_GP 8) 36 (UNSPEC_EH_RETURN 9) 37 (UNSPEC_CONSTTABLE_INT 10) 38 (UNSPEC_CONSTTABLE_FLOAT 11) 39 (UNSPEC_ALIGN 14) 40 (UNSPEC_HIGH 17) 41 (UNSPEC_LOAD_LEFT 18) 42 (UNSPEC_LOAD_RIGHT 19) 43 (UNSPEC_STORE_LEFT 20) 44 (UNSPEC_STORE_RIGHT 21) 45 (UNSPEC_LOADGP 22) 46 (UNSPEC_LOAD_CALL 23) 47 (UNSPEC_LOAD_GOT 24) 48 (UNSPEC_GP 25) 49 (UNSPEC_MFHI 26) 50 (UNSPEC_MTHI 27) 51 (UNSPEC_SET_HILO 28) 52 (UNSPEC_TLS_LDM 29) 53 (UNSPEC_TLS_GET_TP 30) 54 (UNSPEC_MFHC1 31) 55 (UNSPEC_MTHC1 32) 56 (UNSPEC_CLEAR_HAZARD 33) 57 (UNSPEC_RDHWR 34) 58 (UNSPEC_SYNCI 35) 59 (UNSPEC_SYNC 36) 60 (UNSPEC_COMPARE_AND_SWAP 37) 61 (UNSPEC_COMPARE_AND_SWAP_12 38) 62 (UNSPEC_SYNC_OLD_OP 39) 63 (UNSPEC_SYNC_NEW_OP 40) 64 (UNSPEC_SYNC_NEW_OP_12 41) 65 (UNSPEC_SYNC_OLD_OP_12 42) 66 (UNSPEC_SYNC_EXCHANGE 43) 67 (UNSPEC_SYNC_EXCHANGE_12 44) 68 (UNSPEC_MEMORY_BARRIER 45) 69 (UNSPEC_SET_GOT_VERSION 46) 70 (UNSPEC_UPDATE_GOT_VERSION 47) 71 (UNSPEC_COPYGP 48) 72 (UNSPEC_ERET 49) 73 (UNSPEC_DERET 50) 74 (UNSPEC_DI 51) 75 (UNSPEC_EHB 52) 76 (UNSPEC_RDPGPR 53) 77 (UNSPEC_COP0 54) 78 ;; Used in a call expression in place of args_size. It's present for PIC 79 ;; indirect calls where it contains args_size and the function symbol. 80 (UNSPEC_CALL_ATTR 55) 81 82 (UNSPEC_ADDRESS_FIRST 100) 83 84 (TLS_GET_TP_REGNUM 3) 85 (RETURN_ADDR_REGNUM 31) 86 (CPRESTORE_SLOT_REGNUM 76) 87 (GOT_VERSION_REGNUM 79) 88 89 ;; For MIPS Paired-Singled Floating Point Instructions. 90 91 (UNSPEC_MOVE_TF_PS 200) 92 (UNSPEC_C 201) 93 94 ;; MIPS64/MIPS32R2 alnv.ps 95 (UNSPEC_ALNV_PS 202) 96 97 ;; MIPS-3D instructions 98 (UNSPEC_CABS 203) 99 100 (UNSPEC_ADDR_PS 204) 101 (UNSPEC_CVT_PW_PS 205) 102 (UNSPEC_CVT_PS_PW 206) 103 (UNSPEC_MULR_PS 207) 104 (UNSPEC_ABS_PS 208) 105 106 (UNSPEC_RSQRT1 209) 107 (UNSPEC_RSQRT2 210) 108 (UNSPEC_RECIP1 211) 109 (UNSPEC_RECIP2 212) 110 (UNSPEC_SINGLE_CC 213) 111 (UNSPEC_SCC 214) 112 113 ;; MIPS DSP ASE Revision 0.98 3/24/2005 114 (UNSPEC_ADDQ 300) 115 (UNSPEC_ADDQ_S 301) 116 (UNSPEC_SUBQ 302) 117 (UNSPEC_SUBQ_S 303) 118 (UNSPEC_ADDSC 304) 119 (UNSPEC_ADDWC 305) 120 (UNSPEC_MODSUB 306) 121 (UNSPEC_RADDU_W_QB 307) 122 (UNSPEC_ABSQ_S 308) 123 (UNSPEC_PRECRQ_QB_PH 309) 124 (UNSPEC_PRECRQ_PH_W 310) 125 (UNSPEC_PRECRQ_RS_PH_W 311) 126 (UNSPEC_PRECRQU_S_QB_PH 312) 127 (UNSPEC_PRECEQ_W_PHL 313) 128 (UNSPEC_PRECEQ_W_PHR 314) 129 (UNSPEC_PRECEQU_PH_QBL 315) 130 (UNSPEC_PRECEQU_PH_QBR 316) 131 (UNSPEC_PRECEQU_PH_QBLA 317) 132 (UNSPEC_PRECEQU_PH_QBRA 318) 133 (UNSPEC_PRECEU_PH_QBL 319) 134 (UNSPEC_PRECEU_PH_QBR 320) 135 (UNSPEC_PRECEU_PH_QBLA 321) 136 (UNSPEC_PRECEU_PH_QBRA 322) 137 (UNSPEC_SHLL 323) 138 (UNSPEC_SHLL_S 324) 139 (UNSPEC_SHRL_QB 325) 140 (UNSPEC_SHRA_PH 326) 141 (UNSPEC_SHRA_R 327) 142 (UNSPEC_MULEU_S_PH_QBL 328) 143 (UNSPEC_MULEU_S_PH_QBR 329) 144 (UNSPEC_MULQ_RS_PH 330) 145 (UNSPEC_MULEQ_S_W_PHL 331) 146 (UNSPEC_MULEQ_S_W_PHR 332) 147 (UNSPEC_DPAU_H_QBL 333) 148 (UNSPEC_DPAU_H_QBR 334) 149 (UNSPEC_DPSU_H_QBL 335) 150 (UNSPEC_DPSU_H_QBR 336) 151 (UNSPEC_DPAQ_S_W_PH 337) 152 (UNSPEC_DPSQ_S_W_PH 338) 153 (UNSPEC_MULSAQ_S_W_PH 339) 154 (UNSPEC_DPAQ_SA_L_W 340) 155 (UNSPEC_DPSQ_SA_L_W 341) 156 (UNSPEC_MAQ_S_W_PHL 342) 157 (UNSPEC_MAQ_S_W_PHR 343) 158 (UNSPEC_MAQ_SA_W_PHL 344) 159 (UNSPEC_MAQ_SA_W_PHR 345) 160 (UNSPEC_BITREV 346) 161 (UNSPEC_INSV 347) 162 (UNSPEC_REPL_QB 348) 163 (UNSPEC_REPL_PH 349) 164 (UNSPEC_CMP_EQ 350) 165 (UNSPEC_CMP_LT 351) 166 (UNSPEC_CMP_LE 352) 167 (UNSPEC_CMPGU_EQ_QB 353) 168 (UNSPEC_CMPGU_LT_QB 354) 169 (UNSPEC_CMPGU_LE_QB 355) 170 (UNSPEC_PICK 356) 171 (UNSPEC_PACKRL_PH 357) 172 (UNSPEC_EXTR_W 358) 173 (UNSPEC_EXTR_R_W 359) 174 (UNSPEC_EXTR_RS_W 360) 175 (UNSPEC_EXTR_S_H 361) 176 (UNSPEC_EXTP 362) 177 (UNSPEC_EXTPDP 363) 178 (UNSPEC_SHILO 364) 179 (UNSPEC_MTHLIP 365) 180 (UNSPEC_WRDSP 366) 181 (UNSPEC_RDDSP 367) 182 183 ;; MIPS DSP ASE REV 2 Revision 0.02 11/24/2006 184 (UNSPEC_ABSQ_S_QB 400) 185 (UNSPEC_ADDU_PH 401) 186 (UNSPEC_ADDU_S_PH 402) 187 (UNSPEC_ADDUH_QB 403) 188 (UNSPEC_ADDUH_R_QB 404) 189 (UNSPEC_APPEND 405) 190 (UNSPEC_BALIGN 406) 191 (UNSPEC_CMPGDU_EQ_QB 407) 192 (UNSPEC_CMPGDU_LT_QB 408) 193 (UNSPEC_CMPGDU_LE_QB 409) 194 (UNSPEC_DPA_W_PH 410) 195 (UNSPEC_DPS_W_PH 411) 196 (UNSPEC_MADD 412) 197 (UNSPEC_MADDU 413) 198 (UNSPEC_MSUB 414) 199 (UNSPEC_MSUBU 415) 200 (UNSPEC_MUL_PH 416) 201 (UNSPEC_MUL_S_PH 417) 202 (UNSPEC_MULQ_RS_W 418) 203 (UNSPEC_MULQ_S_PH 419) 204 (UNSPEC_MULQ_S_W 420) 205 (UNSPEC_MULSA_W_PH 421) 206 (UNSPEC_MULT 422) 207 (UNSPEC_MULTU 423) 208 (UNSPEC_PRECR_QB_PH 424) 209 (UNSPEC_PRECR_SRA_PH_W 425) 210 (UNSPEC_PRECR_SRA_R_PH_W 426) 211 (UNSPEC_PREPEND 427) 212 (UNSPEC_SHRA_QB 428) 213 (UNSPEC_SHRA_R_QB 429) 214 (UNSPEC_SHRL_PH 430) 215 (UNSPEC_SUBU_PH 431) 216 (UNSPEC_SUBU_S_PH 432) 217 (UNSPEC_SUBUH_QB 433) 218 (UNSPEC_SUBUH_R_QB 434) 219 (UNSPEC_ADDQH_PH 435) 220 (UNSPEC_ADDQH_R_PH 436) 221 (UNSPEC_ADDQH_W 437) 222 (UNSPEC_ADDQH_R_W 438) 223 (UNSPEC_SUBQH_PH 439) 224 (UNSPEC_SUBQH_R_PH 440) 225 (UNSPEC_SUBQH_W 441) 226 (UNSPEC_SUBQH_R_W 442) 227 (UNSPEC_DPAX_W_PH 443) 228 (UNSPEC_DPSX_W_PH 444) 229 (UNSPEC_DPAQX_S_W_PH 445) 230 (UNSPEC_DPAQX_SA_W_PH 446) 231 (UNSPEC_DPSQX_S_W_PH 447) 232 (UNSPEC_DPSQX_SA_W_PH 448) 233 234 ;; ST Microelectronics Loongson-2E/2F. 235 (UNSPEC_LOONGSON_PAVG 500) 236 (UNSPEC_LOONGSON_PCMPEQ 501) 237 (UNSPEC_LOONGSON_PCMPGT 502) 238 (UNSPEC_LOONGSON_PEXTR 503) 239 (UNSPEC_LOONGSON_PINSR_0 504) 240 (UNSPEC_LOONGSON_PINSR_1 505) 241 (UNSPEC_LOONGSON_PINSR_2 506) 242 (UNSPEC_LOONGSON_PINSR_3 507) 243 (UNSPEC_LOONGSON_PMADD 508) 244 (UNSPEC_LOONGSON_PMOVMSK 509) 245 (UNSPEC_LOONGSON_PMULHU 510) 246 (UNSPEC_LOONGSON_PMULH 511) 247 (UNSPEC_LOONGSON_PMULL 512) 248 (UNSPEC_LOONGSON_PMULU 513) 249 (UNSPEC_LOONGSON_PASUBUB 514) 250 (UNSPEC_LOONGSON_BIADD 515) 251 (UNSPEC_LOONGSON_PSADBH 516) 252 (UNSPEC_LOONGSON_PSHUFH 517) 253 (UNSPEC_LOONGSON_PUNPCKH 518) 254 (UNSPEC_LOONGSON_PUNPCKL 519) 255 (UNSPEC_LOONGSON_PADDD 520) 256 (UNSPEC_LOONGSON_PSUBD 521) 257 258 ;; Used in loongson2ef.md 259 (UNSPEC_LOONGSON_ALU1_TURN_ENABLED_INSN 530) 260 (UNSPEC_LOONGSON_ALU2_TURN_ENABLED_INSN 531) 261 (UNSPEC_LOONGSON_FALU1_TURN_ENABLED_INSN 532) 262 (UNSPEC_LOONGSON_FALU2_TURN_ENABLED_INSN 533) 263 264 (UNSPEC_MIPS_CACHE 600) 265 (UNSPEC_R10K_CACHE_BARRIER 601) 266 267 ;; PIC long branch sequences are never longer than 100 bytes. 268 (MAX_PIC_BRANCH_LENGTH 100) 269 ] 270) 271 272(include "predicates.md") 273(include "constraints.md") 274 275;; .................... 276;; 277;; Attributes 278;; 279;; .................... 280 281(define_attr "got" "unset,xgot_high,load" 282 (const_string "unset")) 283 284;; For jal instructions, this attribute is DIRECT when the target address 285;; is symbolic and INDIRECT when it is a register. 286(define_attr "jal" "unset,direct,indirect" 287 (const_string "unset")) 288 289;; This attribute is YES if the instruction is a jal macro (not a 290;; real jal instruction). 291;; 292;; jal is always a macro for TARGET_CALL_CLOBBERED_GP because it includes 293;; an instruction to restore $gp. Direct jals are also macros for 294;; !TARGET_ABSOLUTE_JUMPS because they first load the target address 295;; into a register. 296(define_attr "jal_macro" "no,yes" 297 (cond [(eq_attr "jal" "direct") 298 (symbol_ref "(TARGET_CALL_CLOBBERED_GP || !TARGET_ABSOLUTE_JUMPS 299 ? JAL_MACRO_YES : JAL_MACRO_NO)") 300 (eq_attr "jal" "indirect") 301 (symbol_ref "(TARGET_CALL_CLOBBERED_GP 302 ? JAL_MACRO_YES : JAL_MACRO_NO)")] 303 (const_string "no"))) 304 305;; Classification of moves, extensions and truncations. Most values 306;; are as for "type" (see below) but there are also the following 307;; move-specific values: 308;; 309;; constN move an N-constraint integer into a MIPS16 register 310;; sll0 "sll DEST,SRC,0", which on 64-bit targets is guaranteed 311;; to produce a sign-extended DEST, even if SRC is not 312;; properly sign-extended 313;; ext_ins EXT, DEXT, INS or DINS instruction 314;; andi a single ANDI instruction 315;; loadpool move a constant into a MIPS16 register by loading it 316;; from the pool 317;; shift_shift a shift left followed by a shift right 318;; lui_movf an LUI followed by a MOVF (for d<-z CC moves) 319;; 320;; This attribute is used to determine the instruction's length and 321;; scheduling type. For doubleword moves, the attribute always describes 322;; the split instructions; in some cases, it is more appropriate for the 323;; scheduling type to be "multi" instead. 324(define_attr "move_type" 325 "unknown,load,fpload,store,fpstore,mtc,mfc,mthilo,mfhilo,move,fmove, 326 const,constN,signext,ext_ins,logical,arith,sll0,andi,loadpool, 327 shift_shift,lui_movf" 328 (const_string "unknown")) 329 330;; Main data type used by the insn 331(define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF,FPSW" 332 (const_string "unknown")) 333 334;; True if the main data type is twice the size of a word. 335(define_attr "dword_mode" "no,yes" 336 (cond [(and (eq_attr "mode" "DI,DF") 337 (eq (symbol_ref "TARGET_64BIT") (const_int 0))) 338 (const_string "yes") 339 340 (and (eq_attr "mode" "TI,TF") 341 (ne (symbol_ref "TARGET_64BIT") (const_int 0))) 342 (const_string "yes")] 343 (const_string "no"))) 344 345;; Classification of each insn. 346;; branch conditional branch 347;; jump unconditional jump 348;; call unconditional call 349;; load load instruction(s) 350;; fpload floating point load 351;; fpidxload floating point indexed load 352;; store store instruction(s) 353;; fpstore floating point store 354;; fpidxstore floating point indexed store 355;; prefetch memory prefetch (register + offset) 356;; prefetchx memory indexed prefetch (register + register) 357;; condmove conditional moves 358;; mtc transfer to coprocessor 359;; mfc transfer from coprocessor 360;; mthilo transfer to hi/lo registers 361;; mfhilo transfer from hi/lo registers 362;; const load constant 363;; arith integer arithmetic instructions 364;; logical integer logical instructions 365;; shift integer shift instructions 366;; slt set less than instructions 367;; signext sign extend instructions 368;; clz the clz and clo instructions 369;; pop the pop instruction 370;; trap trap if instructions 371;; imul integer multiply 2 operands 372;; imul3 integer multiply 3 operands 373;; imul3nc integer multiply 3 operands without clobbering HI/LO 374;; imadd integer multiply-add 375;; idiv integer divide 2 operands 376;; idiv3 integer divide 3 operands 377;; move integer register move ({,D}ADD{,U} with rt = 0) 378;; fmove floating point register move 379;; fadd floating point add/subtract 380;; fmul floating point multiply 381;; fmadd floating point multiply-add 382;; fdiv floating point divide 383;; frdiv floating point reciprocal divide 384;; frdiv1 floating point reciprocal divide step 1 385;; frdiv2 floating point reciprocal divide step 2 386;; fabs floating point absolute value 387;; fneg floating point negation 388;; fcmp floating point compare 389;; fcvt floating point convert 390;; fsqrt floating point square root 391;; frsqrt floating point reciprocal square root 392;; frsqrt1 floating point reciprocal square root step1 393;; frsqrt2 floating point reciprocal square root step2 394;; multi multiword sequence (or user asm statements) 395;; nop no operation 396;; ghost an instruction that produces no real code 397(define_attr "type" 398 "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore, 399 prefetch,prefetchx,condmove,mtc,mfc,mthilo,mfhilo,const,arith,logical, 400 shift,slt,signext,clz,pop,trap,imul,imul3,imul3nc,imadd,idiv,idiv3,move, 401 fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt, 402 frsqrt,frsqrt1,frsqrt2,multi,nop,ghost" 403 (cond [(eq_attr "jal" "!unset") (const_string "call") 404 (eq_attr "got" "load") (const_string "load") 405 406 ;; If a doubleword move uses these expensive instructions, 407 ;; it is usually better to schedule them in the same way 408 ;; as the singleword form, rather than as "multi". 409 (eq_attr "move_type" "load") (const_string "load") 410 (eq_attr "move_type" "fpload") (const_string "fpload") 411 (eq_attr "move_type" "store") (const_string "store") 412 (eq_attr "move_type" "fpstore") (const_string "fpstore") 413 (eq_attr "move_type" "mtc") (const_string "mtc") 414 (eq_attr "move_type" "mfc") (const_string "mfc") 415 (eq_attr "move_type" "mthilo") (const_string "mthilo") 416 (eq_attr "move_type" "mfhilo") (const_string "mfhilo") 417 418 ;; These types of move are always single insns. 419 (eq_attr "move_type" "fmove") (const_string "fmove") 420 (eq_attr "move_type" "loadpool") (const_string "load") 421 (eq_attr "move_type" "signext") (const_string "signext") 422 (eq_attr "move_type" "ext_ins") (const_string "arith") 423 (eq_attr "move_type" "arith") (const_string "arith") 424 (eq_attr "move_type" "logical") (const_string "logical") 425 (eq_attr "move_type" "sll0") (const_string "shift") 426 (eq_attr "move_type" "andi") (const_string "logical") 427 428 ;; These types of move are always split. 429 (eq_attr "move_type" "constN,shift_shift") 430 (const_string "multi") 431 432 ;; These types of move are split for doubleword modes only. 433 (and (eq_attr "move_type" "move,const") 434 (eq_attr "dword_mode" "yes")) 435 (const_string "multi") 436 (eq_attr "move_type" "move") (const_string "move") 437 (eq_attr "move_type" "const") (const_string "const")] 438 ;; We classify "lui_movf" as "unknown" rather than "multi" 439 ;; because we don't split it. FIXME: we should split instead. 440 (const_string "unknown"))) 441 442;; Mode for conversion types (fcvt) 443;; I2S integer to float single (SI/DI to SF) 444;; I2D integer to float double (SI/DI to DF) 445;; S2I float to integer (SF to SI/DI) 446;; D2I float to integer (DF to SI/DI) 447;; D2S double to float single 448;; S2D float single to double 449 450(define_attr "cnv_mode" "unknown,I2S,I2D,S2I,D2I,D2S,S2D" 451 (const_string "unknown")) 452 453;; Is this an extended instruction in mips16 mode? 454(define_attr "extended_mips16" "no,yes" 455 (if_then_else (ior (eq_attr "move_type" "sll0") 456 (eq_attr "type" "branch") 457 (eq_attr "jal" "direct")) 458 (const_string "yes") 459 (const_string "no"))) 460 461;; Attributes describing a sync loop. These loops have the form: 462;; 463;; if (RELEASE_BARRIER == YES) sync 464;; 1: OLDVAL = *MEM 465;; if ((OLDVAL & INCLUSIVE_MASK) != REQUIRED_OLDVAL) goto 2 466;; $TMP1 = OLDVAL & EXCLUSIVE_MASK 467;; $TMP2 = INSN1 (OLDVAL, INSN1_OP2) 468;; $TMP3 = INSN2 ($TMP2, INCLUSIVE_MASK) 469;; $AT |= $TMP1 | $TMP3 470;; if (!commit (*MEM = $AT)) goto 1. 471;; if (INSN1 != MOVE && INSN1 != LI) NEWVAL = $TMP3 [delay slot] 472;; sync 473;; 2: 474;; 475;; where "$" values are temporaries and where the other values are 476;; specified by the attributes below. Values are specified as operand 477;; numbers and insns are specified as enums. If no operand number is 478;; specified, the following values are used instead: 479;; 480;; - OLDVAL: $AT 481;; - NEWVAL: $AT 482;; - INCLUSIVE_MASK: -1 483;; - REQUIRED_OLDVAL: OLDVAL & INCLUSIVE_MASK 484;; - EXCLUSIVE_MASK: 0 485;; 486;; MEM and INSN1_OP2 are required. 487;; 488;; Ideally, the operand attributes would be integers, with -1 meaning "none", 489;; but the gen* programs don't yet support that. 490(define_attr "sync_mem" "none,0,1,2,3,4,5" (const_string "none")) 491(define_attr "sync_oldval" "none,0,1,2,3,4,5" (const_string "none")) 492(define_attr "sync_newval" "none,0,1,2,3,4,5" (const_string "none")) 493(define_attr "sync_inclusive_mask" "none,0,1,2,3,4,5" (const_string "none")) 494(define_attr "sync_exclusive_mask" "none,0,1,2,3,4,5" (const_string "none")) 495(define_attr "sync_required_oldval" "none,0,1,2,3,4,5" (const_string "none")) 496(define_attr "sync_insn1_op2" "none,0,1,2,3,4,5" (const_string "none")) 497(define_attr "sync_insn1" "move,li,addu,addiu,subu,and,andi,or,ori,xor,xori" 498 (const_string "move")) 499(define_attr "sync_insn2" "nop,and,xor,not" 500 (const_string "nop")) 501(define_attr "sync_release_barrier" "yes,no" 502 (const_string "yes")) 503 504;; Length of instruction in bytes. 505(define_attr "length" "" 506 (cond [(and (eq_attr "extended_mips16" "yes") 507 (ne (symbol_ref "TARGET_MIPS16") (const_int 0))) 508 (const_int 8) 509 510 ;; Direct branch instructions have a range of [-0x20000,0x1fffc], 511 ;; relative to the address of the delay slot. If a branch is 512 ;; outside this range, we have a choice of two sequences. 513 ;; For PIC, an out-of-range branch like: 514 ;; 515 ;; bne r1,r2,target 516 ;; dslot 517 ;; 518 ;; becomes the equivalent of: 519 ;; 520 ;; beq r1,r2,1f 521 ;; dslot 522 ;; la $at,target 523 ;; jr $at 524 ;; nop 525 ;; 1: 526 ;; 527 ;; The non-PIC case is similar except that we use a direct 528 ;; jump instead of an la/jr pair. Since the target of this 529 ;; jump is an absolute 28-bit bit address (the other bits 530 ;; coming from the address of the delay slot) this form cannot 531 ;; cross a 256MB boundary. We could provide the option of 532 ;; using la/jr in this case too, but we do not do so at 533 ;; present. 534 ;; 535 ;; Note that this value does not account for the delay slot 536 ;; instruction, whose length is added separately. If the RTL 537 ;; pattern has no explicit delay slot, mips_adjust_insn_length 538 ;; will add the length of the implicit nop. The values for 539 ;; forward and backward branches will be different as well. 540 (eq_attr "type" "branch") 541 (cond [(and (le (minus (match_dup 0) (pc)) (const_int 131064)) 542 (le (minus (pc) (match_dup 0)) (const_int 131068))) 543 (const_int 4) 544 545 ;; The non-PIC case: branch, first delay slot, and J. 546 (ne (symbol_ref "TARGET_ABSOLUTE_JUMPS") (const_int 0)) 547 (const_int 12)] 548 549 ;; Use MAX_PIC_BRANCH_LENGTH as a (gross) overestimate. 550 ;; mips_adjust_insn_length substitutes the correct length. 551 ;; 552 ;; Note that we can't simply use (symbol_ref ...) here 553 ;; because genattrtab needs to know the maximum length 554 ;; of an insn. 555 (const_int MAX_PIC_BRANCH_LENGTH)) 556 557 ;; "Ghost" instructions occupy no space. 558 (eq_attr "type" "ghost") 559 (const_int 0) 560 561 (eq_attr "got" "load") 562 (if_then_else (ne (symbol_ref "TARGET_MIPS16") (const_int 0)) 563 (const_int 8) 564 (const_int 4)) 565 (eq_attr "got" "xgot_high") 566 (const_int 8) 567 568 ;; In general, constant-pool loads are extended instructions. 569 (eq_attr "move_type" "loadpool") 570 (const_int 8) 571 572 ;; LUI_MOVFs are decomposed into two separate instructions. 573 (eq_attr "move_type" "lui_movf") 574 (const_int 8) 575 576 ;; SHIFT_SHIFTs are decomposed into two separate instructions. 577 ;; They are extended instructions on MIPS16 targets. 578 (eq_attr "move_type" "shift_shift") 579 (if_then_else (ne (symbol_ref "TARGET_MIPS16") (const_int 0)) 580 (const_int 16) 581 (const_int 8)) 582 583 ;; Check for doubleword moves that are decomposed into two 584 ;; instructions. 585 (and (eq_attr "move_type" "mtc,mfc,mthilo,mfhilo,move") 586 (eq_attr "dword_mode" "yes")) 587 (const_int 8) 588 589 ;; Doubleword CONST{,N} moves are split into two word 590 ;; CONST{,N} moves. 591 (and (eq_attr "move_type" "const,constN") 592 (eq_attr "dword_mode" "yes")) 593 (symbol_ref "mips_split_const_insns (operands[1]) * 4") 594 595 ;; Otherwise, constants, loads and stores are handled by external 596 ;; routines. 597 (eq_attr "move_type" "const,constN") 598 (symbol_ref "mips_const_insns (operands[1]) * 4") 599 (eq_attr "move_type" "load,fpload") 600 (symbol_ref "mips_load_store_insns (operands[1], insn) * 4") 601 (eq_attr "move_type" "store,fpstore") 602 (symbol_ref "mips_load_store_insns (operands[0], insn) * 4") 603 604 ;; In the worst case, a call macro will take 8 instructions: 605 ;; 606 ;; lui $25,%call_hi(FOO) 607 ;; addu $25,$25,$28 608 ;; lw $25,%call_lo(FOO)($25) 609 ;; nop 610 ;; jalr $25 611 ;; nop 612 ;; lw $gp,X($sp) 613 ;; nop 614 (eq_attr "jal_macro" "yes") 615 (const_int 32) 616 617 ;; Various VR4120 errata require a nop to be inserted after a macc 618 ;; instruction. The assembler does this for us, so account for 619 ;; the worst-case length here. 620 (and (eq_attr "type" "imadd") 621 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0))) 622 (const_int 8) 623 624 ;; VR4120 errata MD(4): if there are consecutive dmult instructions, 625 ;; the result of the second one is missed. The assembler should work 626 ;; around this by inserting a nop after the first dmult. 627 (and (eq_attr "type" "imul,imul3") 628 (and (eq_attr "mode" "DI") 629 (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))) 630 (const_int 8) 631 632 (eq_attr "type" "idiv,idiv3") 633 (symbol_ref "mips_idiv_insns () * 4") 634 635 (not (eq_attr "sync_mem" "none")) 636 (symbol_ref "mips_sync_loop_insns (insn, operands) * 4") 637 ] (const_int 4))) 638 639;; Attribute describing the processor. This attribute must match exactly 640;; with the processor_type enumeration in mips.h. 641(define_attr "cpu" 642 "r3000,4kc,4kp,5kc,5kf,20kc,24kc,24kf2_1,24kf1_1,74kc,74kf2_1,74kf1_1,74kf3_2,loongson_2e,loongson_2f,m4k,octeon,r3900,r6000,r4000,r4100,r4111,r4120,r4130,r4300,r4600,r4650,r5000,r5400,r5500,r7000,r8000,r9000,r10000,sb1,sb1a,sr71000,xlr" 643 (const (symbol_ref "mips_tune_attr"))) 644 645;; The type of hardware hazard associated with this instruction. 646;; DELAY means that the next instruction cannot read the result 647;; of this one. HILO means that the next two instructions cannot 648;; write to HI or LO. 649(define_attr "hazard" "none,delay,hilo" 650 (cond [(and (eq_attr "type" "load,fpload,fpidxload") 651 (ne (symbol_ref "ISA_HAS_LOAD_DELAY") (const_int 0))) 652 (const_string "delay") 653 654 (and (eq_attr "type" "mfc,mtc") 655 (ne (symbol_ref "ISA_HAS_XFER_DELAY") (const_int 0))) 656 (const_string "delay") 657 658 (and (eq_attr "type" "fcmp") 659 (ne (symbol_ref "ISA_HAS_FCMP_DELAY") (const_int 0))) 660 (const_string "delay") 661 662 ;; The r4000 multiplication patterns include an mflo instruction. 663 (and (eq_attr "type" "imul") 664 (ne (symbol_ref "TARGET_FIX_R4000") (const_int 0))) 665 (const_string "hilo") 666 667 (and (eq_attr "type" "mfhilo") 668 (eq (symbol_ref "ISA_HAS_HILO_INTERLOCKS") (const_int 0))) 669 (const_string "hilo")] 670 (const_string "none"))) 671 672;; Is it a single instruction? 673(define_attr "single_insn" "no,yes" 674 (symbol_ref "(get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4) 675 ? SINGLE_INSN_YES : SINGLE_INSN_NO)")) 676 677;; Can the instruction be put into a delay slot? 678(define_attr "can_delay" "no,yes" 679 (if_then_else (and (eq_attr "type" "!branch,call,jump") 680 (and (eq_attr "hazard" "none") 681 (eq_attr "single_insn" "yes"))) 682 (const_string "yes") 683 (const_string "no"))) 684 685;; Attribute defining whether or not we can use the branch-likely 686;; instructions. 687(define_attr "branch_likely" "no,yes" 688 (if_then_else (ne (symbol_ref "GENERATE_BRANCHLIKELY") (const_int 0)) 689 (const_string "yes") 690 (const_string "no"))) 691 692;; True if an instruction might assign to hi or lo when reloaded. 693;; This is used by the TUNE_MACC_CHAINS code. 694(define_attr "may_clobber_hilo" "no,yes" 695 (if_then_else (eq_attr "type" "imul,imul3,imadd,idiv,mthilo") 696 (const_string "yes") 697 (const_string "no"))) 698 699;; Describe a user's asm statement. 700(define_asm_attributes 701 [(set_attr "type" "multi") 702 (set_attr "can_delay" "no")]) 703 704;; This mode iterator allows 32-bit and 64-bit GPR patterns to be generated 705;; from the same template. 706(define_mode_iterator GPR [SI (DI "TARGET_64BIT")]) 707 708;; A copy of GPR that can be used when a pattern has two independent 709;; modes. 710(define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")]) 711 712;; This mode iterator allows :HILO to be used as the mode of the 713;; concatenated HI and LO registers. 714(define_mode_iterator HILO [(DI "!TARGET_64BIT") (TI "TARGET_64BIT")]) 715 716;; This mode iterator allows :P to be used for patterns that operate on 717;; pointer-sized quantities. Exactly one of the two alternatives will match. 718(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) 719 720;; This mode iterator allows :MOVECC to be used anywhere that a 721;; conditional-move-type condition is needed. 722(define_mode_iterator MOVECC [SI (DI "TARGET_64BIT") 723 (CC "TARGET_HARD_FLOAT && !TARGET_LOONGSON_2EF")]) 724 725;; 32-bit integer moves for which we provide move patterns. 726(define_mode_iterator IMOVE32 727 [SI 728 (V2HI "TARGET_DSP") 729 (V4QI "TARGET_DSP") 730 (V2HQ "TARGET_DSP") 731 (V2UHQ "TARGET_DSP") 732 (V2HA "TARGET_DSP") 733 (V2UHA "TARGET_DSP") 734 (V4QQ "TARGET_DSP") 735 (V4UQQ "TARGET_DSP")]) 736 737;; 64-bit modes for which we provide move patterns. 738(define_mode_iterator MOVE64 739 [DI DF 740 (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT") 741 (V2SI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS") 742 (V4HI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS") 743 (V8QI "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS")]) 744 745;; 128-bit modes for which we provide move patterns on 64-bit targets. 746(define_mode_iterator MOVE128 [TI TF]) 747 748;; This mode iterator allows the QI and HI extension patterns to be 749;; defined from the same template. 750(define_mode_iterator SHORT [QI HI]) 751 752;; Likewise the 64-bit truncate-and-shift patterns. 753(define_mode_iterator SUBDI [QI HI SI]) 754 755;; This mode iterator allows :ANYF to be used wherever a scalar or vector 756;; floating-point mode is allowed. 757(define_mode_iterator ANYF [(SF "TARGET_HARD_FLOAT") 758 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT") 759 (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")]) 760 761;; Like ANYF, but only applies to scalar modes. 762(define_mode_iterator SCALARF [(SF "TARGET_HARD_FLOAT") 763 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")]) 764 765;; A floating-point mode for which moves involving FPRs may need to be split. 766(define_mode_iterator SPLITF 767 [(DF "!TARGET_64BIT && TARGET_DOUBLE_FLOAT") 768 (DI "!TARGET_64BIT && TARGET_DOUBLE_FLOAT") 769 (V2SF "!TARGET_64BIT && TARGET_PAIRED_SINGLE_FLOAT") 770 (V2SI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS") 771 (V4HI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS") 772 (V8QI "!TARGET_64BIT && TARGET_LOONGSON_VECTORS") 773 (TF "TARGET_64BIT && TARGET_FLOAT64")]) 774 775;; In GPR templates, a string like "<d>subu" will expand to "subu" in the 776;; 32-bit version and "dsubu" in the 64-bit version. 777(define_mode_attr d [(SI "") (DI "d") 778 (QQ "") (HQ "") (SQ "") (DQ "d") 779 (UQQ "") (UHQ "") (USQ "") (UDQ "d") 780 (HA "") (SA "") (DA "d") 781 (UHA "") (USA "") (UDA "d")]) 782 783;; Same as d but upper-case. 784(define_mode_attr D [(SI "") (DI "D") 785 (QQ "") (HQ "") (SQ "") (DQ "D") 786 (UQQ "") (UHQ "") (USQ "") (UDQ "D") 787 (HA "") (SA "") (DA "D") 788 (UHA "") (USA "") (UDA "D")]) 789 790;; This attribute gives the length suffix for a sign- or zero-extension 791;; instruction. 792(define_mode_attr size [(QI "b") (HI "h")]) 793 794;; This attributes gives the mode mask of a SHORT. 795(define_mode_attr mask [(QI "0x00ff") (HI "0xffff")]) 796 797;; Mode attributes for GPR loads. 798(define_mode_attr load [(SI "lw") (DI "ld")]) 799;; Instruction names for stores. 800(define_mode_attr store [(QI "sb") (HI "sh") (SI "sw") (DI "sd")]) 801 802;; Similarly for MIPS IV indexed FPR loads and stores. 803(define_mode_attr loadx [(SF "lwxc1") (DF "ldxc1") (V2SF "ldxc1")]) 804(define_mode_attr storex [(SF "swxc1") (DF "sdxc1") (V2SF "sdxc1")]) 805 806;; The unextended ranges of the MIPS16 addiu and daddiu instructions 807;; are different. Some forms of unextended addiu have an 8-bit immediate 808;; field but the equivalent daddiu has only a 5-bit field. 809(define_mode_attr si8_di5 [(SI "8") (DI "5")]) 810 811;; This attribute gives the best constraint to use for registers of 812;; a given mode. 813(define_mode_attr reg [(SI "d") (DI "d") (CC "z")]) 814 815;; This attribute gives the format suffix for floating-point operations. 816(define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")]) 817 818;; This attribute gives the upper-case mode name for one unit of a 819;; floating-point mode. 820(define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")]) 821 822;; This attribute gives the integer mode that has the same size as a 823;; fixed-point mode. 824(define_mode_attr IMODE [(QQ "QI") (HQ "HI") (SQ "SI") (DQ "DI") 825 (UQQ "QI") (UHQ "HI") (USQ "SI") (UDQ "DI") 826 (HA "HI") (SA "SI") (DA "DI") 827 (UHA "HI") (USA "SI") (UDA "DI") 828 (V4UQQ "SI") (V2UHQ "SI") (V2UHA "SI") 829 (V2HQ "SI") (V2HA "SI")]) 830 831;; This attribute gives the integer mode that has half the size of 832;; the controlling mode. 833(define_mode_attr HALFMODE [(DF "SI") (DI "SI") (V2SF "SI") 834 (V2SI "SI") (V4HI "SI") (V8QI "SI") 835 (TF "DI")]) 836 837;; This attribute works around the early SB-1 rev2 core "F2" erratum: 838;; 839;; In certain cases, div.s and div.ps may have a rounding error 840;; and/or wrong inexact flag. 841;; 842;; Therefore, we only allow div.s if not working around SB-1 rev2 843;; errata or if a slight loss of precision is OK. 844(define_mode_attr divide_condition 845 [DF (SF "!TARGET_FIX_SB1 || flag_unsafe_math_optimizations") 846 (V2SF "TARGET_SB1 && (!TARGET_FIX_SB1 || flag_unsafe_math_optimizations)")]) 847 848;; This attribute gives the conditions under which SQRT.fmt instructions 849;; can be used. 850(define_mode_attr sqrt_condition 851 [(SF "!ISA_MIPS1") (DF "!ISA_MIPS1") (V2SF "TARGET_SB1")]) 852 853;; This attribute gives the conditions under which RECIP.fmt and RSQRT.fmt 854;; instructions can be used. The MIPS32 and MIPS64 ISAs say that RECIP.D 855;; and RSQRT.D are unpredictable when doubles are stored in pairs of FPRs, 856;; so for safety's sake, we apply this restriction to all targets. 857(define_mode_attr recip_condition 858 [(SF "ISA_HAS_FP4") 859 (DF "ISA_HAS_FP4 && TARGET_FLOAT64") 860 (V2SF "TARGET_SB1")]) 861 862;; This code iterator allows signed and unsigned widening multiplications 863;; to use the same template. 864(define_code_iterator any_extend [sign_extend zero_extend]) 865 866;; This code iterator allows the two right shift instructions to be 867;; generated from the same template. 868(define_code_iterator any_shiftrt [ashiftrt lshiftrt]) 869 870;; This code iterator allows the three shift instructions to be generated 871;; from the same template. 872(define_code_iterator any_shift [ashift ashiftrt lshiftrt]) 873 874;; This code iterator allows unsigned and signed division to be generated 875;; from the same template. 876(define_code_iterator any_div [div udiv]) 877 878;; This code iterator allows unsigned and signed modulus to be generated 879;; from the same template. 880(define_code_iterator any_mod [mod umod]) 881 882;; This code iterator allows all native floating-point comparisons to be 883;; generated from the same template. 884(define_code_iterator fcond [unordered uneq unlt unle eq lt le]) 885 886;; This code iterator is used for comparisons that can be implemented 887;; by swapping the operands. 888(define_code_iterator swapped_fcond [ge gt unge ungt]) 889 890;; Equality operators. 891(define_code_iterator equality_op [eq ne]) 892 893;; These code iterators allow the signed and unsigned scc operations to use 894;; the same template. 895(define_code_iterator any_gt [gt gtu]) 896(define_code_iterator any_ge [ge geu]) 897(define_code_iterator any_lt [lt ltu]) 898(define_code_iterator any_le [le leu]) 899 900;; <u> expands to an empty string when doing a signed operation and 901;; "u" when doing an unsigned operation. 902(define_code_attr u [(sign_extend "") (zero_extend "u") 903 (div "") (udiv "u") 904 (mod "") (umod "u") 905 (gt "") (gtu "u") 906 (ge "") (geu "u") 907 (lt "") (ltu "u") 908 (le "") (leu "u")]) 909 910;; <su> is like <u>, but the signed form expands to "s" rather than "". 911(define_code_attr su [(sign_extend "s") (zero_extend "u")]) 912 913;; <optab> expands to the name of the optab for a particular code. 914(define_code_attr optab [(ashift "ashl") 915 (ashiftrt "ashr") 916 (lshiftrt "lshr") 917 (ior "ior") 918 (xor "xor") 919 (and "and") 920 (plus "add") 921 (minus "sub")]) 922 923;; <insn> expands to the name of the insn that implements a particular code. 924(define_code_attr insn [(ashift "sll") 925 (ashiftrt "sra") 926 (lshiftrt "srl") 927 (ior "or") 928 (xor "xor") 929 (and "and") 930 (plus "addu") 931 (minus "subu")]) 932 933;; <immediate_insn> expands to the name of the insn that implements 934;; a particular code to operate on immediate values. 935(define_code_attr immediate_insn [(ior "ori") 936 (xor "xori") 937 (and "andi")]) 938 939;; <fcond> is the c.cond.fmt condition associated with a particular code. 940(define_code_attr fcond [(unordered "un") 941 (uneq "ueq") 942 (unlt "ult") 943 (unle "ule") 944 (eq "eq") 945 (lt "lt") 946 (le "le")]) 947 948;; Similar, but for swapped conditions. 949(define_code_attr swapped_fcond [(ge "le") 950 (gt "lt") 951 (unge "ule") 952 (ungt "ult")]) 953 954;; The value of the bit when the branch is taken for branch_bit patterns. 955;; Comparison is always against zero so this depends on the operator. 956(define_code_attr bbv [(eq "0") (ne "1")]) 957 958;; This is the inverse value of bbv. 959(define_code_attr bbinv [(eq "1") (ne "0")]) 960 961;; ......................... 962;; 963;; Branch, call and jump delay slots 964;; 965;; ......................... 966 967(define_delay (and (eq_attr "type" "branch") 968 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)) 969 (eq_attr "branch_likely" "yes")) 970 [(eq_attr "can_delay" "yes") 971 (nil) 972 (eq_attr "can_delay" "yes")]) 973 974;; Branches that don't have likely variants do not annul on false. 975(define_delay (and (eq_attr "type" "branch") 976 (eq (symbol_ref "TARGET_MIPS16") (const_int 0)) 977 (eq_attr "branch_likely" "no")) 978 [(eq_attr "can_delay" "yes") 979 (nil) 980 (nil)]) 981 982(define_delay (eq_attr "type" "jump") 983 [(eq_attr "can_delay" "yes") 984 (nil) 985 (nil)]) 986 987(define_delay (and (eq_attr "type" "call") 988 (eq_attr "jal_macro" "no")) 989 [(eq_attr "can_delay" "yes") 990 (nil) 991 (nil)]) 992 993;; Pipeline descriptions. 994;; 995;; generic.md provides a fallback for processors without a specific 996;; pipeline description. It is derived from the old define_function_unit 997;; version and uses the "alu" and "imuldiv" units declared below. 998;; 999;; Some of the processor-specific files are also derived from old 1000;; define_function_unit descriptions and simply override the parts of 1001;; generic.md that don't apply. The other processor-specific files 1002;; are self-contained. 1003(define_automaton "alu,imuldiv") 1004 1005(define_cpu_unit "alu" "alu") 1006(define_cpu_unit "imuldiv" "imuldiv") 1007 1008;; Ghost instructions produce no real code and introduce no hazards. 1009;; They exist purely to express an effect on dataflow. 1010(define_insn_reservation "ghost" 0 1011 (eq_attr "type" "ghost") 1012 "nothing") 1013 1014(include "4k.md") 1015(include "5k.md") 1016(include "20kc.md") 1017(include "24k.md") 1018(include "74k.md") 1019(include "3000.md") 1020(include "4000.md") 1021(include "4100.md") 1022(include "4130.md") 1023(include "4300.md") 1024(include "4600.md") 1025(include "5000.md") 1026(include "5400.md") 1027(include "5500.md") 1028(include "6000.md") 1029(include "7000.md") 1030(include "9000.md") 1031(include "10000.md") 1032(include "loongson2ef.md") 1033(include "octeon.md") 1034(include "sb1.md") 1035(include "sr71k.md") 1036(include "xlr.md") 1037(include "generic.md") 1038 1039;; 1040;; .................... 1041;; 1042;; CONDITIONAL TRAPS 1043;; 1044;; .................... 1045;; 1046 1047(define_insn "trap" 1048 [(trap_if (const_int 1) (const_int 0))] 1049 "" 1050{ 1051 if (ISA_HAS_COND_TRAP) 1052 return "teq\t$0,$0"; 1053 else if (TARGET_MIPS16) 1054 return "break 0"; 1055 else 1056 return "break"; 1057} 1058 [(set_attr "type" "trap")]) 1059 1060(define_expand "ctrap<mode>4" 1061 [(trap_if (match_operator 0 "comparison_operator" 1062 [(match_operand:GPR 1 "reg_or_0_operand") 1063 (match_operand:GPR 2 "arith_operand")]) 1064 (match_operand 3 "const_0_operand"))] 1065 "ISA_HAS_COND_TRAP" 1066{ 1067 mips_expand_conditional_trap (operands[0]); 1068 DONE; 1069}) 1070 1071(define_insn "*conditional_trap<mode>" 1072 [(trap_if (match_operator:GPR 0 "trap_comparison_operator" 1073 [(match_operand:GPR 1 "reg_or_0_operand" "dJ") 1074 (match_operand:GPR 2 "arith_operand" "dI")]) 1075 (const_int 0))] 1076 "ISA_HAS_COND_TRAP" 1077 "t%C0\t%z1,%2" 1078 [(set_attr "type" "trap")]) 1079 1080;; 1081;; .................... 1082;; 1083;; ADDITION 1084;; 1085;; .................... 1086;; 1087 1088(define_insn "add<mode>3" 1089 [(set (match_operand:ANYF 0 "register_operand" "=f") 1090 (plus:ANYF (match_operand:ANYF 1 "register_operand" "f") 1091 (match_operand:ANYF 2 "register_operand" "f")))] 1092 "" 1093 "add.<fmt>\t%0,%1,%2" 1094 [(set_attr "type" "fadd") 1095 (set_attr "mode" "<UNITMODE>")]) 1096 1097(define_expand "add<mode>3" 1098 [(set (match_operand:GPR 0 "register_operand") 1099 (plus:GPR (match_operand:GPR 1 "register_operand") 1100 (match_operand:GPR 2 "arith_operand")))] 1101 "") 1102 1103(define_insn "*add<mode>3" 1104 [(set (match_operand:GPR 0 "register_operand" "=d,d") 1105 (plus:GPR (match_operand:GPR 1 "register_operand" "d,d") 1106 (match_operand:GPR 2 "arith_operand" "d,Q")))] 1107 "!TARGET_MIPS16" 1108 "@ 1109 <d>addu\t%0,%1,%2 1110 <d>addiu\t%0,%1,%2" 1111 [(set_attr "type" "arith") 1112 (set_attr "mode" "<MODE>")]) 1113 1114(define_insn "*add<mode>3_mips16" 1115 [(set (match_operand:GPR 0 "register_operand" "=ks,d,d,d,d") 1116 (plus:GPR (match_operand:GPR 1 "register_operand" "ks,ks,0,d,d") 1117 (match_operand:GPR 2 "arith_operand" "Q,Q,Q,O,d")))] 1118 "TARGET_MIPS16" 1119 "@ 1120 <d>addiu\t%0,%2 1121 <d>addiu\t%0,%1,%2 1122 <d>addiu\t%0,%2 1123 <d>addiu\t%0,%1,%2 1124 <d>addu\t%0,%1,%2" 1125 [(set_attr "type" "arith") 1126 (set_attr "mode" "<MODE>") 1127 (set_attr_alternative "length" 1128 [(if_then_else (match_operand 2 "m16_simm8_8") 1129 (const_int 4) 1130 (const_int 8)) 1131 (if_then_else (match_operand 2 "m16_uimm<si8_di5>_4") 1132 (const_int 4) 1133 (const_int 8)) 1134 (if_then_else (match_operand 2 "m16_simm<si8_di5>_1") 1135 (const_int 4) 1136 (const_int 8)) 1137 (if_then_else (match_operand 2 "m16_simm4_1") 1138 (const_int 4) 1139 (const_int 8)) 1140 (const_int 4)])]) 1141 1142;; On the mips16, we can sometimes split an add of a constant which is 1143;; a 4 byte instruction into two adds which are both 2 byte 1144;; instructions. There are two cases: one where we are adding a 1145;; constant plus a register to another register, and one where we are 1146;; simply adding a constant to a register. 1147 1148(define_split 1149 [(set (match_operand:SI 0 "d_operand") 1150 (plus:SI (match_dup 0) 1151 (match_operand:SI 1 "const_int_operand")))] 1152 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE 1153 && ((INTVAL (operands[1]) > 0x7f 1154 && INTVAL (operands[1]) <= 0x7f + 0x7f) 1155 || (INTVAL (operands[1]) < - 0x80 1156 && INTVAL (operands[1]) >= - 0x80 - 0x80))" 1157 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) 1158 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))] 1159{ 1160 HOST_WIDE_INT val = INTVAL (operands[1]); 1161 1162 if (val >= 0) 1163 { 1164 operands[1] = GEN_INT (0x7f); 1165 operands[2] = GEN_INT (val - 0x7f); 1166 } 1167 else 1168 { 1169 operands[1] = GEN_INT (- 0x80); 1170 operands[2] = GEN_INT (val + 0x80); 1171 } 1172}) 1173 1174(define_split 1175 [(set (match_operand:SI 0 "d_operand") 1176 (plus:SI (match_operand:SI 1 "d_operand") 1177 (match_operand:SI 2 "const_int_operand")))] 1178 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE 1179 && REGNO (operands[0]) != REGNO (operands[1]) 1180 && ((INTVAL (operands[2]) > 0x7 1181 && INTVAL (operands[2]) <= 0x7 + 0x7f) 1182 || (INTVAL (operands[2]) < - 0x8 1183 && INTVAL (operands[2]) >= - 0x8 - 0x80))" 1184 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2))) 1185 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))] 1186{ 1187 HOST_WIDE_INT val = INTVAL (operands[2]); 1188 1189 if (val >= 0) 1190 { 1191 operands[2] = GEN_INT (0x7); 1192 operands[3] = GEN_INT (val - 0x7); 1193 } 1194 else 1195 { 1196 operands[2] = GEN_INT (- 0x8); 1197 operands[3] = GEN_INT (val + 0x8); 1198 } 1199}) 1200 1201(define_split 1202 [(set (match_operand:DI 0 "d_operand") 1203 (plus:DI (match_dup 0) 1204 (match_operand:DI 1 "const_int_operand")))] 1205 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE 1206 && ((INTVAL (operands[1]) > 0xf 1207 && INTVAL (operands[1]) <= 0xf + 0xf) 1208 || (INTVAL (operands[1]) < - 0x10 1209 && INTVAL (operands[1]) >= - 0x10 - 0x10))" 1210 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1))) 1211 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))] 1212{ 1213 HOST_WIDE_INT val = INTVAL (operands[1]); 1214 1215 if (val >= 0) 1216 { 1217 operands[1] = GEN_INT (0xf); 1218 operands[2] = GEN_INT (val - 0xf); 1219 } 1220 else 1221 { 1222 operands[1] = GEN_INT (- 0x10); 1223 operands[2] = GEN_INT (val + 0x10); 1224 } 1225}) 1226 1227(define_split 1228 [(set (match_operand:DI 0 "d_operand") 1229 (plus:DI (match_operand:DI 1 "d_operand") 1230 (match_operand:DI 2 "const_int_operand")))] 1231 "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE 1232 && REGNO (operands[0]) != REGNO (operands[1]) 1233 && ((INTVAL (operands[2]) > 0x7 1234 && INTVAL (operands[2]) <= 0x7 + 0xf) 1235 || (INTVAL (operands[2]) < - 0x8 1236 && INTVAL (operands[2]) >= - 0x8 - 0x10))" 1237 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2))) 1238 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] 1239{ 1240 HOST_WIDE_INT val = INTVAL (operands[2]); 1241 1242 if (val >= 0) 1243 { 1244 operands[2] = GEN_INT (0x7); 1245 operands[3] = GEN_INT (val - 0x7); 1246 } 1247 else 1248 { 1249 operands[2] = GEN_INT (- 0x8); 1250 operands[3] = GEN_INT (val + 0x8); 1251 } 1252}) 1253 1254(define_insn "*addsi3_extended" 1255 [(set (match_operand:DI 0 "register_operand" "=d,d") 1256 (sign_extend:DI 1257 (plus:SI (match_operand:SI 1 "register_operand" "d,d") 1258 (match_operand:SI 2 "arith_operand" "d,Q"))))] 1259 "TARGET_64BIT && !TARGET_MIPS16" 1260 "@ 1261 addu\t%0,%1,%2 1262 addiu\t%0,%1,%2" 1263 [(set_attr "type" "arith") 1264 (set_attr "mode" "SI")]) 1265 1266;; Split this insn so that the addiu splitters can have a crack at it. 1267;; Use a conservative length estimate until the split. 1268(define_insn_and_split "*addsi3_extended_mips16" 1269 [(set (match_operand:DI 0 "register_operand" "=d,d,d") 1270 (sign_extend:DI 1271 (plus:SI (match_operand:SI 1 "register_operand" "0,d,d") 1272 (match_operand:SI 2 "arith_operand" "Q,O,d"))))] 1273 "TARGET_64BIT && TARGET_MIPS16" 1274 "#" 1275 "&& reload_completed" 1276 [(set (match_dup 3) (plus:SI (match_dup 1) (match_dup 2)))] 1277 { operands[3] = gen_lowpart (SImode, operands[0]); } 1278 [(set_attr "type" "arith") 1279 (set_attr "mode" "SI") 1280 (set_attr "extended_mips16" "yes")]) 1281 1282;; Combiner patterns for unsigned byte-add. 1283 1284(define_insn "*baddu_si_eb" 1285 [(set (match_operand:SI 0 "register_operand" "=d") 1286 (zero_extend:SI 1287 (subreg:QI 1288 (plus:SI (match_operand:SI 1 "register_operand" "d") 1289 (match_operand:SI 2 "register_operand" "d")) 3)))] 1290 "ISA_HAS_BADDU && BYTES_BIG_ENDIAN" 1291 "baddu\\t%0,%1,%2" 1292 [(set_attr "type" "arith")]) 1293 1294(define_insn "*baddu_si_el" 1295 [(set (match_operand:SI 0 "register_operand" "=d") 1296 (zero_extend:SI 1297 (subreg:QI 1298 (plus:SI (match_operand:SI 1 "register_operand" "d") 1299 (match_operand:SI 2 "register_operand" "d")) 0)))] 1300 "ISA_HAS_BADDU && !BYTES_BIG_ENDIAN" 1301 "baddu\\t%0,%1,%2" 1302 [(set_attr "type" "arith")]) 1303 1304(define_insn "*baddu_di<mode>" 1305 [(set (match_operand:GPR 0 "register_operand" "=d") 1306 (zero_extend:GPR 1307 (truncate:QI 1308 (plus:DI (match_operand:DI 1 "register_operand" "d") 1309 (match_operand:DI 2 "register_operand" "d")))))] 1310 "ISA_HAS_BADDU && TARGET_64BIT" 1311 "baddu\\t%0,%1,%2" 1312 [(set_attr "type" "arith")]) 1313 1314;; 1315;; .................... 1316;; 1317;; SUBTRACTION 1318;; 1319;; .................... 1320;; 1321 1322(define_insn "sub<mode>3" 1323 [(set (match_operand:ANYF 0 "register_operand" "=f") 1324 (minus:ANYF (match_operand:ANYF 1 "register_operand" "f") 1325 (match_operand:ANYF 2 "register_operand" "f")))] 1326 "" 1327 "sub.<fmt>\t%0,%1,%2" 1328 [(set_attr "type" "fadd") 1329 (set_attr "mode" "<UNITMODE>")]) 1330 1331(define_insn "sub<mode>3" 1332 [(set (match_operand:GPR 0 "register_operand" "=d") 1333 (minus:GPR (match_operand:GPR 1 "register_operand" "d") 1334 (match_operand:GPR 2 "register_operand" "d")))] 1335 "" 1336 "<d>subu\t%0,%1,%2" 1337 [(set_attr "type" "arith") 1338 (set_attr "mode" "<MODE>")]) 1339 1340(define_insn "*subsi3_extended" 1341 [(set (match_operand:DI 0 "register_operand" "=d") 1342 (sign_extend:DI 1343 (minus:SI (match_operand:SI 1 "register_operand" "d") 1344 (match_operand:SI 2 "register_operand" "d"))))] 1345 "TARGET_64BIT" 1346 "subu\t%0,%1,%2" 1347 [(set_attr "type" "arith") 1348 (set_attr "mode" "DI")]) 1349 1350;; 1351;; .................... 1352;; 1353;; MULTIPLICATION 1354;; 1355;; .................... 1356;; 1357 1358(define_expand "mul<mode>3" 1359 [(set (match_operand:SCALARF 0 "register_operand") 1360 (mult:SCALARF (match_operand:SCALARF 1 "register_operand") 1361 (match_operand:SCALARF 2 "register_operand")))] 1362 "" 1363 "") 1364 1365(define_insn "*mul<mode>3" 1366 [(set (match_operand:SCALARF 0 "register_operand" "=f") 1367 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f") 1368 (match_operand:SCALARF 2 "register_operand" "f")))] 1369 "!TARGET_4300_MUL_FIX" 1370 "mul.<fmt>\t%0,%1,%2" 1371 [(set_attr "type" "fmul") 1372 (set_attr "mode" "<MODE>")]) 1373 1374;; Early VR4300 silicon has a CPU bug where multiplies with certain 1375;; operands may corrupt immediately following multiplies. This is a 1376;; simple fix to insert NOPs. 1377 1378(define_insn "*mul<mode>3_r4300" 1379 [(set (match_operand:SCALARF 0 "register_operand" "=f") 1380 (mult:SCALARF (match_operand:SCALARF 1 "register_operand" "f") 1381 (match_operand:SCALARF 2 "register_operand" "f")))] 1382 "TARGET_4300_MUL_FIX" 1383 "mul.<fmt>\t%0,%1,%2\;nop" 1384 [(set_attr "type" "fmul") 1385 (set_attr "mode" "<MODE>") 1386 (set_attr "length" "8")]) 1387 1388(define_insn "mulv2sf3" 1389 [(set (match_operand:V2SF 0 "register_operand" "=f") 1390 (mult:V2SF (match_operand:V2SF 1 "register_operand" "f") 1391 (match_operand:V2SF 2 "register_operand" "f")))] 1392 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT" 1393 "mul.ps\t%0,%1,%2" 1394 [(set_attr "type" "fmul") 1395 (set_attr "mode" "SF")]) 1396 1397;; The original R4000 has a cpu bug. If a double-word or a variable 1398;; shift executes while an integer multiplication is in progress, the 1399;; shift may give an incorrect result. Avoid this by keeping the mflo 1400;; with the mult on the R4000. 1401;; 1402;; From "MIPS R4000PC/SC Errata, Processor Revision 2.2 and 3.0" 1403;; (also valid for MIPS R4000MC processors): 1404;; 1405;; "16. R4000PC, R4000SC: Please refer to errata 28 for an update to 1406;; this errata description. 1407;; The following code sequence causes the R4000 to incorrectly 1408;; execute the Double Shift Right Arithmetic 32 (dsra32) 1409;; instruction. If the dsra32 instruction is executed during an 1410;; integer multiply, the dsra32 will only shift by the amount in 1411;; specified in the instruction rather than the amount plus 32 1412;; bits. 1413;; instruction 1: mult rs,rt integer multiply 1414;; instruction 2-12: dsra32 rd,rt,rs doubleword shift 1415;; right arithmetic + 32 1416;; Workaround: A dsra32 instruction placed after an integer 1417;; multiply should not be one of the 11 instructions after the 1418;; multiply instruction." 1419;; 1420;; and: 1421;; 1422;; "28. R4000PC, R4000SC: The text from errata 16 should be replaced by 1423;; the following description. 1424;; All extended shifts (shift by n+32) and variable shifts (32 and 1425;; 64-bit versions) may produce incorrect results under the 1426;; following conditions: 1427;; 1) An integer multiply is currently executing 1428;; 2) These types of shift instructions are executed immediately 1429;; following an integer divide instruction. 1430;; Workaround: 1431;; 1) Make sure no integer multiply is running wihen these 1432;; instruction are executed. If this cannot be predicted at 1433;; compile time, then insert a "mfhi" to R0 instruction 1434;; immediately after the integer multiply instruction. This 1435;; will cause the integer multiply to complete before the shift 1436;; is executed. 1437;; 2) Separate integer divide and these two classes of shift 1438;; instructions by another instruction or a noop." 1439;; 1440;; These processors have PRId values of 0x00004220 and 0x00004300, 1441;; respectively. 1442 1443(define_expand "mul<mode>3" 1444 [(set (match_operand:GPR 0 "register_operand") 1445 (mult:GPR (match_operand:GPR 1 "register_operand") 1446 (match_operand:GPR 2 "register_operand")))] 1447 "" 1448{ 1449 if (TARGET_LOONGSON_2EF) 1450 emit_insn (gen_mul<mode>3_mul3_ls2ef (operands[0], operands[1], 1451 operands[2])); 1452 else if (ISA_HAS_<D>MUL3) 1453 emit_insn (gen_mul<mode>3_mul3 (operands[0], operands[1], operands[2])); 1454 else if (TARGET_FIX_R4000) 1455 emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2])); 1456 else 1457 emit_insn 1458 (gen_mul<mode>3_internal (operands[0], operands[1], operands[2])); 1459 DONE; 1460}) 1461 1462(define_insn "mul<mode>3_mul3_ls2ef" 1463 [(set (match_operand:GPR 0 "register_operand" "=d") 1464 (mult:GPR (match_operand:GPR 1 "register_operand" "d") 1465 (match_operand:GPR 2 "register_operand" "d")))] 1466 "TARGET_LOONGSON_2EF" 1467 "<d>multu.g\t%0,%1,%2" 1468 [(set_attr "type" "imul3nc") 1469 (set_attr "mode" "<MODE>")]) 1470 1471(define_insn "mul<mode>3_mul3" 1472 [(set (match_operand:GPR 0 "register_operand" "=d,l") 1473 (mult:GPR (match_operand:GPR 1 "register_operand" "d,d") 1474 (match_operand:GPR 2 "register_operand" "d,d"))) 1475 (clobber (match_scratch:GPR 3 "=l,X"))] 1476 "ISA_HAS_<D>MUL3" 1477{ 1478 if (which_alternative == 1) 1479 return "<d>mult\t%1,%2"; 1480 if (<MODE>mode == SImode && TARGET_MIPS3900) 1481 return "mult\t%0,%1,%2"; 1482 return "<d>mul\t%0,%1,%2"; 1483} 1484 [(set_attr "type" "imul3,imul") 1485 (set_attr "mode" "<MODE>")]) 1486 1487;; If a register gets allocated to LO, and we spill to memory, the reload 1488;; will include a move from LO to a GPR. Merge it into the multiplication 1489;; if it can set the GPR directly. 1490;; 1491;; Operand 0: LO 1492;; Operand 1: GPR (1st multiplication operand) 1493;; Operand 2: GPR (2nd multiplication operand) 1494;; Operand 3: GPR (destination) 1495(define_peephole2 1496 [(parallel 1497 [(set (match_operand:SI 0 "lo_operand") 1498 (mult:SI (match_operand:SI 1 "d_operand") 1499 (match_operand:SI 2 "d_operand"))) 1500 (clobber (scratch:SI))]) 1501 (set (match_operand:SI 3 "d_operand") 1502 (match_dup 0))] 1503 "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[0])" 1504 [(parallel 1505 [(set (match_dup 3) 1506 (mult:SI (match_dup 1) 1507 (match_dup 2))) 1508 (clobber (match_dup 0))])]) 1509 1510(define_insn "mul<mode>3_internal" 1511 [(set (match_operand:GPR 0 "register_operand" "=l") 1512 (mult:GPR (match_operand:GPR 1 "register_operand" "d") 1513 (match_operand:GPR 2 "register_operand" "d")))] 1514 "!TARGET_FIX_R4000" 1515 "<d>mult\t%1,%2" 1516 [(set_attr "type" "imul") 1517 (set_attr "mode" "<MODE>")]) 1518 1519(define_insn "mul<mode>3_r4000" 1520 [(set (match_operand:GPR 0 "register_operand" "=d") 1521 (mult:GPR (match_operand:GPR 1 "register_operand" "d") 1522 (match_operand:GPR 2 "register_operand" "d"))) 1523 (clobber (match_scratch:GPR 3 "=l"))] 1524 "TARGET_FIX_R4000" 1525 "<d>mult\t%1,%2\;mflo\t%0" 1526 [(set_attr "type" "imul") 1527 (set_attr "mode" "<MODE>") 1528 (set_attr "length" "8")]) 1529 1530;; On the VR4120 and VR4130, it is better to use "mtlo $0; macc" instead 1531;; of "mult; mflo". They have the same latency, but the first form gives 1532;; us an extra cycle to compute the operands. 1533 1534;; Operand 0: LO 1535;; Operand 1: GPR (1st multiplication operand) 1536;; Operand 2: GPR (2nd multiplication operand) 1537;; Operand 3: GPR (destination) 1538(define_peephole2 1539 [(set (match_operand:SI 0 "lo_operand") 1540 (mult:SI (match_operand:SI 1 "d_operand") 1541 (match_operand:SI 2 "d_operand"))) 1542 (set (match_operand:SI 3 "d_operand") 1543 (match_dup 0))] 1544 "ISA_HAS_MACC && !ISA_HAS_MUL3" 1545 [(set (match_dup 0) 1546 (const_int 0)) 1547 (parallel 1548 [(set (match_dup 0) 1549 (plus:SI (mult:SI (match_dup 1) 1550 (match_dup 2)) 1551 (match_dup 0))) 1552 (set (match_dup 3) 1553 (plus:SI (mult:SI (match_dup 1) 1554 (match_dup 2)) 1555 (match_dup 0)))])]) 1556 1557;; Multiply-accumulate patterns 1558 1559;; This pattern is first matched by combine, which tries to use the 1560;; pattern wherever it can. We don't know until later whether it 1561;; is actually profitable to use MADD over a "MUL; ADDIU" sequence, 1562;; so we need to keep both options open. 1563;; 1564;; The second alternative has a "?" marker because it is generally 1565;; one instruction more costly than the first alternative. This "?" 1566;; marker is enough to convey the relative costs to the register 1567;; allocator. 1568;; 1569;; However, reload counts reloads of operands 4 and 5 in the same way as 1570;; reloads of the other operands, even though operands 4 and 5 need no 1571;; copy instructions. Reload therefore thinks that the second alternative 1572;; is two reloads more costly than the first. We add "*?*?" to the first 1573;; alternative as a counterweight. 1574(define_insn "*mul_acc_si" 1575 [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?") 1576 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d") 1577 (match_operand:SI 2 "register_operand" "d,d")) 1578 (match_operand:SI 3 "register_operand" "0,d"))) 1579 (clobber (match_scratch:SI 4 "=X,l")) 1580 (clobber (match_scratch:SI 5 "=X,&d"))] 1581 "GENERATE_MADD_MSUB && !TARGET_MIPS16" 1582 "@ 1583 madd\t%1,%2 1584 #" 1585 [(set_attr "type" "imadd") 1586 (set_attr "mode" "SI") 1587 (set_attr "length" "4,8")]) 1588 1589;; The same idea applies here. The middle alternative needs one less 1590;; clobber than the final alternative, so we add "*?" as a counterweight. 1591(define_insn "*mul_acc_si_r3900" 1592 [(set (match_operand:SI 0 "register_operand" "=l*?*?,d*?,d?") 1593 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d") 1594 (match_operand:SI 2 "register_operand" "d,d,d")) 1595 (match_operand:SI 3 "register_operand" "0,l,d"))) 1596 (clobber (match_scratch:SI 4 "=X,3,l")) 1597 (clobber (match_scratch:SI 5 "=X,X,&d"))] 1598 "TARGET_MIPS3900 && !TARGET_MIPS16" 1599 "@ 1600 madd\t%1,%2 1601 madd\t%0,%1,%2 1602 #" 1603 [(set_attr "type" "imadd") 1604 (set_attr "mode" "SI") 1605 (set_attr "length" "4,4,8")]) 1606 1607;; Split *mul_acc_si if both the source and destination accumulator 1608;; values are GPRs. 1609(define_split 1610 [(set (match_operand:SI 0 "d_operand") 1611 (plus:SI (mult:SI (match_operand:SI 1 "d_operand") 1612 (match_operand:SI 2 "d_operand")) 1613 (match_operand:SI 3 "d_operand"))) 1614 (clobber (match_operand:SI 4 "lo_operand")) 1615 (clobber (match_operand:SI 5 "d_operand"))] 1616 "reload_completed" 1617 [(parallel [(set (match_dup 5) 1618 (mult:SI (match_dup 1) (match_dup 2))) 1619 (clobber (match_dup 4))]) 1620 (set (match_dup 0) (plus:SI (match_dup 5) (match_dup 3)))] 1621 "") 1622 1623(define_insn "*macc" 1624 [(set (match_operand:SI 0 "register_operand" "=l,d") 1625 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d") 1626 (match_operand:SI 2 "register_operand" "d,d")) 1627 (match_operand:SI 3 "register_operand" "0,l"))) 1628 (clobber (match_scratch:SI 4 "=X,3"))] 1629 "ISA_HAS_MACC" 1630{ 1631 if (which_alternative == 1) 1632 return "macc\t%0,%1,%2"; 1633 else if (TARGET_MIPS5500) 1634 return "madd\t%1,%2"; 1635 else 1636 /* The VR4130 assumes that there is a two-cycle latency between a macc 1637 that "writes" to $0 and an instruction that reads from it. We avoid 1638 this by assigning to $1 instead. */ 1639 return "%[macc\t%@,%1,%2%]"; 1640} 1641 [(set_attr "type" "imadd") 1642 (set_attr "mode" "SI")]) 1643 1644(define_insn "*msac" 1645 [(set (match_operand:SI 0 "register_operand" "=l,d") 1646 (minus:SI (match_operand:SI 1 "register_operand" "0,l") 1647 (mult:SI (match_operand:SI 2 "register_operand" "d,d") 1648 (match_operand:SI 3 "register_operand" "d,d")))) 1649 (clobber (match_scratch:SI 4 "=X,1"))] 1650 "ISA_HAS_MSAC" 1651{ 1652 if (which_alternative == 1) 1653 return "msac\t%0,%2,%3"; 1654 else if (TARGET_MIPS5500) 1655 return "msub\t%2,%3"; 1656 else 1657 return "msac\t$0,%2,%3"; 1658} 1659 [(set_attr "type" "imadd") 1660 (set_attr "mode" "SI")]) 1661 1662;; An msac-like instruction implemented using negation and a macc. 1663(define_insn_and_split "*msac_using_macc" 1664 [(set (match_operand:SI 0 "register_operand" "=l,d") 1665 (minus:SI (match_operand:SI 1 "register_operand" "0,l") 1666 (mult:SI (match_operand:SI 2 "register_operand" "d,d") 1667 (match_operand:SI 3 "register_operand" "d,d")))) 1668 (clobber (match_scratch:SI 4 "=X,1")) 1669 (clobber (match_scratch:SI 5 "=d,d"))] 1670 "ISA_HAS_MACC && !ISA_HAS_MSAC" 1671 "#" 1672 "&& reload_completed" 1673 [(set (match_dup 5) 1674 (neg:SI (match_dup 3))) 1675 (parallel 1676 [(set (match_dup 0) 1677 (plus:SI (mult:SI (match_dup 2) 1678 (match_dup 5)) 1679 (match_dup 1))) 1680 (clobber (match_dup 4))])] 1681 "" 1682 [(set_attr "type" "imadd") 1683 (set_attr "length" "8")]) 1684 1685;; Patterns generated by the define_peephole2 below. 1686 1687(define_insn "*macc2" 1688 [(set (match_operand:SI 0 "register_operand" "=l") 1689 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d") 1690 (match_operand:SI 2 "register_operand" "d")) 1691 (match_dup 0))) 1692 (set (match_operand:SI 3 "register_operand" "=d") 1693 (plus:SI (mult:SI (match_dup 1) 1694 (match_dup 2)) 1695 (match_dup 0)))] 1696 "ISA_HAS_MACC && reload_completed" 1697 "macc\t%3,%1,%2" 1698 [(set_attr "type" "imadd") 1699 (set_attr "mode" "SI")]) 1700 1701(define_insn "*msac2" 1702 [(set (match_operand:SI 0 "register_operand" "=l") 1703 (minus:SI (match_dup 0) 1704 (mult:SI (match_operand:SI 1 "register_operand" "d") 1705 (match_operand:SI 2 "register_operand" "d")))) 1706 (set (match_operand:SI 3 "register_operand" "=d") 1707 (minus:SI (match_dup 0) 1708 (mult:SI (match_dup 1) 1709 (match_dup 2))))] 1710 "ISA_HAS_MSAC && reload_completed" 1711 "msac\t%3,%1,%2" 1712 [(set_attr "type" "imadd") 1713 (set_attr "mode" "SI")]) 1714 1715;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2> 1716;; Similarly msac. 1717;; 1718;; Operand 0: LO 1719;; Operand 1: macc/msac 1720;; Operand 2: GPR (destination) 1721(define_peephole2 1722 [(parallel 1723 [(set (match_operand:SI 0 "lo_operand") 1724 (match_operand:SI 1 "macc_msac_operand")) 1725 (clobber (scratch:SI))]) 1726 (set (match_operand:SI 2 "d_operand") 1727 (match_dup 0))] 1728 "" 1729 [(parallel [(set (match_dup 0) 1730 (match_dup 1)) 1731 (set (match_dup 2) 1732 (match_dup 1))])]) 1733 1734;; When we have a three-address multiplication instruction, it should 1735;; be faster to do a separate multiply and add, rather than moving 1736;; something into LO in order to use a macc instruction. 1737;; 1738;; This peephole needs a scratch register to cater for the case when one 1739;; of the multiplication operands is the same as the destination. 1740;; 1741;; Operand 0: GPR (scratch) 1742;; Operand 1: LO 1743;; Operand 2: GPR (addend) 1744;; Operand 3: GPR (destination) 1745;; Operand 4: macc/msac 1746;; Operand 5: new multiplication 1747;; Operand 6: new addition/subtraction 1748(define_peephole2 1749 [(match_scratch:SI 0 "d") 1750 (set (match_operand:SI 1 "lo_operand") 1751 (match_operand:SI 2 "d_operand")) 1752 (match_dup 0) 1753 (parallel 1754 [(set (match_operand:SI 3 "d_operand") 1755 (match_operand:SI 4 "macc_msac_operand")) 1756 (clobber (match_dup 1))])] 1757 "ISA_HAS_MUL3 && peep2_reg_dead_p (2, operands[1])" 1758 [(parallel [(set (match_dup 0) 1759 (match_dup 5)) 1760 (clobber (match_dup 1))]) 1761 (set (match_dup 3) 1762 (match_dup 6))] 1763{ 1764 operands[5] = XEXP (operands[4], GET_CODE (operands[4]) == PLUS ? 0 : 1); 1765 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[4]), SImode, 1766 operands[2], operands[0]); 1767}) 1768 1769;; Same as above, except LO is the initial target of the macc. 1770;; 1771;; Operand 0: GPR (scratch) 1772;; Operand 1: LO 1773;; Operand 2: GPR (addend) 1774;; Operand 3: macc/msac 1775;; Operand 4: GPR (destination) 1776;; Operand 5: new multiplication 1777;; Operand 6: new addition/subtraction 1778(define_peephole2 1779 [(match_scratch:SI 0 "d") 1780 (set (match_operand:SI 1 "lo_operand") 1781 (match_operand:SI 2 "d_operand")) 1782 (match_dup 0) 1783 (parallel 1784 [(set (match_dup 1) 1785 (match_operand:SI 3 "macc_msac_operand")) 1786 (clobber (scratch:SI))]) 1787 (match_dup 0) 1788 (set (match_operand:SI 4 "d_operand") 1789 (match_dup 1))] 1790 "ISA_HAS_MUL3 && peep2_reg_dead_p (3, operands[1])" 1791 [(parallel [(set (match_dup 0) 1792 (match_dup 5)) 1793 (clobber (match_dup 1))]) 1794 (set (match_dup 4) 1795 (match_dup 6))] 1796{ 1797 operands[5] = XEXP (operands[3], GET_CODE (operands[3]) == PLUS ? 0 : 1); 1798 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode, 1799 operands[2], operands[0]); 1800}) 1801 1802;; See the comment above *mul_add_si for details. 1803(define_insn "*mul_sub_si" 1804 [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?") 1805 (minus:SI (match_operand:SI 1 "register_operand" "0,d") 1806 (mult:SI (match_operand:SI 2 "register_operand" "d,d") 1807 (match_operand:SI 3 "register_operand" "d,d")))) 1808 (clobber (match_scratch:SI 4 "=X,l")) 1809 (clobber (match_scratch:SI 5 "=X,&d"))] 1810 "GENERATE_MADD_MSUB" 1811 "@ 1812 msub\t%2,%3 1813 #" 1814 [(set_attr "type" "imadd") 1815 (set_attr "mode" "SI") 1816 (set_attr "length" "4,8")]) 1817 1818;; Split *mul_sub_si if both the source and destination accumulator 1819;; values are GPRs. 1820(define_split 1821 [(set (match_operand:SI 0 "d_operand") 1822 (minus:SI (match_operand:SI 1 "d_operand") 1823 (mult:SI (match_operand:SI 2 "d_operand") 1824 (match_operand:SI 3 "d_operand")))) 1825 (clobber (match_operand:SI 4 "lo_operand")) 1826 (clobber (match_operand:SI 5 "d_operand"))] 1827 "reload_completed" 1828 [(parallel [(set (match_dup 5) 1829 (mult:SI (match_dup 2) (match_dup 3))) 1830 (clobber (match_dup 4))]) 1831 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 5)))] 1832 "") 1833 1834(define_insn "*muls" 1835 [(set (match_operand:SI 0 "register_operand" "=l,d") 1836 (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d") 1837 (match_operand:SI 2 "register_operand" "d,d")))) 1838 (clobber (match_scratch:SI 3 "=X,l"))] 1839 "ISA_HAS_MULS" 1840 "@ 1841 muls\t$0,%1,%2 1842 muls\t%0,%1,%2" 1843 [(set_attr "type" "imul,imul3") 1844 (set_attr "mode" "SI")]) 1845 1846(define_expand "<u>mulsidi3" 1847 [(set (match_operand:DI 0 "register_operand") 1848 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand")) 1849 (any_extend:DI (match_operand:SI 2 "register_operand"))))] 1850 "mips_mulsidi3_gen_fn (<CODE>) != NULL" 1851{ 1852 mulsidi3_gen_fn fn = mips_mulsidi3_gen_fn (<CODE>); 1853 emit_insn (fn (operands[0], operands[1], operands[2])); 1854 DONE; 1855}) 1856 1857(define_insn "<u>mulsidi3_32bit" 1858 [(set (match_operand:DI 0 "register_operand" "=x") 1859 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) 1860 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))))] 1861 "!TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_DSPR2" 1862 "mult<u>\t%1,%2" 1863 [(set_attr "type" "imul") 1864 (set_attr "mode" "SI")]) 1865 1866(define_insn "<u>mulsidi3_32bit_r4000" 1867 [(set (match_operand:DI 0 "register_operand" "=d") 1868 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) 1869 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))) 1870 (clobber (match_scratch:DI 3 "=x"))] 1871 "!TARGET_64BIT && TARGET_FIX_R4000" 1872 "mult<u>\t%1,%2\;mflo\t%L0\;mfhi\t%M0" 1873 [(set_attr "type" "imul") 1874 (set_attr "mode" "SI") 1875 (set_attr "length" "12")]) 1876 1877(define_insn "<u>mulsidi3_64bit" 1878 [(set (match_operand:DI 0 "register_operand" "=d") 1879 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) 1880 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))) 1881 (clobber (match_scratch:TI 3 "=x")) 1882 (clobber (match_scratch:DI 4 "=d"))] 1883 "TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_DMUL3" 1884 "#" 1885 [(set_attr "type" "imul") 1886 (set_attr "mode" "SI") 1887 (set (attr "length") 1888 (if_then_else (ne (symbol_ref "ISA_HAS_EXT_INS") (const_int 0)) 1889 (const_int 16) 1890 (const_int 28)))]) 1891 1892(define_split 1893 [(set (match_operand:DI 0 "d_operand") 1894 (mult:DI (any_extend:DI (match_operand:SI 1 "d_operand")) 1895 (any_extend:DI (match_operand:SI 2 "d_operand")))) 1896 (clobber (match_operand:TI 3 "hilo_operand")) 1897 (clobber (match_operand:DI 4 "d_operand"))] 1898 "TARGET_64BIT && !TARGET_FIX_R4000 && ISA_HAS_EXT_INS && reload_completed" 1899 [(set (match_dup 3) 1900 (unspec:TI [(mult:DI (any_extend:DI (match_dup 1)) 1901 (any_extend:DI (match_dup 2)))] 1902 UNSPEC_SET_HILO)) 1903 1904 ;; OP0 <- LO, OP4 <- HI 1905 (set (match_dup 0) (match_dup 5)) 1906 (set (match_dup 4) (unspec:DI [(match_dup 3)] UNSPEC_MFHI)) 1907 1908 (set (zero_extract:DI (match_dup 0) (const_int 32) (const_int 32)) 1909 (match_dup 4))] 1910 { operands[5] = gen_rtx_REG (DImode, LO_REGNUM); }) 1911 1912(define_split 1913 [(set (match_operand:DI 0 "d_operand") 1914 (mult:DI (any_extend:DI (match_operand:SI 1 "d_operand")) 1915 (any_extend:DI (match_operand:SI 2 "d_operand")))) 1916 (clobber (match_operand:TI 3 "hilo_operand")) 1917 (clobber (match_operand:DI 4 "d_operand"))] 1918 "TARGET_64BIT && !TARGET_FIX_R4000 && !ISA_HAS_EXT_INS && reload_completed" 1919 [(set (match_dup 3) 1920 (unspec:TI [(mult:DI (any_extend:DI (match_dup 1)) 1921 (any_extend:DI (match_dup 2)))] 1922 UNSPEC_SET_HILO)) 1923 1924 ;; OP0 <- LO, OP4 <- HI 1925 (set (match_dup 0) (match_dup 5)) 1926 (set (match_dup 4) (unspec:DI [(match_dup 3)] UNSPEC_MFHI)) 1927 1928 ;; Zero-extend OP0. 1929 (set (match_dup 0) 1930 (ashift:DI (match_dup 0) 1931 (const_int 32))) 1932 (set (match_dup 0) 1933 (lshiftrt:DI (match_dup 0) 1934 (const_int 32))) 1935 1936 ;; Shift OP4 into place. 1937 (set (match_dup 4) 1938 (ashift:DI (match_dup 4) 1939 (const_int 32))) 1940 1941 ;; OR the two halves together 1942 (set (match_dup 0) 1943 (ior:DI (match_dup 0) 1944 (match_dup 4)))] 1945 { operands[5] = gen_rtx_REG (DImode, LO_REGNUM); }) 1946 1947(define_insn "<u>mulsidi3_64bit_hilo" 1948 [(set (match_operand:TI 0 "register_operand" "=x") 1949 (unspec:TI 1950 [(mult:DI 1951 (any_extend:DI (match_operand:SI 1 "register_operand" "d")) 1952 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))] 1953 UNSPEC_SET_HILO))] 1954 "TARGET_64BIT && !TARGET_FIX_R4000" 1955 "mult<u>\t%1,%2" 1956 [(set_attr "type" "imul") 1957 (set_attr "mode" "SI")]) 1958 1959;; See comment before the ISA_HAS_DMUL3 case in mips_mulsidi3_gen_fn. 1960(define_insn "mulsidi3_64bit_dmul" 1961 [(set (match_operand:DI 0 "register_operand" "=d") 1962 (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) 1963 (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))) 1964 (clobber (match_scratch:DI 3 "=l"))] 1965 "TARGET_64BIT && ISA_HAS_DMUL3" 1966 "dmul\t%0,%1,%2" 1967 [(set_attr "type" "imul3") 1968 (set_attr "mode" "DI")]) 1969 1970;; Widening multiply with negation. 1971(define_insn "*muls<u>_di" 1972 [(set (match_operand:DI 0 "register_operand" "=x") 1973 (neg:DI 1974 (mult:DI 1975 (any_extend:DI (match_operand:SI 1 "register_operand" "d")) 1976 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))] 1977 "!TARGET_64BIT && ISA_HAS_MULS" 1978 "muls<u>\t$0,%1,%2" 1979 [(set_attr "type" "imul") 1980 (set_attr "mode" "SI")]) 1981 1982(define_insn "<u>msubsidi4" 1983 [(set (match_operand:DI 0 "register_operand" "=ka") 1984 (minus:DI 1985 (match_operand:DI 3 "register_operand" "0") 1986 (mult:DI 1987 (any_extend:DI (match_operand:SI 1 "register_operand" "d")) 1988 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))))] 1989 "!TARGET_64BIT && (ISA_HAS_MSAC || GENERATE_MADD_MSUB || ISA_HAS_DSPR2)" 1990{ 1991 if (ISA_HAS_DSPR2) 1992 return "msub<u>\t%q0,%1,%2"; 1993 else if (TARGET_MIPS5500 || GENERATE_MADD_MSUB) 1994 return "msub<u>\t%1,%2"; 1995 else 1996 return "msac<u>\t$0,%1,%2"; 1997} 1998 [(set_attr "type" "imadd") 1999 (set_attr "mode" "SI")]) 2000 2001;; _highpart patterns 2002 2003(define_expand "<su>mulsi3_highpart" 2004 [(set (match_operand:SI 0 "register_operand") 2005 (truncate:SI 2006 (lshiftrt:DI 2007 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand")) 2008 (any_extend:DI (match_operand:SI 2 "register_operand"))) 2009 (const_int 32))))] 2010 "" 2011{ 2012 if (ISA_HAS_MULHI) 2013 emit_insn (gen_<su>mulsi3_highpart_mulhi_internal (operands[0], 2014 operands[1], 2015 operands[2])); 2016 else 2017 emit_insn (gen_<su>mulsi3_highpart_internal (operands[0], operands[1], 2018 operands[2])); 2019 DONE; 2020}) 2021 2022(define_insn_and_split "<su>mulsi3_highpart_internal" 2023 [(set (match_operand:SI 0 "register_operand" "=d") 2024 (truncate:SI 2025 (lshiftrt:DI 2026 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) 2027 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))) 2028 (const_int 32)))) 2029 (clobber (match_scratch:SI 3 "=l"))] 2030 "!ISA_HAS_MULHI" 2031 { return TARGET_FIX_R4000 ? "mult<u>\t%1,%2\n\tmfhi\t%0" : "#"; } 2032 "&& reload_completed && !TARGET_FIX_R4000" 2033 [(const_int 0)] 2034{ 2035 rtx hilo; 2036 2037 if (TARGET_64BIT) 2038 { 2039 hilo = gen_rtx_REG (TImode, MD_REG_FIRST); 2040 emit_insn (gen_<u>mulsidi3_64bit_hilo (hilo, operands[1], operands[2])); 2041 emit_insn (gen_mfhisi_ti (operands[0], hilo)); 2042 } 2043 else 2044 { 2045 hilo = gen_rtx_REG (DImode, MD_REG_FIRST); 2046 emit_insn (gen_<u>mulsidi3_32bit (hilo, operands[1], operands[2])); 2047 emit_insn (gen_mfhisi_di (operands[0], hilo)); 2048 } 2049 DONE; 2050} 2051 [(set_attr "type" "imul") 2052 (set_attr "mode" "SI") 2053 (set_attr "length" "8")]) 2054 2055(define_insn "<su>mulsi3_highpart_mulhi_internal" 2056 [(set (match_operand:SI 0 "register_operand" "=d") 2057 (truncate:SI 2058 (lshiftrt:DI 2059 (mult:DI 2060 (any_extend:DI (match_operand:SI 1 "register_operand" "d")) 2061 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))) 2062 (const_int 32)))) 2063 (clobber (match_scratch:SI 3 "=l"))] 2064 "ISA_HAS_MULHI" 2065 "mulhi<u>\t%0,%1,%2" 2066 [(set_attr "type" "imul3") 2067 (set_attr "mode" "SI")]) 2068 2069(define_insn "*<su>mulsi3_highpart_neg_mulhi_internal" 2070 [(set (match_operand:SI 0 "register_operand" "=d") 2071 (truncate:SI 2072 (lshiftrt:DI 2073 (neg:DI 2074 (mult:DI 2075 (any_extend:DI (match_operand:SI 1 "register_operand" "d")) 2076 (any_extend:DI (match_operand:SI 2 "register_operand" "d")))) 2077 (const_int 32)))) 2078 (clobber (match_scratch:SI 3 "=l"))] 2079 "ISA_HAS_MULHI" 2080 "mulshi<u>\t%0,%1,%2" 2081 [(set_attr "type" "imul3") 2082 (set_attr "mode" "SI")]) 2083 2084;; Disable unsigned multiplication for -mfix-vr4120. This is for VR4120 2085;; errata MD(0), which says that dmultu does not always produce the 2086;; correct result. 2087(define_insn_and_split "<su>muldi3_highpart" 2088 [(set (match_operand:DI 0 "register_operand" "=d") 2089 (truncate:DI 2090 (lshiftrt:TI 2091 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d")) 2092 (any_extend:TI (match_operand:DI 2 "register_operand" "d"))) 2093 (const_int 64)))) 2094 (clobber (match_scratch:DI 3 "=l"))] 2095 "TARGET_64BIT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)" 2096 { return TARGET_FIX_R4000 ? "dmult<u>\t%1,%2\n\tmfhi\t%0" : "#"; } 2097 "&& reload_completed && !TARGET_FIX_R4000" 2098 [(const_int 0)] 2099{ 2100 rtx hilo; 2101 2102 hilo = gen_rtx_REG (TImode, MD_REG_FIRST); 2103 emit_insn (gen_<u>mulditi3_internal (hilo, operands[1], operands[2])); 2104 emit_insn (gen_mfhidi_ti (operands[0], hilo)); 2105 DONE; 2106} 2107 [(set_attr "type" "imul") 2108 (set_attr "mode" "DI") 2109 (set_attr "length" "8")]) 2110 2111(define_expand "<u>mulditi3" 2112 [(set (match_operand:TI 0 "register_operand") 2113 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand")) 2114 (any_extend:TI (match_operand:DI 2 "register_operand"))))] 2115 "TARGET_64BIT && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)" 2116{ 2117 if (TARGET_FIX_R4000) 2118 emit_insn (gen_<u>mulditi3_r4000 (operands[0], operands[1], operands[2])); 2119 else 2120 emit_insn (gen_<u>mulditi3_internal (operands[0], operands[1], 2121 operands[2])); 2122 DONE; 2123}) 2124 2125(define_insn "<u>mulditi3_internal" 2126 [(set (match_operand:TI 0 "register_operand" "=x") 2127 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d")) 2128 (any_extend:TI (match_operand:DI 2 "register_operand" "d"))))] 2129 "TARGET_64BIT 2130 && !TARGET_FIX_R4000 2131 && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)" 2132 "dmult<u>\t%1,%2" 2133 [(set_attr "type" "imul") 2134 (set_attr "mode" "DI")]) 2135 2136(define_insn "<u>mulditi3_r4000" 2137 [(set (match_operand:TI 0 "register_operand" "=d") 2138 (mult:TI (any_extend:TI (match_operand:DI 1 "register_operand" "d")) 2139 (any_extend:TI (match_operand:DI 2 "register_operand" "d")))) 2140 (clobber (match_scratch:TI 3 "=x"))] 2141 "TARGET_64BIT 2142 && TARGET_FIX_R4000 2143 && !(<CODE> == ZERO_EXTEND && TARGET_FIX_VR4120)" 2144 "dmult<u>\t%1,%2\;mflo\t%L0\;mfhi\t%M0" 2145 [(set_attr "type" "imul") 2146 (set_attr "mode" "DI") 2147 (set_attr "length" "12")]) 2148 2149;; The R4650 supports a 32-bit multiply/ 64-bit accumulate 2150;; instruction. The HI/LO registers are used as a 64-bit accumulator. 2151 2152(define_insn "madsi" 2153 [(set (match_operand:SI 0 "register_operand" "+l") 2154 (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d") 2155 (match_operand:SI 2 "register_operand" "d")) 2156 (match_dup 0)))] 2157 "TARGET_MAD" 2158 "mad\t%1,%2" 2159 [(set_attr "type" "imadd") 2160 (set_attr "mode" "SI")]) 2161 2162(define_insn "<u>maddsidi4" 2163 [(set (match_operand:DI 0 "register_operand" "=ka") 2164 (plus:DI 2165 (mult:DI (any_extend:DI (match_operand:SI 1 "register_operand" "d")) 2166 (any_extend:DI (match_operand:SI 2 "register_operand" "d"))) 2167 (match_operand:DI 3 "register_operand" "0")))] 2168 "(TARGET_MAD || ISA_HAS_MACC || GENERATE_MADD_MSUB || ISA_HAS_DSPR2) 2169 && !TARGET_64BIT" 2170{ 2171 if (TARGET_MAD) 2172 return "mad<u>\t%1,%2"; 2173 else if (ISA_HAS_DSPR2) 2174 return "madd<u>\t%q0,%1,%2"; 2175 else if (GENERATE_MADD_MSUB || TARGET_MIPS5500) 2176 return "madd<u>\t%1,%2"; 2177 else 2178 /* See comment in *macc. */ 2179 return "%[macc<u>\t%@,%1,%2%]"; 2180} 2181 [(set_attr "type" "imadd") 2182 (set_attr "mode" "SI")]) 2183 2184;; Floating point multiply accumulate instructions. 2185 2186(define_insn "*madd4<mode>" 2187 [(set (match_operand:ANYF 0 "register_operand" "=f") 2188 (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") 2189 (match_operand:ANYF 2 "register_operand" "f")) 2190 (match_operand:ANYF 3 "register_operand" "f")))] 2191 "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD" 2192 "madd.<fmt>\t%0,%3,%1,%2" 2193 [(set_attr "type" "fmadd") 2194 (set_attr "mode" "<UNITMODE>")]) 2195 2196(define_insn "*madd3<mode>" 2197 [(set (match_operand:ANYF 0 "register_operand" "=f") 2198 (plus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") 2199 (match_operand:ANYF 2 "register_operand" "f")) 2200 (match_operand:ANYF 3 "register_operand" "0")))] 2201 "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD" 2202 "madd.<fmt>\t%0,%1,%2" 2203 [(set_attr "type" "fmadd") 2204 (set_attr "mode" "<UNITMODE>")]) 2205 2206(define_insn "*msub4<mode>" 2207 [(set (match_operand:ANYF 0 "register_operand" "=f") 2208 (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") 2209 (match_operand:ANYF 2 "register_operand" "f")) 2210 (match_operand:ANYF 3 "register_operand" "f")))] 2211 "ISA_HAS_FP_MADD4_MSUB4 && TARGET_FUSED_MADD" 2212 "msub.<fmt>\t%0,%3,%1,%2" 2213 [(set_attr "type" "fmadd") 2214 (set_attr "mode" "<UNITMODE>")]) 2215 2216(define_insn "*msub3<mode>" 2217 [(set (match_operand:ANYF 0 "register_operand" "=f") 2218 (minus:ANYF (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") 2219 (match_operand:ANYF 2 "register_operand" "f")) 2220 (match_operand:ANYF 3 "register_operand" "0")))] 2221 "ISA_HAS_FP_MADD3_MSUB3 && TARGET_FUSED_MADD" 2222 "msub.<fmt>\t%0,%1,%2" 2223 [(set_attr "type" "fmadd") 2224 (set_attr "mode" "<UNITMODE>")]) 2225 2226(define_insn "*nmadd4<mode>" 2227 [(set (match_operand:ANYF 0 "register_operand" "=f") 2228 (neg:ANYF (plus:ANYF 2229 (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") 2230 (match_operand:ANYF 2 "register_operand" "f")) 2231 (match_operand:ANYF 3 "register_operand" "f"))))] 2232 "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode) 2233 && TARGET_FUSED_MADD 2234 && HONOR_SIGNED_ZEROS (<MODE>mode) 2235 && !HONOR_NANS (<MODE>mode)" 2236 "nmadd.<fmt>\t%0,%3,%1,%2" 2237 [(set_attr "type" "fmadd") 2238 (set_attr "mode" "<UNITMODE>")]) 2239 2240(define_insn "*nmadd3<mode>" 2241 [(set (match_operand:ANYF 0 "register_operand" "=f") 2242 (neg:ANYF (plus:ANYF 2243 (mult:ANYF (match_operand:ANYF 1 "register_operand" "f") 2244 (match_operand:ANYF 2 "register_operand" "f")) 2245 (match_operand:ANYF 3 "register_operand" "0"))))] 2246 "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode) 2247 && TARGET_FUSED_MADD 2248 && HONOR_SIGNED_ZEROS (<MODE>mode) 2249 && !HONOR_NANS (<MODE>mode)" 2250 "nmadd.<fmt>\t%0,%1,%2" 2251 [(set_attr "type" "fmadd") 2252 (set_attr "mode" "<UNITMODE>")]) 2253 2254(define_insn "*nmadd4<mode>_fastmath" 2255 [(set (match_operand:ANYF 0 "register_operand" "=f") 2256 (minus:ANYF 2257 (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) 2258 (match_operand:ANYF 2 "register_operand" "f")) 2259 (match_operand:ANYF 3 "register_operand" "f")))] 2260 "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode) 2261 && TARGET_FUSED_MADD 2262 && !HONOR_SIGNED_ZEROS (<MODE>mode) 2263 && !HONOR_NANS (<MODE>mode)" 2264 "nmadd.<fmt>\t%0,%3,%1,%2" 2265 [(set_attr "type" "fmadd") 2266 (set_attr "mode" "<UNITMODE>")]) 2267 2268(define_insn "*nmadd3<mode>_fastmath" 2269 [(set (match_operand:ANYF 0 "register_operand" "=f") 2270 (minus:ANYF 2271 (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")) 2272 (match_operand:ANYF 2 "register_operand" "f")) 2273 (match_operand:ANYF 3 "register_operand" "0")))] 2274 "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode) 2275 && TARGET_FUSED_MADD 2276 && !HONOR_SIGNED_ZEROS (<MODE>mode) 2277 && !HONOR_NANS (<MODE>mode)" 2278 "nmadd.<fmt>\t%0,%1,%2" 2279 [(set_attr "type" "fmadd") 2280 (set_attr "mode" "<UNITMODE>")]) 2281 2282(define_insn "*nmsub4<mode>" 2283 [(set (match_operand:ANYF 0 "register_operand" "=f") 2284 (neg:ANYF (minus:ANYF 2285 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") 2286 (match_operand:ANYF 3 "register_operand" "f")) 2287 (match_operand:ANYF 1 "register_operand" "f"))))] 2288 "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode) 2289 && TARGET_FUSED_MADD 2290 && HONOR_SIGNED_ZEROS (<MODE>mode) 2291 && !HONOR_NANS (<MODE>mode)" 2292 "nmsub.<fmt>\t%0,%1,%2,%3" 2293 [(set_attr "type" "fmadd") 2294 (set_attr "mode" "<UNITMODE>")]) 2295 2296(define_insn "*nmsub3<mode>" 2297 [(set (match_operand:ANYF 0 "register_operand" "=f") 2298 (neg:ANYF (minus:ANYF 2299 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") 2300 (match_operand:ANYF 3 "register_operand" "f")) 2301 (match_operand:ANYF 1 "register_operand" "0"))))] 2302 "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode) 2303 && TARGET_FUSED_MADD 2304 && HONOR_SIGNED_ZEROS (<MODE>mode) 2305 && !HONOR_NANS (<MODE>mode)" 2306 "nmsub.<fmt>\t%0,%1,%2" 2307 [(set_attr "type" "fmadd") 2308 (set_attr "mode" "<UNITMODE>")]) 2309 2310(define_insn "*nmsub4<mode>_fastmath" 2311 [(set (match_operand:ANYF 0 "register_operand" "=f") 2312 (minus:ANYF 2313 (match_operand:ANYF 1 "register_operand" "f") 2314 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") 2315 (match_operand:ANYF 3 "register_operand" "f"))))] 2316 "ISA_HAS_NMADD4_NMSUB4 (<MODE>mode) 2317 && TARGET_FUSED_MADD 2318 && !HONOR_SIGNED_ZEROS (<MODE>mode) 2319 && !HONOR_NANS (<MODE>mode)" 2320 "nmsub.<fmt>\t%0,%1,%2,%3" 2321 [(set_attr "type" "fmadd") 2322 (set_attr "mode" "<UNITMODE>")]) 2323 2324(define_insn "*nmsub3<mode>_fastmath" 2325 [(set (match_operand:ANYF 0 "register_operand" "=f") 2326 (minus:ANYF 2327 (match_operand:ANYF 1 "register_operand" "f") 2328 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f") 2329 (match_operand:ANYF 3 "register_operand" "0"))))] 2330 "ISA_HAS_NMADD3_NMSUB3 (<MODE>mode) 2331 && TARGET_FUSED_MADD 2332 && !HONOR_SIGNED_ZEROS (<MODE>mode) 2333 && !HONOR_NANS (<MODE>mode)" 2334 "nmsub.<fmt>\t%0,%1,%2" 2335 [(set_attr "type" "fmadd") 2336 (set_attr "mode" "<UNITMODE>")]) 2337 2338;; 2339;; .................... 2340;; 2341;; DIVISION and REMAINDER 2342;; 2343;; .................... 2344;; 2345 2346(define_expand "div<mode>3" 2347 [(set (match_operand:ANYF 0 "register_operand") 2348 (div:ANYF (match_operand:ANYF 1 "reg_or_1_operand") 2349 (match_operand:ANYF 2 "register_operand")))] 2350 "<divide_condition>" 2351{ 2352 if (const_1_operand (operands[1], <MODE>mode)) 2353 if (!(<recip_condition> && flag_unsafe_math_optimizations)) 2354 operands[1] = force_reg (<MODE>mode, operands[1]); 2355}) 2356 2357;; These patterns work around the early SB-1 rev2 core "F1" erratum: 2358;; 2359;; If an mfc1 or dmfc1 happens to access the floating point register 2360;; file at the same time a long latency operation (div, sqrt, recip, 2361;; sqrt) iterates an intermediate result back through the floating 2362;; point register file bypass, then instead returning the correct 2363;; register value the mfc1 or dmfc1 operation returns the intermediate 2364;; result of the long latency operation. 2365;; 2366;; The workaround is to insert an unconditional 'mov' from/to the 2367;; long latency op destination register. 2368 2369(define_insn "*div<mode>3" 2370 [(set (match_operand:ANYF 0 "register_operand" "=f") 2371 (div:ANYF (match_operand:ANYF 1 "register_operand" "f") 2372 (match_operand:ANYF 2 "register_operand" "f")))] 2373 "<divide_condition>" 2374{ 2375 if (TARGET_FIX_SB1) 2376 return "div.<fmt>\t%0,%1,%2\;mov.<fmt>\t%0,%0"; 2377 else 2378 return "div.<fmt>\t%0,%1,%2"; 2379} 2380 [(set_attr "type" "fdiv") 2381 (set_attr "mode" "<UNITMODE>") 2382 (set (attr "length") 2383 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) 2384 (const_int 8) 2385 (const_int 4)))]) 2386 2387(define_insn "*recip<mode>3" 2388 [(set (match_operand:ANYF 0 "register_operand" "=f") 2389 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") 2390 (match_operand:ANYF 2 "register_operand" "f")))] 2391 "<recip_condition> && flag_unsafe_math_optimizations" 2392{ 2393 if (TARGET_FIX_SB1) 2394 return "recip.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0"; 2395 else 2396 return "recip.<fmt>\t%0,%2"; 2397} 2398 [(set_attr "type" "frdiv") 2399 (set_attr "mode" "<UNITMODE>") 2400 (set (attr "length") 2401 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) 2402 (const_int 8) 2403 (const_int 4)))]) 2404 2405;; VR4120 errata MD(A1): signed division instructions do not work correctly 2406;; with negative operands. We use special libgcc functions instead. 2407(define_insn_and_split "divmod<mode>4" 2408 [(set (match_operand:GPR 0 "register_operand" "=l") 2409 (div:GPR (match_operand:GPR 1 "register_operand" "d") 2410 (match_operand:GPR 2 "register_operand" "d"))) 2411 (set (match_operand:GPR 3 "register_operand" "=d") 2412 (mod:GPR (match_dup 1) 2413 (match_dup 2)))] 2414 "!TARGET_FIX_VR4120" 2415 "#" 2416 "&& reload_completed" 2417 [(const_int 0)] 2418{ 2419 rtx hilo; 2420 2421 if (TARGET_64BIT) 2422 { 2423 hilo = gen_rtx_REG (TImode, MD_REG_FIRST); 2424 emit_insn (gen_divmod<mode>4_hilo_ti (hilo, operands[1], operands[2])); 2425 emit_insn (gen_mfhi<mode>_ti (operands[3], hilo)); 2426 } 2427 else 2428 { 2429 hilo = gen_rtx_REG (DImode, MD_REG_FIRST); 2430 emit_insn (gen_divmod<mode>4_hilo_di (hilo, operands[1], operands[2])); 2431 emit_insn (gen_mfhi<mode>_di (operands[3], hilo)); 2432 } 2433 DONE; 2434} 2435 [(set_attr "type" "idiv") 2436 (set_attr "mode" "<MODE>") 2437 (set_attr "length" "8")]) 2438 2439(define_insn_and_split "udivmod<mode>4" 2440 [(set (match_operand:GPR 0 "register_operand" "=l") 2441 (udiv:GPR (match_operand:GPR 1 "register_operand" "d") 2442 (match_operand:GPR 2 "register_operand" "d"))) 2443 (set (match_operand:GPR 3 "register_operand" "=d") 2444 (umod:GPR (match_dup 1) 2445 (match_dup 2)))] 2446 "" 2447 "#" 2448 "reload_completed" 2449 [(const_int 0)] 2450{ 2451 rtx hilo; 2452 2453 if (TARGET_64BIT) 2454 { 2455 hilo = gen_rtx_REG (TImode, MD_REG_FIRST); 2456 emit_insn (gen_udivmod<mode>4_hilo_ti (hilo, operands[1], operands[2])); 2457 emit_insn (gen_mfhi<mode>_ti (operands[3], hilo)); 2458 } 2459 else 2460 { 2461 hilo = gen_rtx_REG (DImode, MD_REG_FIRST); 2462 emit_insn (gen_udivmod<mode>4_hilo_di (hilo, operands[1], operands[2])); 2463 emit_insn (gen_mfhi<mode>_di (operands[3], hilo)); 2464 } 2465 DONE; 2466} 2467 [(set_attr "type" "idiv") 2468 (set_attr "mode" "<MODE>") 2469 (set_attr "length" "8")]) 2470 2471(define_insn "<u>divmod<GPR:mode>4_hilo_<HILO:mode>" 2472 [(set (match_operand:HILO 0 "register_operand" "=x") 2473 (unspec:HILO 2474 [(any_div:GPR (match_operand:GPR 1 "register_operand" "d") 2475 (match_operand:GPR 2 "register_operand" "d"))] 2476 UNSPEC_SET_HILO))] 2477 "" 2478 { return mips_output_division ("<GPR:d>div<u>\t%.,%1,%2", operands); } 2479 [(set_attr "type" "idiv") 2480 (set_attr "mode" "<GPR:MODE>")]) 2481 2482;; 2483;; .................... 2484;; 2485;; SQUARE ROOT 2486;; 2487;; .................... 2488 2489;; These patterns work around the early SB-1 rev2 core "F1" erratum (see 2490;; "*div[sd]f3" comment for details). 2491 2492(define_insn "sqrt<mode>2" 2493 [(set (match_operand:ANYF 0 "register_operand" "=f") 2494 (sqrt:ANYF (match_operand:ANYF 1 "register_operand" "f")))] 2495 "<sqrt_condition>" 2496{ 2497 if (TARGET_FIX_SB1) 2498 return "sqrt.<fmt>\t%0,%1\;mov.<fmt>\t%0,%0"; 2499 else 2500 return "sqrt.<fmt>\t%0,%1"; 2501} 2502 [(set_attr "type" "fsqrt") 2503 (set_attr "mode" "<UNITMODE>") 2504 (set (attr "length") 2505 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) 2506 (const_int 8) 2507 (const_int 4)))]) 2508 2509(define_insn "*rsqrt<mode>a" 2510 [(set (match_operand:ANYF 0 "register_operand" "=f") 2511 (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") 2512 (sqrt:ANYF (match_operand:ANYF 2 "register_operand" "f"))))] 2513 "<recip_condition> && flag_unsafe_math_optimizations" 2514{ 2515 if (TARGET_FIX_SB1) 2516 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0"; 2517 else 2518 return "rsqrt.<fmt>\t%0,%2"; 2519} 2520 [(set_attr "type" "frsqrt") 2521 (set_attr "mode" "<UNITMODE>") 2522 (set (attr "length") 2523 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) 2524 (const_int 8) 2525 (const_int 4)))]) 2526 2527(define_insn "*rsqrt<mode>b" 2528 [(set (match_operand:ANYF 0 "register_operand" "=f") 2529 (sqrt:ANYF (div:ANYF (match_operand:ANYF 1 "const_1_operand" "") 2530 (match_operand:ANYF 2 "register_operand" "f"))))] 2531 "<recip_condition> && flag_unsafe_math_optimizations" 2532{ 2533 if (TARGET_FIX_SB1) 2534 return "rsqrt.<fmt>\t%0,%2\;mov.<fmt>\t%0,%0"; 2535 else 2536 return "rsqrt.<fmt>\t%0,%2"; 2537} 2538 [(set_attr "type" "frsqrt") 2539 (set_attr "mode" "<UNITMODE>") 2540 (set (attr "length") 2541 (if_then_else (ne (symbol_ref "TARGET_FIX_SB1") (const_int 0)) 2542 (const_int 8) 2543 (const_int 4)))]) 2544 2545;; 2546;; .................... 2547;; 2548;; ABSOLUTE VALUE 2549;; 2550;; .................... 2551 2552;; Do not use the integer abs macro instruction, since that signals an 2553;; exception on -2147483648 (sigh). 2554 2555;; abs.fmt is an arithmetic instruction and treats all NaN inputs as 2556;; invalid; it does not clear their sign bits. We therefore can't use 2557;; abs.fmt if the signs of NaNs matter. 2558 2559(define_insn "abs<mode>2" 2560 [(set (match_operand:ANYF 0 "register_operand" "=f") 2561 (abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))] 2562 "!HONOR_NANS (<MODE>mode)" 2563 "abs.<fmt>\t%0,%1" 2564 [(set_attr "type" "fabs") 2565 (set_attr "mode" "<UNITMODE>")]) 2566 2567;; 2568;; ................... 2569;; 2570;; Count leading zeroes. 2571;; 2572;; ................... 2573;; 2574 2575(define_insn "clz<mode>2" 2576 [(set (match_operand:GPR 0 "register_operand" "=d") 2577 (clz:GPR (match_operand:GPR 1 "register_operand" "d")))] 2578 "ISA_HAS_CLZ_CLO" 2579 "<d>clz\t%0,%1" 2580 [(set_attr "type" "clz") 2581 (set_attr "mode" "<MODE>")]) 2582 2583;; 2584;; ................... 2585;; 2586;; Count number of set bits. 2587;; 2588;; ................... 2589;; 2590 2591(define_insn "popcount<mode>2" 2592 [(set (match_operand:GPR 0 "register_operand" "=d") 2593 (popcount:GPR (match_operand:GPR 1 "register_operand" "d")))] 2594 "ISA_HAS_POP" 2595 "<d>pop\t%0,%1" 2596 [(set_attr "type" "pop") 2597 (set_attr "mode" "<MODE>")]) 2598 2599;; 2600;; .................... 2601;; 2602;; NEGATION and ONE'S COMPLEMENT 2603;; 2604;; .................... 2605 2606(define_insn "negsi2" 2607 [(set (match_operand:SI 0 "register_operand" "=d") 2608 (neg:SI (match_operand:SI 1 "register_operand" "d")))] 2609 "" 2610{ 2611 if (TARGET_MIPS16) 2612 return "neg\t%0,%1"; 2613 else 2614 return "subu\t%0,%.,%1"; 2615} 2616 [(set_attr "type" "arith") 2617 (set_attr "mode" "SI")]) 2618 2619(define_insn "negdi2" 2620 [(set (match_operand:DI 0 "register_operand" "=d") 2621 (neg:DI (match_operand:DI 1 "register_operand" "d")))] 2622 "TARGET_64BIT && !TARGET_MIPS16" 2623 "dsubu\t%0,%.,%1" 2624 [(set_attr "type" "arith") 2625 (set_attr "mode" "DI")]) 2626 2627;; neg.fmt is an arithmetic instruction and treats all NaN inputs as 2628;; invalid; it does not flip their sign bit. We therefore can't use 2629;; neg.fmt if the signs of NaNs matter. 2630 2631(define_insn "neg<mode>2" 2632 [(set (match_operand:ANYF 0 "register_operand" "=f") 2633 (neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))] 2634 "!HONOR_NANS (<MODE>mode)" 2635 "neg.<fmt>\t%0,%1" 2636 [(set_attr "type" "fneg") 2637 (set_attr "mode" "<UNITMODE>")]) 2638 2639(define_insn "one_cmpl<mode>2" 2640 [(set (match_operand:GPR 0 "register_operand" "=d") 2641 (not:GPR (match_operand:GPR 1 "register_operand" "d")))] 2642 "" 2643{ 2644 if (TARGET_MIPS16) 2645 return "not\t%0,%1"; 2646 else 2647 return "nor\t%0,%.,%1"; 2648} 2649 [(set_attr "type" "logical") 2650 (set_attr "mode" "<MODE>")]) 2651 2652;; 2653;; .................... 2654;; 2655;; LOGICAL 2656;; 2657;; .................... 2658;; 2659 2660;; Many of these instructions use trivial define_expands, because we 2661;; want to use a different set of constraints when TARGET_MIPS16. 2662 2663(define_expand "and<mode>3" 2664 [(set (match_operand:GPR 0 "register_operand") 2665 (and:GPR (match_operand:GPR 1 "register_operand") 2666 (match_operand:GPR 2 "and_reg_operand")))]) 2667 2668;; The middle-end is not allowed to convert ANDing with 0xffff_ffff into a 2669;; zero_extendsidi2 because of TRULY_NOOP_TRUNCATION, so handle these here. 2670;; Note that this variant does not trigger for SI mode because we require 2671;; a 64-bit HOST_WIDE_INT and 0xffff_ffff wouldn't be a canonical 2672;; sign-extended SImode value. 2673;; 2674;; These are possible combinations for operand 1 and 2. The table 2675;; includes both MIPS and MIPS16 cases. (r=register, mem=memory, 2676;; 16=MIPS16, x=match, S=split): 2677;; 2678;; \ op1 r/EXT r/!EXT mem r/16 mem/16 2679;; op2 2680;; 2681;; andi x x 2682;; 0xff x x x x 2683;; 0xffff x x x x 2684;; 0xffff_ffff x S x S x 2685;; low-bitmask x 2686;; register x x 2687;; register =op1 x 2688 2689(define_insn "*and<mode>3" 2690 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d,d,d") 2691 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "o,o,W,d,d,d,d") 2692 (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,K,Yx,Yw,d")))] 2693 "!TARGET_MIPS16 && and_operands_ok (<MODE>mode, operands[1], operands[2])" 2694{ 2695 int len; 2696 2697 switch (which_alternative) 2698 { 2699 case 0: 2700 operands[1] = gen_lowpart (QImode, operands[1]); 2701 return "lbu\t%0,%1"; 2702 case 1: 2703 operands[1] = gen_lowpart (HImode, operands[1]); 2704 return "lhu\t%0,%1"; 2705 case 2: 2706 operands[1] = gen_lowpart (SImode, operands[1]); 2707 return "lwu\t%0,%1"; 2708 case 3: 2709 return "andi\t%0,%1,%x2"; 2710 case 4: 2711 len = low_bitmask_len (<MODE>mode, INTVAL (operands[2])); 2712 operands[2] = GEN_INT (len); 2713 return "<d>ext\t%0,%1,0,%2"; 2714 case 5: 2715 return "#"; 2716 case 6: 2717 return "and\t%0,%1,%2"; 2718 default: 2719 gcc_unreachable (); 2720 } 2721} 2722 [(set_attr "move_type" "load,load,load,andi,ext_ins,shift_shift,logical") 2723 (set_attr "mode" "<MODE>")]) 2724 2725(define_insn "*and<mode>3_mips16" 2726 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d") 2727 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "%o,o,W,d,0") 2728 (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Yw,d")))] 2729 "TARGET_MIPS16 && and_operands_ok (<MODE>mode, operands[1], operands[2])" 2730{ 2731 switch (which_alternative) 2732 { 2733 case 0: 2734 operands[1] = gen_lowpart (QImode, operands[1]); 2735 return "lbu\t%0,%1"; 2736 case 1: 2737 operands[1] = gen_lowpart (HImode, operands[1]); 2738 return "lhu\t%0,%1"; 2739 case 2: 2740 operands[1] = gen_lowpart (SImode, operands[1]); 2741 return "lwu\t%0,%1"; 2742 case 3: 2743 return "#"; 2744 case 4: 2745 return "and\t%0,%2"; 2746 default: 2747 gcc_unreachable (); 2748 } 2749} 2750 [(set_attr "move_type" "load,load,load,shift_shift,logical") 2751 (set_attr "mode" "<MODE>")]) 2752 2753(define_expand "ior<mode>3" 2754 [(set (match_operand:GPR 0 "register_operand") 2755 (ior:GPR (match_operand:GPR 1 "register_operand") 2756 (match_operand:GPR 2 "uns_arith_operand")))] 2757 "" 2758{ 2759 if (TARGET_MIPS16) 2760 operands[2] = force_reg (<MODE>mode, operands[2]); 2761}) 2762 2763(define_insn "*ior<mode>3" 2764 [(set (match_operand:GPR 0 "register_operand" "=d,d") 2765 (ior:GPR (match_operand:GPR 1 "register_operand" "%d,d") 2766 (match_operand:GPR 2 "uns_arith_operand" "d,K")))] 2767 "!TARGET_MIPS16" 2768 "@ 2769 or\t%0,%1,%2 2770 ori\t%0,%1,%x2" 2771 [(set_attr "type" "logical") 2772 (set_attr "mode" "<MODE>")]) 2773 2774(define_insn "*ior<mode>3_mips16" 2775 [(set (match_operand:GPR 0 "register_operand" "=d") 2776 (ior:GPR (match_operand:GPR 1 "register_operand" "%0") 2777 (match_operand:GPR 2 "register_operand" "d")))] 2778 "TARGET_MIPS16" 2779 "or\t%0,%2" 2780 [(set_attr "type" "logical") 2781 (set_attr "mode" "<MODE>")]) 2782 2783(define_expand "xor<mode>3" 2784 [(set (match_operand:GPR 0 "register_operand") 2785 (xor:GPR (match_operand:GPR 1 "register_operand") 2786 (match_operand:GPR 2 "uns_arith_operand")))] 2787 "" 2788 "") 2789 2790(define_insn "" 2791 [(set (match_operand:GPR 0 "register_operand" "=d,d") 2792 (xor:GPR (match_operand:GPR 1 "register_operand" "%d,d") 2793 (match_operand:GPR 2 "uns_arith_operand" "d,K")))] 2794 "!TARGET_MIPS16" 2795 "@ 2796 xor\t%0,%1,%2 2797 xori\t%0,%1,%x2" 2798 [(set_attr "type" "logical") 2799 (set_attr "mode" "<MODE>")]) 2800 2801(define_insn "" 2802 [(set (match_operand:GPR 0 "register_operand" "=d,t,t") 2803 (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d") 2804 (match_operand:GPR 2 "uns_arith_operand" "d,K,d")))] 2805 "TARGET_MIPS16" 2806 "@ 2807 xor\t%0,%2 2808 cmpi\t%1,%2 2809 cmp\t%1,%2" 2810 [(set_attr "type" "logical,arith,arith") 2811 (set_attr "mode" "<MODE>") 2812 (set_attr_alternative "length" 2813 [(const_int 4) 2814 (if_then_else (match_operand:VOID 2 "m16_uimm8_1") 2815 (const_int 4) 2816 (const_int 8)) 2817 (const_int 4)])]) 2818 2819(define_insn "*nor<mode>3" 2820 [(set (match_operand:GPR 0 "register_operand" "=d") 2821 (and:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d")) 2822 (not:GPR (match_operand:GPR 2 "register_operand" "d"))))] 2823 "!TARGET_MIPS16" 2824 "nor\t%0,%1,%2" 2825 [(set_attr "type" "logical") 2826 (set_attr "mode" "<MODE>")]) 2827 2828;; 2829;; .................... 2830;; 2831;; TRUNCATION 2832;; 2833;; .................... 2834 2835 2836 2837(define_insn "truncdfsf2" 2838 [(set (match_operand:SF 0 "register_operand" "=f") 2839 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))] 2840 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 2841 "cvt.s.d\t%0,%1" 2842 [(set_attr "type" "fcvt") 2843 (set_attr "cnv_mode" "D2S") 2844 (set_attr "mode" "SF")]) 2845 2846;; Integer truncation patterns. Truncating SImode values to smaller 2847;; modes is a no-op, as it is for most other GCC ports. Truncating 2848;; DImode values to SImode is not a no-op for TARGET_64BIT since we 2849;; need to make sure that the lower 32 bits are properly sign-extended 2850;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes 2851;; smaller than SImode is equivalent to two separate truncations: 2852;; 2853;; A B 2854;; DI ---> HI == DI ---> SI ---> HI 2855;; DI ---> QI == DI ---> SI ---> QI 2856;; 2857;; Step A needs a real instruction but step B does not. 2858 2859(define_insn "truncdi<mode>2" 2860 [(set (match_operand:SUBDI 0 "nonimmediate_operand" "=d,m") 2861 (truncate:SUBDI (match_operand:DI 1 "register_operand" "d,d")))] 2862 "TARGET_64BIT" 2863 "@ 2864 sll\t%0,%1,0 2865 <store>\t%1,%0" 2866 [(set_attr "move_type" "sll0,store") 2867 (set_attr "mode" "SI")]) 2868 2869;; Combiner patterns to optimize shift/truncate combinations. 2870 2871(define_insn "*ashr_trunc<mode>" 2872 [(set (match_operand:SUBDI 0 "register_operand" "=d") 2873 (truncate:SUBDI 2874 (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") 2875 (match_operand:DI 2 "const_arith_operand" ""))))] 2876 "TARGET_64BIT && !TARGET_MIPS16 && IN_RANGE (INTVAL (operands[2]), 32, 63)" 2877 "dsra\t%0,%1,%2" 2878 [(set_attr "type" "shift") 2879 (set_attr "mode" "<MODE>")]) 2880 2881(define_insn "*lshr32_trunc<mode>" 2882 [(set (match_operand:SUBDI 0 "register_operand" "=d") 2883 (truncate:SUBDI 2884 (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") 2885 (const_int 32))))] 2886 "TARGET_64BIT && !TARGET_MIPS16" 2887 "dsra\t%0,%1,32" 2888 [(set_attr "type" "shift") 2889 (set_attr "mode" "<MODE>")]) 2890 2891;; Logical shift by more than 32 results in proper SI values so truncation is 2892;; removed by the middle end. Note that a logical shift by 32 is handled by 2893;; the previous pattern. 2894(define_insn "*<optab>_trunc<mode>_exts" 2895 [(set (match_operand:SUBDI 0 "register_operand" "=d") 2896 (truncate:SUBDI 2897 (any_shiftrt:DI (match_operand:DI 1 "register_operand" "d") 2898 (match_operand:DI 2 "const_arith_operand" ""))))] 2899 "ISA_HAS_EXTS && TARGET_64BIT && UINTVAL (operands[2]) < 32" 2900 "exts\t%0,%1,%2,31" 2901 [(set_attr "type" "arith") 2902 (set_attr "mode" "<MODE>")]) 2903 2904;; 2905;; .................... 2906;; 2907;; ZERO EXTENSION 2908;; 2909;; .................... 2910 2911;; Extension insns. 2912 2913(define_expand "zero_extendsidi2" 2914 [(set (match_operand:DI 0 "register_operand") 2915 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))] 2916 "TARGET_64BIT") 2917 2918(define_insn_and_split "*zero_extendsidi2" 2919 [(set (match_operand:DI 0 "register_operand" "=d,d") 2920 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))] 2921 "TARGET_64BIT && !ISA_HAS_EXT_INS" 2922 "@ 2923 # 2924 lwu\t%0,%1" 2925 "&& reload_completed && REG_P (operands[1])" 2926 [(set (match_dup 0) 2927 (ashift:DI (match_dup 1) (const_int 32))) 2928 (set (match_dup 0) 2929 (lshiftrt:DI (match_dup 0) (const_int 32)))] 2930 { operands[1] = gen_lowpart (DImode, operands[1]); } 2931 [(set_attr "move_type" "shift_shift,load") 2932 (set_attr "mode" "DI")]) 2933 2934(define_insn "*zero_extendsidi2_dext" 2935 [(set (match_operand:DI 0 "register_operand" "=d,d") 2936 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,W")))] 2937 "TARGET_64BIT && ISA_HAS_EXT_INS" 2938 "@ 2939 dext\t%0,%1,0,32 2940 lwu\t%0,%1" 2941 [(set_attr "move_type" "arith,load") 2942 (set_attr "mode" "DI")]) 2943 2944;; See the comment before the *and<mode>3 pattern why this is generated by 2945;; combine. 2946 2947(define_split 2948 [(set (match_operand:DI 0 "register_operand") 2949 (and:DI (match_operand:DI 1 "register_operand") 2950 (const_int 4294967295)))] 2951 "TARGET_64BIT && !ISA_HAS_EXT_INS && reload_completed" 2952 [(set (match_dup 0) 2953 (ashift:DI (match_dup 1) (const_int 32))) 2954 (set (match_dup 0) 2955 (lshiftrt:DI (match_dup 0) (const_int 32)))]) 2956 2957(define_expand "zero_extend<SHORT:mode><GPR:mode>2" 2958 [(set (match_operand:GPR 0 "register_operand") 2959 (zero_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))] 2960 "" 2961{ 2962 if (TARGET_MIPS16 && !GENERATE_MIPS16E 2963 && !memory_operand (operands[1], <SHORT:MODE>mode)) 2964 { 2965 emit_insn (gen_and<GPR:mode>3 (operands[0], 2966 gen_lowpart (<GPR:MODE>mode, operands[1]), 2967 force_reg (<GPR:MODE>mode, 2968 GEN_INT (<SHORT:mask>)))); 2969 DONE; 2970 } 2971}) 2972 2973(define_insn "*zero_extend<SHORT:mode><GPR:mode>2" 2974 [(set (match_operand:GPR 0 "register_operand" "=d,d") 2975 (zero_extend:GPR 2976 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))] 2977 "!TARGET_MIPS16" 2978 "@ 2979 andi\t%0,%1,<SHORT:mask> 2980 l<SHORT:size>u\t%0,%1" 2981 [(set_attr "move_type" "andi,load") 2982 (set_attr "mode" "<GPR:MODE>")]) 2983 2984(define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16e" 2985 [(set (match_operand:GPR 0 "register_operand" "=d") 2986 (zero_extend:GPR (match_operand:SHORT 1 "register_operand" "0")))] 2987 "GENERATE_MIPS16E" 2988 "ze<SHORT:size>\t%0" 2989 ;; This instruction is effectively a special encoding of ANDI. 2990 [(set_attr "move_type" "andi") 2991 (set_attr "mode" "<GPR:MODE>")]) 2992 2993(define_insn "*zero_extend<SHORT:mode><GPR:mode>2_mips16" 2994 [(set (match_operand:GPR 0 "register_operand" "=d") 2995 (zero_extend:GPR (match_operand:SHORT 1 "memory_operand" "m")))] 2996 "TARGET_MIPS16" 2997 "l<SHORT:size>u\t%0,%1" 2998 [(set_attr "move_type" "load") 2999 (set_attr "mode" "<GPR:MODE>")]) 3000 3001(define_expand "zero_extendqihi2" 3002 [(set (match_operand:HI 0 "register_operand") 3003 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))] 3004 "" 3005{ 3006 if (TARGET_MIPS16 && !memory_operand (operands[1], QImode)) 3007 { 3008 emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]), 3009 operands[1])); 3010 DONE; 3011 } 3012}) 3013 3014(define_insn "*zero_extendqihi2" 3015 [(set (match_operand:HI 0 "register_operand" "=d,d") 3016 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] 3017 "!TARGET_MIPS16" 3018 "@ 3019 andi\t%0,%1,0x00ff 3020 lbu\t%0,%1" 3021 [(set_attr "move_type" "andi,load") 3022 (set_attr "mode" "HI")]) 3023 3024(define_insn "*zero_extendqihi2_mips16" 3025 [(set (match_operand:HI 0 "register_operand" "=d") 3026 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))] 3027 "TARGET_MIPS16" 3028 "lbu\t%0,%1" 3029 [(set_attr "move_type" "load") 3030 (set_attr "mode" "HI")]) 3031 3032;; Combiner patterns to optimize truncate/zero_extend combinations. 3033 3034(define_insn "*zero_extend<GPR:mode>_trunc<SHORT:mode>" 3035 [(set (match_operand:GPR 0 "register_operand" "=d") 3036 (zero_extend:GPR 3037 (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))] 3038 "TARGET_64BIT && !TARGET_MIPS16" 3039{ 3040 operands[2] = GEN_INT (GET_MODE_MASK (<SHORT:MODE>mode)); 3041 return "andi\t%0,%1,%x2"; 3042} 3043 [(set_attr "type" "logical") 3044 (set_attr "mode" "<GPR:MODE>")]) 3045 3046(define_insn "*zero_extendhi_truncqi" 3047 [(set (match_operand:HI 0 "register_operand" "=d") 3048 (zero_extend:HI 3049 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))] 3050 "TARGET_64BIT && !TARGET_MIPS16" 3051 "andi\t%0,%1,0xff" 3052 [(set_attr "type" "logical") 3053 (set_attr "mode" "HI")]) 3054 3055;; 3056;; .................... 3057;; 3058;; SIGN EXTENSION 3059;; 3060;; .................... 3061 3062;; Extension insns. 3063;; Those for integer source operand are ordered widest source type first. 3064 3065;; When TARGET_64BIT, all SImode integer registers should already be in 3066;; sign-extended form (see TRULY_NOOP_TRUNCATION and truncdisi2). We can 3067;; therefore get rid of register->register instructions if we constrain 3068;; the source to be in the same register as the destination. 3069;; 3070;; The register alternative has type "arith" so that the pre-reload 3071;; scheduler will treat it as a move. This reflects what happens if 3072;; the register alternative needs a reload. 3073(define_insn_and_split "extendsidi2" 3074 [(set (match_operand:DI 0 "register_operand" "=d,d") 3075 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,m")))] 3076 "TARGET_64BIT" 3077 "@ 3078 # 3079 lw\t%0,%1" 3080 "&& reload_completed && register_operand (operands[1], VOIDmode)" 3081 [(const_int 0)] 3082{ 3083 emit_note (NOTE_INSN_DELETED); 3084 DONE; 3085} 3086 [(set_attr "move_type" "move,load") 3087 (set_attr "mode" "DI")]) 3088 3089(define_expand "extend<SHORT:mode><GPR:mode>2" 3090 [(set (match_operand:GPR 0 "register_operand") 3091 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand")))] 3092 "") 3093 3094(define_insn "*extend<SHORT:mode><GPR:mode>2_mips16e" 3095 [(set (match_operand:GPR 0 "register_operand" "=d,d") 3096 (sign_extend:GPR (match_operand:SHORT 1 "nonimmediate_operand" "0,m")))] 3097 "GENERATE_MIPS16E" 3098 "@ 3099 se<SHORT:size>\t%0 3100 l<SHORT:size>\t%0,%1" 3101 [(set_attr "move_type" "signext,load") 3102 (set_attr "mode" "<GPR:MODE>")]) 3103 3104(define_insn_and_split "*extend<SHORT:mode><GPR:mode>2" 3105 [(set (match_operand:GPR 0 "register_operand" "=d,d") 3106 (sign_extend:GPR 3107 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))] 3108 "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E" 3109 "@ 3110 # 3111 l<SHORT:size>\t%0,%1" 3112 "&& reload_completed && REG_P (operands[1])" 3113 [(set (match_dup 0) (ashift:GPR (match_dup 1) (match_dup 2))) 3114 (set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))] 3115{ 3116 operands[1] = gen_lowpart (<GPR:MODE>mode, operands[1]); 3117 operands[2] = GEN_INT (GET_MODE_BITSIZE (<GPR:MODE>mode) 3118 - GET_MODE_BITSIZE (<SHORT:MODE>mode)); 3119} 3120 [(set_attr "move_type" "shift_shift,load") 3121 (set_attr "mode" "<GPR:MODE>")]) 3122 3123(define_insn "*extend<SHORT:mode><GPR:mode>2_se<SHORT:size>" 3124 [(set (match_operand:GPR 0 "register_operand" "=d,d") 3125 (sign_extend:GPR 3126 (match_operand:SHORT 1 "nonimmediate_operand" "d,m")))] 3127 "ISA_HAS_SEB_SEH" 3128 "@ 3129 se<SHORT:size>\t%0,%1 3130 l<SHORT:size>\t%0,%1" 3131 [(set_attr "move_type" "signext,load") 3132 (set_attr "mode" "<GPR:MODE>")]) 3133 3134(define_expand "extendqihi2" 3135 [(set (match_operand:HI 0 "register_operand") 3136 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand")))] 3137 "") 3138 3139(define_insn "*extendqihi2_mips16e" 3140 [(set (match_operand:HI 0 "register_operand" "=d,d") 3141 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,m")))] 3142 "GENERATE_MIPS16E" 3143 "@ 3144 seb\t%0 3145 lb\t%0,%1" 3146 [(set_attr "move_type" "signext,load") 3147 (set_attr "mode" "SI")]) 3148 3149(define_insn_and_split "*extendqihi2" 3150 [(set (match_operand:HI 0 "register_operand" "=d,d") 3151 (sign_extend:HI 3152 (match_operand:QI 1 "nonimmediate_operand" "d,m")))] 3153 "!ISA_HAS_SEB_SEH && !GENERATE_MIPS16E" 3154 "@ 3155 # 3156 lb\t%0,%1" 3157 "&& reload_completed && REG_P (operands[1])" 3158 [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2))) 3159 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 2)))] 3160{ 3161 operands[0] = gen_lowpart (SImode, operands[0]); 3162 operands[1] = gen_lowpart (SImode, operands[1]); 3163 operands[2] = GEN_INT (GET_MODE_BITSIZE (SImode) 3164 - GET_MODE_BITSIZE (QImode)); 3165} 3166 [(set_attr "move_type" "shift_shift,load") 3167 (set_attr "mode" "SI")]) 3168 3169(define_insn "*extendqihi2_seb" 3170 [(set (match_operand:HI 0 "register_operand" "=d,d") 3171 (sign_extend:HI 3172 (match_operand:QI 1 "nonimmediate_operand" "d,m")))] 3173 "ISA_HAS_SEB_SEH" 3174 "@ 3175 seb\t%0,%1 3176 lb\t%0,%1" 3177 [(set_attr "move_type" "signext,load") 3178 (set_attr "mode" "SI")]) 3179 3180;; Combiner patterns for truncate/sign_extend combinations. The SI versions 3181;; use the shift/truncate patterns. 3182 3183(define_insn_and_split "*extenddi_truncate<mode>" 3184 [(set (match_operand:DI 0 "register_operand" "=d") 3185 (sign_extend:DI 3186 (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))] 3187 "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS" 3188 "#" 3189 "&& reload_completed" 3190 [(set (match_dup 2) 3191 (ashift:DI (match_dup 1) 3192 (match_dup 3))) 3193 (set (match_dup 0) 3194 (ashiftrt:DI (match_dup 2) 3195 (match_dup 3)))] 3196{ 3197 operands[2] = gen_lowpart (DImode, operands[0]); 3198 operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode)); 3199} 3200 [(set_attr "move_type" "shift_shift") 3201 (set_attr "mode" "DI")]) 3202 3203(define_insn_and_split "*extendsi_truncate<mode>" 3204 [(set (match_operand:SI 0 "register_operand" "=d") 3205 (sign_extend:SI 3206 (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))] 3207 "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS" 3208 "#" 3209 "&& reload_completed" 3210 [(set (match_dup 2) 3211 (ashift:DI (match_dup 1) 3212 (match_dup 3))) 3213 (set (match_dup 0) 3214 (truncate:SI (ashiftrt:DI (match_dup 2) 3215 (match_dup 3))))] 3216{ 3217 operands[2] = gen_lowpart (DImode, operands[0]); 3218 operands[3] = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (<MODE>mode)); 3219} 3220 [(set_attr "move_type" "shift_shift") 3221 (set_attr "mode" "SI")]) 3222 3223(define_insn_and_split "*extendhi_truncateqi" 3224 [(set (match_operand:HI 0 "register_operand" "=d") 3225 (sign_extend:HI 3226 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))] 3227 "TARGET_64BIT && !TARGET_MIPS16 && !ISA_HAS_EXTS" 3228 "#" 3229 "&& reload_completed" 3230 [(set (match_dup 2) 3231 (ashift:DI (match_dup 1) 3232 (const_int 56))) 3233 (set (match_dup 0) 3234 (truncate:HI (ashiftrt:DI (match_dup 2) 3235 (const_int 56))))] 3236{ 3237 operands[2] = gen_lowpart (DImode, operands[0]); 3238} 3239 [(set_attr "move_type" "shift_shift") 3240 (set_attr "mode" "SI")]) 3241 3242(define_insn "*extend<GPR:mode>_truncate<SHORT:mode>_exts" 3243 [(set (match_operand:GPR 0 "register_operand" "=d") 3244 (sign_extend:GPR 3245 (truncate:SHORT (match_operand:DI 1 "register_operand" "d"))))] 3246 "TARGET_64BIT && !TARGET_MIPS16 && ISA_HAS_EXTS" 3247{ 3248 operands[2] = GEN_INT (GET_MODE_BITSIZE (<SHORT:MODE>mode)); 3249 return "exts\t%0,%1,0,%m2"; 3250} 3251 [(set_attr "type" "arith") 3252 (set_attr "mode" "<GPR:MODE>")]) 3253 3254(define_insn "*extendhi_truncateqi_exts" 3255 [(set (match_operand:HI 0 "register_operand" "=d") 3256 (sign_extend:HI 3257 (truncate:QI (match_operand:DI 1 "register_operand" "d"))))] 3258 "TARGET_64BIT && !TARGET_MIPS16 && ISA_HAS_EXTS" 3259 "exts\t%0,%1,0,7" 3260 [(set_attr "type" "arith") 3261 (set_attr "mode" "SI")]) 3262 3263(define_insn "extendsfdf2" 3264 [(set (match_operand:DF 0 "register_operand" "=f") 3265 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))] 3266 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 3267 "cvt.d.s\t%0,%1" 3268 [(set_attr "type" "fcvt") 3269 (set_attr "cnv_mode" "S2D") 3270 (set_attr "mode" "DF")]) 3271 3272;; 3273;; .................... 3274;; 3275;; CONVERSIONS 3276;; 3277;; .................... 3278 3279(define_expand "fix_truncdfsi2" 3280 [(set (match_operand:SI 0 "register_operand") 3281 (fix:SI (match_operand:DF 1 "register_operand")))] 3282 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 3283{ 3284 if (!ISA_HAS_TRUNC_W) 3285 { 3286 emit_insn (gen_fix_truncdfsi2_macro (operands[0], operands[1])); 3287 DONE; 3288 } 3289}) 3290 3291(define_insn "fix_truncdfsi2_insn" 3292 [(set (match_operand:SI 0 "register_operand" "=f") 3293 (fix:SI (match_operand:DF 1 "register_operand" "f")))] 3294 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && ISA_HAS_TRUNC_W" 3295 "trunc.w.d %0,%1" 3296 [(set_attr "type" "fcvt") 3297 (set_attr "mode" "DF") 3298 (set_attr "cnv_mode" "D2I")]) 3299 3300(define_insn "fix_truncdfsi2_macro" 3301 [(set (match_operand:SI 0 "register_operand" "=f") 3302 (fix:SI (match_operand:DF 1 "register_operand" "f"))) 3303 (clobber (match_scratch:DF 2 "=d"))] 3304 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !ISA_HAS_TRUNC_W" 3305{ 3306 if (mips_nomacro.nesting_level > 0) 3307 return ".set\tmacro\;trunc.w.d %0,%1,%2\;.set\tnomacro"; 3308 else 3309 return "trunc.w.d %0,%1,%2"; 3310} 3311 [(set_attr "type" "fcvt") 3312 (set_attr "mode" "DF") 3313 (set_attr "cnv_mode" "D2I") 3314 (set_attr "length" "36")]) 3315 3316(define_expand "fix_truncsfsi2" 3317 [(set (match_operand:SI 0 "register_operand") 3318 (fix:SI (match_operand:SF 1 "register_operand")))] 3319 "TARGET_HARD_FLOAT" 3320{ 3321 if (!ISA_HAS_TRUNC_W) 3322 { 3323 emit_insn (gen_fix_truncsfsi2_macro (operands[0], operands[1])); 3324 DONE; 3325 } 3326}) 3327 3328(define_insn "fix_truncsfsi2_insn" 3329 [(set (match_operand:SI 0 "register_operand" "=f") 3330 (fix:SI (match_operand:SF 1 "register_operand" "f")))] 3331 "TARGET_HARD_FLOAT && ISA_HAS_TRUNC_W" 3332 "trunc.w.s %0,%1" 3333 [(set_attr "type" "fcvt") 3334 (set_attr "mode" "SF") 3335 (set_attr "cnv_mode" "S2I")]) 3336 3337(define_insn "fix_truncsfsi2_macro" 3338 [(set (match_operand:SI 0 "register_operand" "=f") 3339 (fix:SI (match_operand:SF 1 "register_operand" "f"))) 3340 (clobber (match_scratch:SF 2 "=d"))] 3341 "TARGET_HARD_FLOAT && !ISA_HAS_TRUNC_W" 3342{ 3343 if (mips_nomacro.nesting_level > 0) 3344 return ".set\tmacro\;trunc.w.s %0,%1,%2\;.set\tnomacro"; 3345 else 3346 return "trunc.w.s %0,%1,%2"; 3347} 3348 [(set_attr "type" "fcvt") 3349 (set_attr "mode" "SF") 3350 (set_attr "cnv_mode" "S2I") 3351 (set_attr "length" "36")]) 3352 3353 3354(define_insn "fix_truncdfdi2" 3355 [(set (match_operand:DI 0 "register_operand" "=f") 3356 (fix:DI (match_operand:DF 1 "register_operand" "f")))] 3357 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT" 3358 "trunc.l.d %0,%1" 3359 [(set_attr "type" "fcvt") 3360 (set_attr "mode" "DF") 3361 (set_attr "cnv_mode" "D2I")]) 3362 3363 3364(define_insn "fix_truncsfdi2" 3365 [(set (match_operand:DI 0 "register_operand" "=f") 3366 (fix:DI (match_operand:SF 1 "register_operand" "f")))] 3367 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT" 3368 "trunc.l.s %0,%1" 3369 [(set_attr "type" "fcvt") 3370 (set_attr "mode" "SF") 3371 (set_attr "cnv_mode" "S2I")]) 3372 3373 3374(define_insn "floatsidf2" 3375 [(set (match_operand:DF 0 "register_operand" "=f") 3376 (float:DF (match_operand:SI 1 "register_operand" "f")))] 3377 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 3378 "cvt.d.w\t%0,%1" 3379 [(set_attr "type" "fcvt") 3380 (set_attr "mode" "DF") 3381 (set_attr "cnv_mode" "I2D")]) 3382 3383 3384(define_insn "floatdidf2" 3385 [(set (match_operand:DF 0 "register_operand" "=f") 3386 (float:DF (match_operand:DI 1 "register_operand" "f")))] 3387 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT" 3388 "cvt.d.l\t%0,%1" 3389 [(set_attr "type" "fcvt") 3390 (set_attr "mode" "DF") 3391 (set_attr "cnv_mode" "I2D")]) 3392 3393 3394(define_insn "floatsisf2" 3395 [(set (match_operand:SF 0 "register_operand" "=f") 3396 (float:SF (match_operand:SI 1 "register_operand" "f")))] 3397 "TARGET_HARD_FLOAT" 3398 "cvt.s.w\t%0,%1" 3399 [(set_attr "type" "fcvt") 3400 (set_attr "mode" "SF") 3401 (set_attr "cnv_mode" "I2S")]) 3402 3403 3404(define_insn "floatdisf2" 3405 [(set (match_operand:SF 0 "register_operand" "=f") 3406 (float:SF (match_operand:DI 1 "register_operand" "f")))] 3407 "TARGET_HARD_FLOAT && TARGET_FLOAT64 && TARGET_DOUBLE_FLOAT" 3408 "cvt.s.l\t%0,%1" 3409 [(set_attr "type" "fcvt") 3410 (set_attr "mode" "SF") 3411 (set_attr "cnv_mode" "I2S")]) 3412 3413 3414(define_expand "fixuns_truncdfsi2" 3415 [(set (match_operand:SI 0 "register_operand") 3416 (unsigned_fix:SI (match_operand:DF 1 "register_operand")))] 3417 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 3418{ 3419 rtx reg1 = gen_reg_rtx (DFmode); 3420 rtx reg2 = gen_reg_rtx (DFmode); 3421 rtx reg3 = gen_reg_rtx (SImode); 3422 rtx label1 = gen_label_rtx (); 3423 rtx label2 = gen_label_rtx (); 3424 rtx test; 3425 REAL_VALUE_TYPE offset; 3426 3427 real_2expN (&offset, 31, DFmode); 3428 3429 if (reg1) /* Turn off complaints about unreached code. */ 3430 { 3431 mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode)); 3432 do_pending_stack_adjust (); 3433 3434 test = gen_rtx_GE (VOIDmode, operands[1], reg1); 3435 emit_jump_insn (gen_cbranchdf4 (test, operands[1], reg1, label1)); 3436 3437 emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1])); 3438 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, 3439 gen_rtx_LABEL_REF (VOIDmode, label2))); 3440 emit_barrier (); 3441 3442 emit_label (label1); 3443 mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1)); 3444 mips_emit_move (reg3, GEN_INT (trunc_int_for_mode 3445 (BITMASK_HIGH, SImode))); 3446 3447 emit_insn (gen_fix_truncdfsi2 (operands[0], reg2)); 3448 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3)); 3449 3450 emit_label (label2); 3451 3452 /* Allow REG_NOTES to be set on last insn (labels don't have enough 3453 fields, and can't be used for REG_NOTES anyway). */ 3454 emit_use (stack_pointer_rtx); 3455 DONE; 3456 } 3457}) 3458 3459 3460(define_expand "fixuns_truncdfdi2" 3461 [(set (match_operand:DI 0 "register_operand") 3462 (unsigned_fix:DI (match_operand:DF 1 "register_operand")))] 3463 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT" 3464{ 3465 rtx reg1 = gen_reg_rtx (DFmode); 3466 rtx reg2 = gen_reg_rtx (DFmode); 3467 rtx reg3 = gen_reg_rtx (DImode); 3468 rtx label1 = gen_label_rtx (); 3469 rtx label2 = gen_label_rtx (); 3470 rtx test; 3471 REAL_VALUE_TYPE offset; 3472 3473 real_2expN (&offset, 63, DFmode); 3474 3475 mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, DFmode)); 3476 do_pending_stack_adjust (); 3477 3478 test = gen_rtx_GE (VOIDmode, operands[1], reg1); 3479 emit_jump_insn (gen_cbranchdf4 (test, operands[1], reg1, label1)); 3480 3481 emit_insn (gen_fix_truncdfdi2 (operands[0], operands[1])); 3482 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, 3483 gen_rtx_LABEL_REF (VOIDmode, label2))); 3484 emit_barrier (); 3485 3486 emit_label (label1); 3487 mips_emit_move (reg2, gen_rtx_MINUS (DFmode, operands[1], reg1)); 3488 mips_emit_move (reg3, GEN_INT (BITMASK_HIGH)); 3489 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32))); 3490 3491 emit_insn (gen_fix_truncdfdi2 (operands[0], reg2)); 3492 emit_insn (gen_iordi3 (operands[0], operands[0], reg3)); 3493 3494 emit_label (label2); 3495 3496 /* Allow REG_NOTES to be set on last insn (labels don't have enough 3497 fields, and can't be used for REG_NOTES anyway). */ 3498 emit_use (stack_pointer_rtx); 3499 DONE; 3500}) 3501 3502 3503(define_expand "fixuns_truncsfsi2" 3504 [(set (match_operand:SI 0 "register_operand") 3505 (unsigned_fix:SI (match_operand:SF 1 "register_operand")))] 3506 "TARGET_HARD_FLOAT" 3507{ 3508 rtx reg1 = gen_reg_rtx (SFmode); 3509 rtx reg2 = gen_reg_rtx (SFmode); 3510 rtx reg3 = gen_reg_rtx (SImode); 3511 rtx label1 = gen_label_rtx (); 3512 rtx label2 = gen_label_rtx (); 3513 rtx test; 3514 REAL_VALUE_TYPE offset; 3515 3516 real_2expN (&offset, 31, SFmode); 3517 3518 mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode)); 3519 do_pending_stack_adjust (); 3520 3521 test = gen_rtx_GE (VOIDmode, operands[1], reg1); 3522 emit_jump_insn (gen_cbranchsf4 (test, operands[1], reg1, label1)); 3523 3524 emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1])); 3525 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, 3526 gen_rtx_LABEL_REF (VOIDmode, label2))); 3527 emit_barrier (); 3528 3529 emit_label (label1); 3530 mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1)); 3531 mips_emit_move (reg3, GEN_INT (trunc_int_for_mode 3532 (BITMASK_HIGH, SImode))); 3533 3534 emit_insn (gen_fix_truncsfsi2 (operands[0], reg2)); 3535 emit_insn (gen_iorsi3 (operands[0], operands[0], reg3)); 3536 3537 emit_label (label2); 3538 3539 /* Allow REG_NOTES to be set on last insn (labels don't have enough 3540 fields, and can't be used for REG_NOTES anyway). */ 3541 emit_use (stack_pointer_rtx); 3542 DONE; 3543}) 3544 3545 3546(define_expand "fixuns_truncsfdi2" 3547 [(set (match_operand:DI 0 "register_operand") 3548 (unsigned_fix:DI (match_operand:SF 1 "register_operand")))] 3549 "TARGET_HARD_FLOAT && TARGET_64BIT && TARGET_DOUBLE_FLOAT" 3550{ 3551 rtx reg1 = gen_reg_rtx (SFmode); 3552 rtx reg2 = gen_reg_rtx (SFmode); 3553 rtx reg3 = gen_reg_rtx (DImode); 3554 rtx label1 = gen_label_rtx (); 3555 rtx label2 = gen_label_rtx (); 3556 rtx test; 3557 REAL_VALUE_TYPE offset; 3558 3559 real_2expN (&offset, 63, SFmode); 3560 3561 mips_emit_move (reg1, CONST_DOUBLE_FROM_REAL_VALUE (offset, SFmode)); 3562 do_pending_stack_adjust (); 3563 3564 test = gen_rtx_GE (VOIDmode, operands[1], reg1); 3565 emit_jump_insn (gen_cbranchsf4 (test, operands[1], reg1, label1)); 3566 3567 emit_insn (gen_fix_truncsfdi2 (operands[0], operands[1])); 3568 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, 3569 gen_rtx_LABEL_REF (VOIDmode, label2))); 3570 emit_barrier (); 3571 3572 emit_label (label1); 3573 mips_emit_move (reg2, gen_rtx_MINUS (SFmode, operands[1], reg1)); 3574 mips_emit_move (reg3, GEN_INT (BITMASK_HIGH)); 3575 emit_insn (gen_ashldi3 (reg3, reg3, GEN_INT (32))); 3576 3577 emit_insn (gen_fix_truncsfdi2 (operands[0], reg2)); 3578 emit_insn (gen_iordi3 (operands[0], operands[0], reg3)); 3579 3580 emit_label (label2); 3581 3582 /* Allow REG_NOTES to be set on last insn (labels don't have enough 3583 fields, and can't be used for REG_NOTES anyway). */ 3584 emit_use (stack_pointer_rtx); 3585 DONE; 3586}) 3587 3588;; 3589;; .................... 3590;; 3591;; DATA MOVEMENT 3592;; 3593;; .................... 3594 3595;; Bit field extract patterns which use lwl/lwr or ldl/ldr. 3596 3597(define_expand "extv" 3598 [(set (match_operand 0 "register_operand") 3599 (sign_extract (match_operand 1 "nonimmediate_operand") 3600 (match_operand 2 "const_int_operand") 3601 (match_operand 3 "const_int_operand")))] 3602 "!TARGET_MIPS16" 3603{ 3604 if (mips_expand_ext_as_unaligned_load (operands[0], operands[1], 3605 INTVAL (operands[2]), 3606 INTVAL (operands[3]))) 3607 DONE; 3608 else if (register_operand (operands[1], GET_MODE (operands[0])) 3609 && ISA_HAS_EXTS && UINTVAL (operands[2]) <= 32) 3610 { 3611 if (GET_MODE (operands[0]) == DImode) 3612 emit_insn (gen_extvdi (operands[0], operands[1], operands[2], 3613 operands[3])); 3614 else 3615 emit_insn (gen_extvsi (operands[0], operands[1], operands[2], 3616 operands[3])); 3617 DONE; 3618 } 3619 else 3620 FAIL; 3621}) 3622 3623(define_insn "extv<mode>" 3624 [(set (match_operand:GPR 0 "register_operand" "=d") 3625 (sign_extract:GPR (match_operand:GPR 1 "register_operand" "d") 3626 (match_operand 2 "const_int_operand" "") 3627 (match_operand 3 "const_int_operand" "")))] 3628 "ISA_HAS_EXTS && UINTVAL (operands[2]) <= 32" 3629 "exts\t%0,%1,%3,%m2" 3630 [(set_attr "type" "arith") 3631 (set_attr "mode" "<MODE>")]) 3632 3633 3634(define_expand "extzv" 3635 [(set (match_operand 0 "register_operand") 3636 (zero_extract (match_operand 1 "nonimmediate_operand") 3637 (match_operand 2 "const_int_operand") 3638 (match_operand 3 "const_int_operand")))] 3639 "!TARGET_MIPS16" 3640{ 3641 if (mips_expand_ext_as_unaligned_load (operands[0], operands[1], 3642 INTVAL (operands[2]), 3643 INTVAL (operands[3]))) 3644 DONE; 3645 else if (mips_use_ins_ext_p (operands[1], INTVAL (operands[2]), 3646 INTVAL (operands[3]))) 3647 { 3648 if (GET_MODE (operands[0]) == DImode) 3649 emit_insn (gen_extzvdi (operands[0], operands[1], operands[2], 3650 operands[3])); 3651 else 3652 emit_insn (gen_extzvsi (operands[0], operands[1], operands[2], 3653 operands[3])); 3654 DONE; 3655 } 3656 else 3657 FAIL; 3658}) 3659 3660(define_insn "extzv<mode>" 3661 [(set (match_operand:GPR 0 "register_operand" "=d") 3662 (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d") 3663 (match_operand 2 "const_int_operand" "") 3664 (match_operand 3 "const_int_operand" "")))] 3665 "mips_use_ins_ext_p (operands[1], INTVAL (operands[2]), 3666 INTVAL (operands[3]))" 3667 "<d>ext\t%0,%1,%3,%2" 3668 [(set_attr "type" "arith") 3669 (set_attr "mode" "<MODE>")]) 3670 3671(define_insn "*extzv_truncsi_exts" 3672 [(set (match_operand:SI 0 "register_operand" "=d") 3673 (truncate:SI 3674 (zero_extract:DI (match_operand:DI 1 "register_operand" "d") 3675 (match_operand 2 "const_int_operand" "") 3676 (match_operand 3 "const_int_operand" ""))))] 3677 "ISA_HAS_EXTS && TARGET_64BIT && IN_RANGE (INTVAL (operands[2]), 32, 63)" 3678 "exts\t%0,%1,%3,31" 3679 [(set_attr "type" "arith") 3680 (set_attr "mode" "SI")]) 3681 3682 3683(define_expand "insv" 3684 [(set (zero_extract (match_operand 0 "nonimmediate_operand") 3685 (match_operand 1 "immediate_operand") 3686 (match_operand 2 "immediate_operand")) 3687 (match_operand 3 "reg_or_0_operand"))] 3688 "!TARGET_MIPS16" 3689{ 3690 if (mips_expand_ins_as_unaligned_store (operands[0], operands[3], 3691 INTVAL (operands[1]), 3692 INTVAL (operands[2]))) 3693 DONE; 3694 else if (mips_use_ins_ext_p (operands[0], INTVAL (operands[1]), 3695 INTVAL (operands[2]))) 3696 { 3697 if (GET_MODE (operands[0]) == DImode) 3698 emit_insn (gen_insvdi (operands[0], operands[1], operands[2], 3699 operands[3])); 3700 else 3701 emit_insn (gen_insvsi (operands[0], operands[1], operands[2], 3702 operands[3])); 3703 DONE; 3704 } 3705 else 3706 FAIL; 3707}) 3708 3709(define_insn "insv<mode>" 3710 [(set (zero_extract:GPR (match_operand:GPR 0 "register_operand" "+d") 3711 (match_operand:SI 1 "immediate_operand" "I") 3712 (match_operand:SI 2 "immediate_operand" "I")) 3713 (match_operand:GPR 3 "reg_or_0_operand" "dJ"))] 3714 "mips_use_ins_ext_p (operands[0], INTVAL (operands[1]), 3715 INTVAL (operands[2]))" 3716 "<d>ins\t%0,%z3,%2,%1" 3717 [(set_attr "type" "arith") 3718 (set_attr "mode" "<MODE>")]) 3719 3720;; Combiner pattern for cins (clear and insert bit field). We can 3721;; implement mask-and-shift-left operation with this. Note that if 3722;; the upper bit of the mask is set in an SImode operation, the mask 3723;; itself will be sign-extended. mask_low_and_shift_len will 3724;; therefore be greater than our threshold of 32. 3725 3726(define_insn "*cins<mode>" 3727 [(set (match_operand:GPR 0 "register_operand" "=d") 3728 (and:GPR 3729 (ashift:GPR (match_operand:GPR 1 "register_operand" "d") 3730 (match_operand:GPR 2 "const_int_operand" "")) 3731 (match_operand:GPR 3 "const_int_operand" "")))] 3732 "ISA_HAS_CINS 3733 && mask_low_and_shift_p (<MODE>mode, operands[3], operands[2], 32)" 3734{ 3735 operands[3] = 3736 GEN_INT (mask_low_and_shift_len (<MODE>mode, operands[3], operands[2])); 3737 return "cins\t%0,%1,%2,%m3"; 3738} 3739 [(set_attr "type" "shift") 3740 (set_attr "mode" "<MODE>")]) 3741 3742;; Unaligned word moves generated by the bit field patterns. 3743;; 3744;; As far as the rtl is concerned, both the left-part and right-part 3745;; instructions can access the whole field. However, the real operand 3746;; refers to just the first or the last byte (depending on endianness). 3747;; We therefore use two memory operands to each instruction, one to 3748;; describe the rtl effect and one to use in the assembly output. 3749;; 3750;; Operands 0 and 1 are the rtl-level target and source respectively. 3751;; This allows us to use the standard length calculations for the "load" 3752;; and "store" type attributes. 3753 3754(define_insn "mov_<load>l" 3755 [(set (match_operand:GPR 0 "register_operand" "=d") 3756 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m") 3757 (match_operand:QI 2 "memory_operand" "m")] 3758 UNSPEC_LOAD_LEFT))] 3759 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])" 3760 "<load>l\t%0,%2" 3761 [(set_attr "move_type" "load") 3762 (set_attr "mode" "<MODE>")]) 3763 3764(define_insn "mov_<load>r" 3765 [(set (match_operand:GPR 0 "register_operand" "=d") 3766 (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m") 3767 (match_operand:QI 2 "memory_operand" "m") 3768 (match_operand:GPR 3 "register_operand" "0")] 3769 UNSPEC_LOAD_RIGHT))] 3770 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])" 3771 "<load>r\t%0,%2" 3772 [(set_attr "move_type" "load") 3773 (set_attr "mode" "<MODE>")]) 3774 3775(define_insn "mov_<store>l" 3776 [(set (match_operand:BLK 0 "memory_operand" "=m") 3777 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ") 3778 (match_operand:QI 2 "memory_operand" "m")] 3779 UNSPEC_STORE_LEFT))] 3780 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])" 3781 "<store>l\t%z1,%2" 3782 [(set_attr "move_type" "store") 3783 (set_attr "mode" "<MODE>")]) 3784 3785(define_insn "mov_<store>r" 3786 [(set (match_operand:BLK 0 "memory_operand" "+m") 3787 (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ") 3788 (match_operand:QI 2 "memory_operand" "m") 3789 (match_dup 0)] 3790 UNSPEC_STORE_RIGHT))] 3791 "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])" 3792 "<store>r\t%z1,%2" 3793 [(set_attr "move_type" "store") 3794 (set_attr "mode" "<MODE>")]) 3795 3796;; An instruction to calculate the high part of a 64-bit SYMBOL_ABSOLUTE. 3797;; The required value is: 3798;; 3799;; (%highest(op1) << 48) + (%higher(op1) << 32) + (%hi(op1) << 16) 3800;; 3801;; which translates to: 3802;; 3803;; lui op0,%highest(op1) 3804;; daddiu op0,op0,%higher(op1) 3805;; dsll op0,op0,16 3806;; daddiu op0,op0,%hi(op1) 3807;; dsll op0,op0,16 3808;; 3809;; The split is deferred until after flow2 to allow the peephole2 below 3810;; to take effect. 3811(define_insn_and_split "*lea_high64" 3812 [(set (match_operand:DI 0 "register_operand" "=d") 3813 (high:DI (match_operand:DI 1 "absolute_symbolic_operand" "")))] 3814 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS" 3815 "#" 3816 "&& epilogue_completed" 3817 [(set (match_dup 0) (high:DI (match_dup 2))) 3818 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2))) 3819 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16))) 3820 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3))) 3821 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))] 3822{ 3823 operands[2] = mips_unspec_address (operands[1], SYMBOL_64_HIGH); 3824 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_MID); 3825} 3826 [(set_attr "length" "20")]) 3827 3828;; Use a scratch register to reduce the latency of the above pattern 3829;; on superscalar machines. The optimized sequence is: 3830;; 3831;; lui op1,%highest(op2) 3832;; lui op0,%hi(op2) 3833;; daddiu op1,op1,%higher(op2) 3834;; dsll32 op1,op1,0 3835;; daddu op1,op1,op0 3836(define_peephole2 3837 [(set (match_operand:DI 1 "d_operand") 3838 (high:DI (match_operand:DI 2 "absolute_symbolic_operand"))) 3839 (match_scratch:DI 0 "d")] 3840 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS" 3841 [(set (match_dup 1) (high:DI (match_dup 3))) 3842 (set (match_dup 0) (high:DI (match_dup 4))) 3843 (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3))) 3844 (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32))) 3845 (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))] 3846{ 3847 operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH); 3848 operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW); 3849}) 3850 3851;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit 3852;; SYMBOL_ABSOLUTE X will take 6 cycles. This next pattern allows combine 3853;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only 3854;; used once. We can then use the sequence: 3855;; 3856;; lui op0,%highest(op1) 3857;; lui op2,%hi(op1) 3858;; daddiu op0,op0,%higher(op1) 3859;; daddiu op2,op2,%lo(op1) 3860;; dsll32 op0,op0,0 3861;; daddu op0,op0,op2 3862;; 3863;; which takes 4 cycles on most superscalar targets. 3864(define_insn_and_split "*lea64" 3865 [(set (match_operand:DI 0 "register_operand" "=d") 3866 (match_operand:DI 1 "absolute_symbolic_operand" "")) 3867 (clobber (match_scratch:DI 2 "=&d"))] 3868 "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected" 3869 "#" 3870 "&& reload_completed" 3871 [(set (match_dup 0) (high:DI (match_dup 3))) 3872 (set (match_dup 2) (high:DI (match_dup 4))) 3873 (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 3))) 3874 (set (match_dup 2) (lo_sum:DI (match_dup 2) (match_dup 4))) 3875 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32))) 3876 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))] 3877{ 3878 operands[3] = mips_unspec_address (operands[1], SYMBOL_64_HIGH); 3879 operands[4] = mips_unspec_address (operands[1], SYMBOL_64_LOW); 3880} 3881 [(set_attr "length" "24")]) 3882 3883;; Split HIGHs into: 3884;; 3885;; li op0,%hi(sym) 3886;; sll op0,16 3887;; 3888;; on MIPS16 targets. 3889(define_split 3890 [(set (match_operand:SI 0 "d_operand") 3891 (high:SI (match_operand:SI 1 "absolute_symbolic_operand")))] 3892 "TARGET_MIPS16 && reload_completed" 3893 [(set (match_dup 0) (match_dup 2)) 3894 (set (match_dup 0) (ashift:SI (match_dup 0) (const_int 16)))] 3895{ 3896 operands[2] = mips_unspec_address (operands[1], SYMBOL_32_HIGH); 3897}) 3898 3899;; Insns to fetch a symbol from a big GOT. 3900 3901(define_insn_and_split "*xgot_hi<mode>" 3902 [(set (match_operand:P 0 "register_operand" "=d") 3903 (high:P (match_operand:P 1 "got_disp_operand" "")))] 3904 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT" 3905 "#" 3906 "&& reload_completed" 3907 [(set (match_dup 0) (high:P (match_dup 2))) 3908 (set (match_dup 0) (plus:P (match_dup 0) (match_dup 3)))] 3909{ 3910 operands[2] = mips_unspec_address (operands[1], SYMBOL_GOTOFF_DISP); 3911 operands[3] = pic_offset_table_rtx; 3912} 3913 [(set_attr "got" "xgot_high") 3914 (set_attr "mode" "<MODE>")]) 3915 3916(define_insn_and_split "*xgot_lo<mode>" 3917 [(set (match_operand:P 0 "register_operand" "=d") 3918 (lo_sum:P (match_operand:P 1 "register_operand" "d") 3919 (match_operand:P 2 "got_disp_operand" "")))] 3920 "TARGET_EXPLICIT_RELOCS && TARGET_XGOT" 3921 "#" 3922 "&& reload_completed" 3923 [(set (match_dup 0) 3924 (unspec:P [(match_dup 1) (match_dup 3)] UNSPEC_LOAD_GOT))] 3925 { operands[3] = mips_unspec_address (operands[2], SYMBOL_GOTOFF_DISP); } 3926 [(set_attr "got" "load") 3927 (set_attr "mode" "<MODE>")]) 3928 3929;; Insns to fetch a symbol from a normal GOT. 3930 3931(define_insn_and_split "*got_disp<mode>" 3932 [(set (match_operand:P 0 "register_operand" "=d") 3933 (match_operand:P 1 "got_disp_operand" ""))] 3934 "TARGET_EXPLICIT_RELOCS && !mips_split_p[SYMBOL_GOT_DISP]" 3935 "#" 3936 "&& reload_completed" 3937 [(set (match_dup 0) (match_dup 2))] 3938 { operands[2] = mips_got_load (NULL, operands[1], SYMBOL_GOTOFF_DISP); } 3939 [(set_attr "got" "load") 3940 (set_attr "mode" "<MODE>")]) 3941 3942;; Insns for loading the "page" part of a page/ofst address from the GOT. 3943 3944(define_insn_and_split "*got_page<mode>" 3945 [(set (match_operand:P 0 "register_operand" "=d") 3946 (high:P (match_operand:P 1 "got_page_ofst_operand" "")))] 3947 "TARGET_EXPLICIT_RELOCS && !mips_split_hi_p[SYMBOL_GOT_PAGE_OFST]" 3948 "#" 3949 "&& reload_completed" 3950 [(set (match_dup 0) (match_dup 2))] 3951 { operands[2] = mips_got_load (NULL, operands[1], SYMBOL_GOTOFF_PAGE); } 3952 [(set_attr "got" "load") 3953 (set_attr "mode" "<MODE>")]) 3954 3955;; Convenience expander that generates the rhs of a load_got<mode> insn. 3956(define_expand "unspec_got<mode>" 3957 [(unspec:P [(match_operand:P 0) 3958 (match_operand:P 1)] UNSPEC_LOAD_GOT)]) 3959 3960;; Lower-level instructions for loading an address from the GOT. 3961;; We could use MEMs, but an unspec gives more optimization 3962;; opportunities. 3963 3964(define_insn "load_got<mode>" 3965 [(set (match_operand:P 0 "register_operand" "=d") 3966 (unspec:P [(match_operand:P 1 "register_operand" "d") 3967 (match_operand:P 2 "immediate_operand" "")] 3968 UNSPEC_LOAD_GOT))] 3969 "" 3970 "<load>\t%0,%R2(%1)" 3971 [(set_attr "got" "load") 3972 (set_attr "mode" "<MODE>")]) 3973 3974;; Instructions for adding the low 16 bits of an address to a register. 3975;; Operand 2 is the address: mips_print_operand works out which relocation 3976;; should be applied. 3977 3978(define_insn "*low<mode>" 3979 [(set (match_operand:P 0 "register_operand" "=d") 3980 (lo_sum:P (match_operand:P 1 "register_operand" "d") 3981 (match_operand:P 2 "immediate_operand" "")))] 3982 "!TARGET_MIPS16" 3983 "<d>addiu\t%0,%1,%R2" 3984 [(set_attr "type" "arith") 3985 (set_attr "mode" "<MODE>")]) 3986 3987(define_insn "*low<mode>_mips16" 3988 [(set (match_operand:P 0 "register_operand" "=d") 3989 (lo_sum:P (match_operand:P 1 "register_operand" "0") 3990 (match_operand:P 2 "immediate_operand" "")))] 3991 "TARGET_MIPS16" 3992 "<d>addiu\t%0,%R2" 3993 [(set_attr "type" "arith") 3994 (set_attr "mode" "<MODE>") 3995 (set_attr "extended_mips16" "yes")]) 3996 3997;; Expose MIPS16 uses of the global pointer after reload if the function 3998;; is responsible for setting up the register itself. 3999(define_split 4000 [(set (match_operand:GPR 0 "d_operand") 4001 (const:GPR (unspec:GPR [(const_int 0)] UNSPEC_GP)))] 4002 "TARGET_MIPS16 && TARGET_USE_GOT && reload_completed" 4003 [(set (match_dup 0) (match_dup 1))] 4004 { operands[1] = pic_offset_table_rtx; }) 4005 4006;; Allow combine to split complex const_int load sequences, using operand 2 4007;; to store the intermediate results. See move_operand for details. 4008(define_split 4009 [(set (match_operand:GPR 0 "register_operand") 4010 (match_operand:GPR 1 "splittable_const_int_operand")) 4011 (clobber (match_operand:GPR 2 "register_operand"))] 4012 "" 4013 [(const_int 0)] 4014{ 4015 mips_move_integer (operands[2], operands[0], INTVAL (operands[1])); 4016 DONE; 4017}) 4018 4019;; Likewise, for symbolic operands. 4020(define_split 4021 [(set (match_operand:P 0 "register_operand") 4022 (match_operand:P 1)) 4023 (clobber (match_operand:P 2 "register_operand"))] 4024 "mips_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)" 4025 [(set (match_dup 0) (match_dup 3))] 4026{ 4027 mips_split_symbol (operands[2], operands[1], 4028 MAX_MACHINE_MODE, &operands[3]); 4029}) 4030 4031;; 64-bit integer moves 4032 4033;; Unlike most other insns, the move insns can't be split with 4034;; different predicates, because register spilling and other parts of 4035;; the compiler, have memoized the insn number already. 4036 4037(define_expand "movdi" 4038 [(set (match_operand:DI 0 "") 4039 (match_operand:DI 1 ""))] 4040 "" 4041{ 4042 if (mips_legitimize_move (DImode, operands[0], operands[1])) 4043 DONE; 4044}) 4045 4046;; For mips16, we need a special case to handle storing $31 into 4047;; memory, since we don't have a constraint to match $31. This 4048;; instruction can be generated by save_restore_insns. 4049 4050(define_insn "*mov<mode>_ra" 4051 [(set (match_operand:GPR 0 "stack_operand" "=m") 4052 (reg:GPR RETURN_ADDR_REGNUM))] 4053 "TARGET_MIPS16" 4054 "<store>\t$31,%0" 4055 [(set_attr "move_type" "store") 4056 (set_attr "mode" "<MODE>")]) 4057 4058(define_insn "*movdi_32bit" 4059 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*f,*f,*d,*m,*B*C*D,*B*C*D,*d,*m") 4060 (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*J*d,*m,*f,*f,*d,*m,*B*C*D,*B*C*D"))] 4061 "!TARGET_64BIT && !TARGET_MIPS16 4062 && (register_operand (operands[0], DImode) 4063 || reg_or_0_operand (operands[1], DImode))" 4064 { return mips_output_move (operands[0], operands[1]); } 4065 [(set_attr "move_type" "move,const,load,store,mthilo,mfhilo,mtc,fpload,mfc,fpstore,mtc,fpload,mfc,fpstore") 4066 (set_attr "mode" "DI")]) 4067 4068(define_insn "*movdi_32bit_mips16" 4069 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d") 4070 (match_operand:DI 1 "move_operand" "d,d,y,K,N,m,d,*x"))] 4071 "!TARGET_64BIT && TARGET_MIPS16 4072 && (register_operand (operands[0], DImode) 4073 || register_operand (operands[1], DImode))" 4074 { return mips_output_move (operands[0], operands[1]); } 4075 [(set_attr "move_type" "move,move,move,const,constN,load,store,mfhilo") 4076 (set_attr "mode" "DI")]) 4077 4078(define_insn "*movdi_64bit" 4079 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*d,*m,*a,*d,*B*C*D,*B*C*D,*d,*m") 4080 (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*d*J,*m,*f,*f,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))] 4081 "TARGET_64BIT && !TARGET_MIPS16 4082 && (register_operand (operands[0], DImode) 4083 || reg_or_0_operand (operands[1], DImode))" 4084 { return mips_output_move (operands[0], operands[1]); } 4085 [(set_attr "move_type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mthilo,mfhilo,mtc,fpload,mfc,fpstore") 4086 (set_attr "mode" "DI")]) 4087 4088(define_insn "*movdi_64bit_mips16" 4089 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m,*d") 4090 (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,kf,m,d,*a"))] 4091 "TARGET_64BIT && TARGET_MIPS16 4092 && (register_operand (operands[0], DImode) 4093 || register_operand (operands[1], DImode))" 4094 { return mips_output_move (operands[0], operands[1]); } 4095 [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mfhilo") 4096 (set_attr "mode" "DI")]) 4097 4098;; On the mips16, we can split ld $r,N($r) into an add and a load, 4099;; when the original load is a 4 byte instruction but the add and the 4100;; load are 2 2 byte instructions. 4101 4102(define_split 4103 [(set (match_operand:DI 0 "d_operand") 4104 (mem:DI (plus:DI (match_dup 0) 4105 (match_operand:DI 1 "const_int_operand"))))] 4106 "TARGET_64BIT && TARGET_MIPS16 && reload_completed 4107 && !TARGET_DEBUG_D_MODE 4108 && ((INTVAL (operands[1]) < 0 4109 && INTVAL (operands[1]) >= -0x10) 4110 || (INTVAL (operands[1]) >= 32 * 8 4111 && INTVAL (operands[1]) <= 31 * 8 + 0x8) 4112 || (INTVAL (operands[1]) >= 0 4113 && INTVAL (operands[1]) < 32 * 8 4114 && (INTVAL (operands[1]) & 7) != 0))" 4115 [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1))) 4116 (set (match_dup 0) (mem:DI (plus:DI (match_dup 0) (match_dup 2))))] 4117{ 4118 HOST_WIDE_INT val = INTVAL (operands[1]); 4119 4120 if (val < 0) 4121 operands[2] = const0_rtx; 4122 else if (val >= 32 * 8) 4123 { 4124 int off = val & 7; 4125 4126 operands[1] = GEN_INT (0x8 + off); 4127 operands[2] = GEN_INT (val - off - 0x8); 4128 } 4129 else 4130 { 4131 int off = val & 7; 4132 4133 operands[1] = GEN_INT (off); 4134 operands[2] = GEN_INT (val - off); 4135 } 4136}) 4137 4138;; 32-bit Integer moves 4139 4140;; Unlike most other insns, the move insns can't be split with 4141;; different predicates, because register spilling and other parts of 4142;; the compiler, have memoized the insn number already. 4143 4144(define_expand "mov<mode>" 4145 [(set (match_operand:IMOVE32 0 "") 4146 (match_operand:IMOVE32 1 ""))] 4147 "" 4148{ 4149 if (mips_legitimize_move (<MODE>mode, operands[0], operands[1])) 4150 DONE; 4151}) 4152 4153;; The difference between these two is whether or not ints are allowed 4154;; in FP registers (off by default, use -mdebugh to enable). 4155 4156(define_insn "*mov<mode>_internal" 4157 [(set (match_operand:IMOVE32 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*d,*m,*d,*z,*a,*d,*B*C*D,*B*C*D,*d,*m") 4158 (match_operand:IMOVE32 1 "move_operand" "d,U,T,m,dJ,*d*J,*m,*f,*f,*z,*d,*J*d,*a,*d,*m,*B*C*D,*B*C*D"))] 4159 "!TARGET_MIPS16 4160 && (register_operand (operands[0], <MODE>mode) 4161 || reg_or_0_operand (operands[1], <MODE>mode))" 4162 { return mips_output_move (operands[0], operands[1]); } 4163 [(set_attr "move_type" "move,const,const,load,store,mtc,fpload,mfc,fpstore,mfc,mtc,mthilo,mfhilo,mtc,fpload,mfc,fpstore") 4164 (set_attr "mode" "SI")]) 4165 4166(define_insn "*mov<mode>_mips16" 4167 [(set (match_operand:IMOVE32 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,m,*d") 4168 (match_operand:IMOVE32 1 "move_operand" "d,d,y,K,N,U,kf,m,d,*a"))] 4169 "TARGET_MIPS16 4170 && (register_operand (operands[0], <MODE>mode) 4171 || register_operand (operands[1], <MODE>mode))" 4172 { return mips_output_move (operands[0], operands[1]); } 4173 [(set_attr "move_type" "move,move,move,const,constN,const,loadpool,load,store,mfhilo") 4174 (set_attr "mode" "SI")]) 4175 4176;; On the mips16, we can split lw $r,N($r) into an add and a load, 4177;; when the original load is a 4 byte instruction but the add and the 4178;; load are 2 2 byte instructions. 4179 4180(define_split 4181 [(set (match_operand:SI 0 "d_operand") 4182 (mem:SI (plus:SI (match_dup 0) 4183 (match_operand:SI 1 "const_int_operand"))))] 4184 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE 4185 && ((INTVAL (operands[1]) < 0 4186 && INTVAL (operands[1]) >= -0x80) 4187 || (INTVAL (operands[1]) >= 32 * 4 4188 && INTVAL (operands[1]) <= 31 * 4 + 0x7c) 4189 || (INTVAL (operands[1]) >= 0 4190 && INTVAL (operands[1]) < 32 * 4 4191 && (INTVAL (operands[1]) & 3) != 0))" 4192 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) 4193 (set (match_dup 0) (mem:SI (plus:SI (match_dup 0) (match_dup 2))))] 4194{ 4195 HOST_WIDE_INT val = INTVAL (operands[1]); 4196 4197 if (val < 0) 4198 operands[2] = const0_rtx; 4199 else if (val >= 32 * 4) 4200 { 4201 int off = val & 3; 4202 4203 operands[1] = GEN_INT (0x7c + off); 4204 operands[2] = GEN_INT (val - off - 0x7c); 4205 } 4206 else 4207 { 4208 int off = val & 3; 4209 4210 operands[1] = GEN_INT (off); 4211 operands[2] = GEN_INT (val - off); 4212 } 4213}) 4214 4215;; On the mips16, we can split a load of certain constants into a load 4216;; and an add. This turns a 4 byte instruction into 2 2 byte 4217;; instructions. 4218 4219(define_split 4220 [(set (match_operand:SI 0 "d_operand") 4221 (match_operand:SI 1 "const_int_operand"))] 4222 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE 4223 && INTVAL (operands[1]) >= 0x100 4224 && INTVAL (operands[1]) <= 0xff + 0x7f" 4225 [(set (match_dup 0) (match_dup 1)) 4226 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))] 4227{ 4228 int val = INTVAL (operands[1]); 4229 4230 operands[1] = GEN_INT (0xff); 4231 operands[2] = GEN_INT (val - 0xff); 4232}) 4233 4234;; This insn handles moving CCmode values. It's really just a 4235;; slightly simplified copy of movsi_internal2, with additional cases 4236;; to move a condition register to a general register and to move 4237;; between the general registers and the floating point registers. 4238 4239(define_insn "movcc" 4240 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m") 4241 (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))] 4242 "ISA_HAS_8CC && TARGET_HARD_FLOAT" 4243 { return mips_output_move (operands[0], operands[1]); } 4244 [(set_attr "move_type" "lui_movf,move,load,store,mfc,mtc,fmove,fpload,fpstore") 4245 (set_attr "mode" "SI")]) 4246 4247;; Reload condition code registers. reload_incc and reload_outcc 4248;; both handle moves from arbitrary operands into condition code 4249;; registers. reload_incc handles the more common case in which 4250;; a source operand is constrained to be in a condition-code 4251;; register, but has not been allocated to one. 4252;; 4253;; Sometimes, such as in movcc, we have a CCmode destination whose 4254;; constraints do not include 'z'. reload_outcc handles the case 4255;; when such an operand is allocated to a condition-code register. 4256;; 4257;; Note that reloads from a condition code register to some 4258;; other location can be done using ordinary moves. Moving 4259;; into a GPR takes a single movcc, moving elsewhere takes 4260;; two. We can leave these cases to the generic reload code. 4261(define_expand "reload_incc" 4262 [(set (match_operand:CC 0 "fcc_reload_operand" "=z") 4263 (match_operand:CC 1 "general_operand" "")) 4264 (clobber (match_operand:TF 2 "register_operand" "=&f"))] 4265 "ISA_HAS_8CC && TARGET_HARD_FLOAT" 4266{ 4267 mips_expand_fcc_reload (operands[0], operands[1], operands[2]); 4268 DONE; 4269}) 4270 4271(define_expand "reload_outcc" 4272 [(set (match_operand:CC 0 "fcc_reload_operand" "=z") 4273 (match_operand:CC 1 "register_operand" "")) 4274 (clobber (match_operand:TF 2 "register_operand" "=&f"))] 4275 "ISA_HAS_8CC && TARGET_HARD_FLOAT" 4276{ 4277 mips_expand_fcc_reload (operands[0], operands[1], operands[2]); 4278 DONE; 4279}) 4280 4281;; MIPS4 supports loading and storing a floating point register from 4282;; the sum of two general registers. We use two versions for each of 4283;; these four instructions: one where the two general registers are 4284;; SImode, and one where they are DImode. This is because general 4285;; registers will be in SImode when they hold 32-bit values, but, 4286;; since the 32-bit values are always sign extended, the [ls][wd]xc1 4287;; instructions will still work correctly. 4288 4289;; ??? Perhaps it would be better to support these instructions by 4290;; modifying TARGET_LEGITIMATE_ADDRESS_P and friends. However, since 4291;; these instructions can only be used to load and store floating 4292;; point registers, that would probably cause trouble in reload. 4293 4294(define_insn "*<ANYF:loadx>_<P:mode>" 4295 [(set (match_operand:ANYF 0 "register_operand" "=f") 4296 (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d") 4297 (match_operand:P 2 "register_operand" "d"))))] 4298 "ISA_HAS_FP4" 4299 "<ANYF:loadx>\t%0,%1(%2)" 4300 [(set_attr "type" "fpidxload") 4301 (set_attr "mode" "<ANYF:UNITMODE>")]) 4302 4303(define_insn "*<ANYF:storex>_<P:mode>" 4304 [(set (mem:ANYF (plus:P (match_operand:P 1 "register_operand" "d") 4305 (match_operand:P 2 "register_operand" "d"))) 4306 (match_operand:ANYF 0 "register_operand" "f"))] 4307 "ISA_HAS_FP4" 4308 "<ANYF:storex>\t%0,%1(%2)" 4309 [(set_attr "type" "fpidxstore") 4310 (set_attr "mode" "<ANYF:UNITMODE>")]) 4311 4312;; Scaled indexed address load. 4313;; Per md.texi, we only need to look for a pattern with multiply in the 4314;; address expression, not shift. 4315 4316(define_insn "*lwxs" 4317 [(set (match_operand:IMOVE32 0 "register_operand" "=d") 4318 (mem:IMOVE32 4319 (plus:P (mult:P (match_operand:P 1 "register_operand" "d") 4320 (const_int 4)) 4321 (match_operand:P 2 "register_operand" "d"))))] 4322 "ISA_HAS_LWXS" 4323 "lwxs\t%0,%1(%2)" 4324 [(set_attr "type" "load") 4325 (set_attr "mode" "SI")]) 4326 4327;; 16-bit Integer moves 4328 4329;; Unlike most other insns, the move insns can't be split with 4330;; different predicates, because register spilling and other parts of 4331;; the compiler, have memoized the insn number already. 4332;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND. 4333 4334(define_expand "movhi" 4335 [(set (match_operand:HI 0 "") 4336 (match_operand:HI 1 ""))] 4337 "" 4338{ 4339 if (mips_legitimize_move (HImode, operands[0], operands[1])) 4340 DONE; 4341}) 4342 4343(define_insn "*movhi_internal" 4344 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d") 4345 (match_operand:HI 1 "move_operand" "d,I,m,dJ,*d*J,*a"))] 4346 "!TARGET_MIPS16 4347 && (register_operand (operands[0], HImode) 4348 || reg_or_0_operand (operands[1], HImode))" 4349 { return mips_output_move (operands[0], operands[1]); } 4350 [(set_attr "move_type" "move,const,load,store,mthilo,mfhilo") 4351 (set_attr "mode" "HI")]) 4352 4353(define_insn "*movhi_mips16" 4354 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d") 4355 (match_operand:HI 1 "move_operand" "d,d,y,K,N,m,d,*a"))] 4356 "TARGET_MIPS16 4357 && (register_operand (operands[0], HImode) 4358 || register_operand (operands[1], HImode))" 4359 { return mips_output_move (operands[0], operands[1]); } 4360 [(set_attr "move_type" "move,move,move,const,constN,load,store,mfhilo") 4361 (set_attr "mode" "HI")]) 4362 4363;; On the mips16, we can split lh $r,N($r) into an add and a load, 4364;; when the original load is a 4 byte instruction but the add and the 4365;; load are 2 2 byte instructions. 4366 4367(define_split 4368 [(set (match_operand:HI 0 "d_operand") 4369 (mem:HI (plus:SI (match_dup 0) 4370 (match_operand:SI 1 "const_int_operand"))))] 4371 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE 4372 && ((INTVAL (operands[1]) < 0 4373 && INTVAL (operands[1]) >= -0x80) 4374 || (INTVAL (operands[1]) >= 32 * 2 4375 && INTVAL (operands[1]) <= 31 * 2 + 0x7e) 4376 || (INTVAL (operands[1]) >= 0 4377 && INTVAL (operands[1]) < 32 * 2 4378 && (INTVAL (operands[1]) & 1) != 0))" 4379 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) 4380 (set (match_dup 0) (mem:HI (plus:SI (match_dup 0) (match_dup 2))))] 4381{ 4382 HOST_WIDE_INT val = INTVAL (operands[1]); 4383 4384 if (val < 0) 4385 operands[2] = const0_rtx; 4386 else if (val >= 32 * 2) 4387 { 4388 int off = val & 1; 4389 4390 operands[1] = GEN_INT (0x7e + off); 4391 operands[2] = GEN_INT (val - off - 0x7e); 4392 } 4393 else 4394 { 4395 int off = val & 1; 4396 4397 operands[1] = GEN_INT (off); 4398 operands[2] = GEN_INT (val - off); 4399 } 4400}) 4401 4402;; 8-bit Integer moves 4403 4404;; Unlike most other insns, the move insns can't be split with 4405;; different predicates, because register spilling and other parts of 4406;; the compiler, have memoized the insn number already. 4407;; Unsigned loads are used because LOAD_EXTEND_OP returns ZERO_EXTEND. 4408 4409(define_expand "movqi" 4410 [(set (match_operand:QI 0 "") 4411 (match_operand:QI 1 ""))] 4412 "" 4413{ 4414 if (mips_legitimize_move (QImode, operands[0], operands[1])) 4415 DONE; 4416}) 4417 4418(define_insn "*movqi_internal" 4419 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d") 4420 (match_operand:QI 1 "move_operand" "d,I,m,dJ,*d*J,*a"))] 4421 "!TARGET_MIPS16 4422 && (register_operand (operands[0], QImode) 4423 || reg_or_0_operand (operands[1], QImode))" 4424 { return mips_output_move (operands[0], operands[1]); } 4425 [(set_attr "move_type" "move,const,load,store,mthilo,mfhilo") 4426 (set_attr "mode" "QI")]) 4427 4428(define_insn "*movqi_mips16" 4429 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d") 4430 (match_operand:QI 1 "move_operand" "d,d,y,K,N,m,d,*a"))] 4431 "TARGET_MIPS16 4432 && (register_operand (operands[0], QImode) 4433 || register_operand (operands[1], QImode))" 4434 { return mips_output_move (operands[0], operands[1]); } 4435 [(set_attr "move_type" "move,move,move,const,constN,load,store,mfhilo") 4436 (set_attr "mode" "QI")]) 4437 4438;; On the mips16, we can split lb $r,N($r) into an add and a load, 4439;; when the original load is a 4 byte instruction but the add and the 4440;; load are 2 2 byte instructions. 4441 4442(define_split 4443 [(set (match_operand:QI 0 "d_operand") 4444 (mem:QI (plus:SI (match_dup 0) 4445 (match_operand:SI 1 "const_int_operand"))))] 4446 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE 4447 && ((INTVAL (operands[1]) < 0 4448 && INTVAL (operands[1]) >= -0x80) 4449 || (INTVAL (operands[1]) >= 32 4450 && INTVAL (operands[1]) <= 31 + 0x7f))" 4451 [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1))) 4452 (set (match_dup 0) (mem:QI (plus:SI (match_dup 0) (match_dup 2))))] 4453{ 4454 HOST_WIDE_INT val = INTVAL (operands[1]); 4455 4456 if (val < 0) 4457 operands[2] = const0_rtx; 4458 else 4459 { 4460 operands[1] = GEN_INT (0x7f); 4461 operands[2] = GEN_INT (val - 0x7f); 4462 } 4463}) 4464 4465;; 32-bit floating point moves 4466 4467(define_expand "movsf" 4468 [(set (match_operand:SF 0 "") 4469 (match_operand:SF 1 ""))] 4470 "" 4471{ 4472 if (mips_legitimize_move (SFmode, operands[0], operands[1])) 4473 DONE; 4474}) 4475 4476(define_insn "*movsf_hardfloat" 4477 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m") 4478 (match_operand:SF 1 "move_operand" "f,G,m,f,G,*d,*f,*G*d,*m,*d"))] 4479 "TARGET_HARD_FLOAT 4480 && (register_operand (operands[0], SFmode) 4481 || reg_or_0_operand (operands[1], SFmode))" 4482 { return mips_output_move (operands[0], operands[1]); } 4483 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") 4484 (set_attr "mode" "SF")]) 4485 4486(define_insn "*movsf_softfloat" 4487 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m") 4488 (match_operand:SF 1 "move_operand" "Gd,m,d"))] 4489 "TARGET_SOFT_FLOAT && !TARGET_MIPS16 4490 && (register_operand (operands[0], SFmode) 4491 || reg_or_0_operand (operands[1], SFmode))" 4492 { return mips_output_move (operands[0], operands[1]); } 4493 [(set_attr "move_type" "move,load,store") 4494 (set_attr "mode" "SF")]) 4495 4496(define_insn "*movsf_mips16" 4497 [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m") 4498 (match_operand:SF 1 "move_operand" "d,d,y,m,d"))] 4499 "TARGET_MIPS16 4500 && (register_operand (operands[0], SFmode) 4501 || register_operand (operands[1], SFmode))" 4502 { return mips_output_move (operands[0], operands[1]); } 4503 [(set_attr "move_type" "move,move,move,load,store") 4504 (set_attr "mode" "SF")]) 4505 4506;; 64-bit floating point moves 4507 4508(define_expand "movdf" 4509 [(set (match_operand:DF 0 "") 4510 (match_operand:DF 1 ""))] 4511 "" 4512{ 4513 if (mips_legitimize_move (DFmode, operands[0], operands[1])) 4514 DONE; 4515}) 4516 4517(define_insn "*movdf_hardfloat" 4518 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m") 4519 (match_operand:DF 1 "move_operand" "f,G,m,f,G,*d,*f,*d*G,*m,*d"))] 4520 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT 4521 && (register_operand (operands[0], DFmode) 4522 || reg_or_0_operand (operands[1], DFmode))" 4523 { return mips_output_move (operands[0], operands[1]); } 4524 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") 4525 (set_attr "mode" "DF")]) 4526 4527(define_insn "*movdf_softfloat" 4528 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m") 4529 (match_operand:DF 1 "move_operand" "dG,m,dG"))] 4530 "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16 4531 && (register_operand (operands[0], DFmode) 4532 || reg_or_0_operand (operands[1], DFmode))" 4533 { return mips_output_move (operands[0], operands[1]); } 4534 [(set_attr "move_type" "move,load,store") 4535 (set_attr "mode" "DF")]) 4536 4537(define_insn "*movdf_mips16" 4538 [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m") 4539 (match_operand:DF 1 "move_operand" "d,d,y,m,d"))] 4540 "TARGET_MIPS16 4541 && (register_operand (operands[0], DFmode) 4542 || register_operand (operands[1], DFmode))" 4543 { return mips_output_move (operands[0], operands[1]); } 4544 [(set_attr "move_type" "move,move,move,load,store") 4545 (set_attr "mode" "DF")]) 4546 4547;; 128-bit integer moves 4548 4549(define_expand "movti" 4550 [(set (match_operand:TI 0) 4551 (match_operand:TI 1))] 4552 "TARGET_64BIT" 4553{ 4554 if (mips_legitimize_move (TImode, operands[0], operands[1])) 4555 DONE; 4556}) 4557 4558(define_insn "*movti" 4559 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d") 4560 (match_operand:TI 1 "move_operand" "d,i,m,dJ,*d*J,*a"))] 4561 "TARGET_64BIT 4562 && !TARGET_MIPS16 4563 && (register_operand (operands[0], TImode) 4564 || reg_or_0_operand (operands[1], TImode))" 4565 "#" 4566 [(set_attr "move_type" "move,const,load,store,mthilo,mfhilo") 4567 (set_attr "mode" "TI")]) 4568 4569(define_insn "*movti_mips16" 4570 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d") 4571 (match_operand:TI 1 "move_operand" "d,d,y,K,N,m,d,*a"))] 4572 "TARGET_64BIT 4573 && TARGET_MIPS16 4574 && (register_operand (operands[0], TImode) 4575 || register_operand (operands[1], TImode))" 4576 "#" 4577 [(set_attr "move_type" "move,move,move,const,constN,load,store,mfhilo") 4578 (set_attr "mode" "TI")]) 4579 4580;; 128-bit floating point moves 4581 4582(define_expand "movtf" 4583 [(set (match_operand:TF 0) 4584 (match_operand:TF 1))] 4585 "TARGET_64BIT" 4586{ 4587 if (mips_legitimize_move (TFmode, operands[0], operands[1])) 4588 DONE; 4589}) 4590 4591;; This pattern handles both hard- and soft-float cases. 4592(define_insn "*movtf" 4593 [(set (match_operand:TF 0 "nonimmediate_operand" "=d,d,m,f,d,f,m") 4594 (match_operand:TF 1 "move_operand" "dG,m,dG,dG,f,m,f"))] 4595 "TARGET_64BIT 4596 && !TARGET_MIPS16 4597 && (register_operand (operands[0], TFmode) 4598 || reg_or_0_operand (operands[1], TFmode))" 4599 "#" 4600 [(set_attr "move_type" "move,load,store,mtc,mfc,fpload,fpstore") 4601 (set_attr "mode" "TF")]) 4602 4603(define_insn "*movtf_mips16" 4604 [(set (match_operand:TF 0 "nonimmediate_operand" "=d,y,d,d,m") 4605 (match_operand:TF 1 "move_operand" "d,d,y,m,d"))] 4606 "TARGET_64BIT 4607 && TARGET_MIPS16 4608 && (register_operand (operands[0], TFmode) 4609 || register_operand (operands[1], TFmode))" 4610 "#" 4611 [(set_attr "move_type" "move,move,move,load,store") 4612 (set_attr "mode" "TF")]) 4613 4614(define_split 4615 [(set (match_operand:MOVE64 0 "nonimmediate_operand") 4616 (match_operand:MOVE64 1 "move_operand"))] 4617 "reload_completed && !TARGET_64BIT 4618 && mips_split_64bit_move_p (operands[0], operands[1])" 4619 [(const_int 0)] 4620{ 4621 mips_split_doubleword_move (operands[0], operands[1]); 4622 DONE; 4623}) 4624 4625(define_split 4626 [(set (match_operand:MOVE128 0 "nonimmediate_operand") 4627 (match_operand:MOVE128 1 "move_operand"))] 4628 "TARGET_64BIT && reload_completed" 4629 [(const_int 0)] 4630{ 4631 mips_split_doubleword_move (operands[0], operands[1]); 4632 DONE; 4633}) 4634 4635;; When generating mips16 code, split moves of negative constants into 4636;; a positive "li" followed by a negation. 4637(define_split 4638 [(set (match_operand 0 "d_operand") 4639 (match_operand 1 "const_int_operand"))] 4640 "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0" 4641 [(set (match_dup 2) 4642 (match_dup 3)) 4643 (set (match_dup 2) 4644 (neg:SI (match_dup 2)))] 4645{ 4646 operands[2] = gen_lowpart (SImode, operands[0]); 4647 operands[3] = GEN_INT (-INTVAL (operands[1])); 4648}) 4649 4650;; 64-bit paired-single floating point moves 4651 4652(define_expand "movv2sf" 4653 [(set (match_operand:V2SF 0) 4654 (match_operand:V2SF 1))] 4655 "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT" 4656{ 4657 if (mips_legitimize_move (V2SFmode, operands[0], operands[1])) 4658 DONE; 4659}) 4660 4661(define_insn "*movv2sf" 4662 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m") 4663 (match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))] 4664 "TARGET_HARD_FLOAT 4665 && TARGET_PAIRED_SINGLE_FLOAT 4666 && (register_operand (operands[0], V2SFmode) 4667 || reg_or_0_operand (operands[1], V2SFmode))" 4668 { return mips_output_move (operands[0], operands[1]); } 4669 [(set_attr "move_type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store") 4670 (set_attr "mode" "DF")]) 4671 4672;; Extract the high part of a HI/LO value. See mips_hard_regno_mode_ok_p 4673;; for the reason why we can't just use (reg:GPR HI_REGNUM). 4674;; 4675;; When generating VR4120 or VR4130 code, we use MACCHI and DMACCHI 4676;; instead of MFHI. This avoids both the normal MIPS III hi/lo hazards 4677;; and the errata related to -mfix-vr4130. 4678(define_insn "mfhi<GPR:mode>_<HILO:mode>" 4679 [(set (match_operand:GPR 0 "register_operand" "=d") 4680 (unspec:GPR [(match_operand:HILO 1 "register_operand" "x")] 4681 UNSPEC_MFHI))] 4682 "" 4683 { return ISA_HAS_MACCHI ? "<GPR:d>macchi\t%0,%.,%." : "mfhi\t%0"; } 4684 [(set_attr "move_type" "mfhilo") 4685 (set_attr "mode" "<GPR:MODE>")]) 4686 4687;; Set the high part of a HI/LO value, given that the low part has 4688;; already been set. See mips_hard_regno_mode_ok_p for the reason 4689;; why we can't just use (reg:GPR HI_REGNUM). 4690(define_insn "mthi<GPR:mode>_<HILO:mode>" 4691 [(set (match_operand:HILO 0 "register_operand" "=x") 4692 (unspec:HILO [(match_operand:GPR 1 "reg_or_0_operand" "dJ") 4693 (match_operand:GPR 2 "register_operand" "l")] 4694 UNSPEC_MTHI))] 4695 "" 4696 "mthi\t%z1" 4697 [(set_attr "move_type" "mthilo") 4698 (set_attr "mode" "SI")]) 4699 4700;; Emit a doubleword move in which exactly one of the operands is 4701;; a floating-point register. We can't just emit two normal moves 4702;; because of the constraints imposed by the FPU register model; 4703;; see mips_cannot_change_mode_class for details. Instead, we keep 4704;; the FPR whole and use special patterns to refer to each word of 4705;; the other operand. 4706 4707(define_expand "move_doubleword_fpr<mode>" 4708 [(set (match_operand:SPLITF 0) 4709 (match_operand:SPLITF 1))] 4710 "" 4711{ 4712 if (FP_REG_RTX_P (operands[0])) 4713 { 4714 rtx low = mips_subword (operands[1], 0); 4715 rtx high = mips_subword (operands[1], 1); 4716 emit_insn (gen_load_low<mode> (operands[0], low)); 4717 if (TARGET_FLOAT64 && !TARGET_64BIT) 4718 emit_insn (gen_mthc1<mode> (operands[0], high, operands[0])); 4719 else 4720 emit_insn (gen_load_high<mode> (operands[0], high, operands[0])); 4721 } 4722 else 4723 { 4724 rtx low = mips_subword (operands[0], 0); 4725 rtx high = mips_subword (operands[0], 1); 4726 emit_insn (gen_store_word<mode> (low, operands[1], const0_rtx)); 4727 if (TARGET_FLOAT64 && !TARGET_64BIT) 4728 emit_insn (gen_mfhc1<mode> (high, operands[1])); 4729 else 4730 emit_insn (gen_store_word<mode> (high, operands[1], const1_rtx)); 4731 } 4732 DONE; 4733}) 4734 4735;; Load the low word of operand 0 with operand 1. 4736(define_insn "load_low<mode>" 4737 [(set (match_operand:SPLITF 0 "register_operand" "=f,f") 4738 (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m")] 4739 UNSPEC_LOAD_LOW))] 4740 "TARGET_HARD_FLOAT" 4741{ 4742 operands[0] = mips_subword (operands[0], 0); 4743 return mips_output_move (operands[0], operands[1]); 4744} 4745 [(set_attr "move_type" "mtc,fpload") 4746 (set_attr "mode" "<HALFMODE>")]) 4747 4748;; Load the high word of operand 0 from operand 1, preserving the value 4749;; in the low word. 4750(define_insn "load_high<mode>" 4751 [(set (match_operand:SPLITF 0 "register_operand" "=f,f") 4752 (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m") 4753 (match_operand:SPLITF 2 "register_operand" "0,0")] 4754 UNSPEC_LOAD_HIGH))] 4755 "TARGET_HARD_FLOAT" 4756{ 4757 operands[0] = mips_subword (operands[0], 1); 4758 return mips_output_move (operands[0], operands[1]); 4759} 4760 [(set_attr "move_type" "mtc,fpload") 4761 (set_attr "mode" "<HALFMODE>")]) 4762 4763;; Store one word of operand 1 in operand 0. Operand 2 is 1 to store the 4764;; high word and 0 to store the low word. 4765(define_insn "store_word<mode>" 4766 [(set (match_operand:<HALFMODE> 0 "nonimmediate_operand" "=d,m") 4767 (unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f,f") 4768 (match_operand 2 "const_int_operand")] 4769 UNSPEC_STORE_WORD))] 4770 "TARGET_HARD_FLOAT" 4771{ 4772 operands[1] = mips_subword (operands[1], INTVAL (operands[2])); 4773 return mips_output_move (operands[0], operands[1]); 4774} 4775 [(set_attr "move_type" "mfc,fpstore") 4776 (set_attr "mode" "<HALFMODE>")]) 4777 4778;; Move operand 1 to the high word of operand 0 using mthc1, preserving the 4779;; value in the low word. 4780(define_insn "mthc1<mode>" 4781 [(set (match_operand:SPLITF 0 "register_operand" "=f") 4782 (unspec:SPLITF [(match_operand:<HALFMODE> 1 "reg_or_0_operand" "dJ") 4783 (match_operand:SPLITF 2 "register_operand" "0")] 4784 UNSPEC_MTHC1))] 4785 "TARGET_HARD_FLOAT && ISA_HAS_MXHC1" 4786 "mthc1\t%z1,%0" 4787 [(set_attr "move_type" "mtc") 4788 (set_attr "mode" "<HALFMODE>")]) 4789 4790;; Move high word of operand 1 to operand 0 using mfhc1. 4791(define_insn "mfhc1<mode>" 4792 [(set (match_operand:<HALFMODE> 0 "register_operand" "=d") 4793 (unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f")] 4794 UNSPEC_MFHC1))] 4795 "TARGET_HARD_FLOAT && ISA_HAS_MXHC1" 4796 "mfhc1\t%0,%1" 4797 [(set_attr "move_type" "mfc") 4798 (set_attr "mode" "<HALFMODE>")]) 4799 4800;; Move a constant that satisfies CONST_GP_P into operand 0. 4801(define_expand "load_const_gp_<mode>" 4802 [(set (match_operand:P 0 "register_operand" "=d") 4803 (const:P (unspec:P [(const_int 0)] UNSPEC_GP)))]) 4804 4805;; Insn to initialize $gp for n32/n64 abicalls. Operand 0 is the offset 4806;; of _gp from the start of this function. Operand 1 is the incoming 4807;; function address. 4808(define_insn_and_split "loadgp_newabi_<mode>" 4809 [(set (match_operand:P 0 "register_operand" "=&d") 4810 (unspec:P [(match_operand:P 1) 4811 (match_operand:P 2 "register_operand" "d")] 4812 UNSPEC_LOADGP))] 4813 "mips_current_loadgp_style () == LOADGP_NEWABI" 4814 { return mips_must_initialize_gp_p () ? "#" : ""; } 4815 "&& mips_must_initialize_gp_p ()" 4816 [(set (match_dup 0) (match_dup 3)) 4817 (set (match_dup 0) (match_dup 4)) 4818 (set (match_dup 0) (match_dup 5))] 4819{ 4820 operands[3] = gen_rtx_HIGH (Pmode, operands[1]); 4821 operands[4] = gen_rtx_PLUS (Pmode, operands[0], operands[2]); 4822 operands[5] = gen_rtx_LO_SUM (Pmode, operands[0], operands[1]); 4823} 4824 [(set_attr "type" "ghost")]) 4825 4826;; Likewise, for -mno-shared code. Operand 0 is the __gnu_local_gp symbol. 4827(define_insn_and_split "loadgp_absolute_<mode>" 4828 [(set (match_operand:P 0 "register_operand" "=d") 4829 (unspec:P [(match_operand:P 1)] UNSPEC_LOADGP))] 4830 "mips_current_loadgp_style () == LOADGP_ABSOLUTE" 4831 { return mips_must_initialize_gp_p () ? "#" : ""; } 4832 "&& mips_must_initialize_gp_p ()" 4833 [(const_int 0)] 4834{ 4835 mips_emit_move (operands[0], operands[1]); 4836 DONE; 4837} 4838 [(set_attr "type" "ghost")]) 4839 4840;; This blockage instruction prevents the gp load from being 4841;; scheduled after an implicit use of gp. It also prevents 4842;; the load from being deleted as dead. 4843(define_insn "loadgp_blockage" 4844 [(unspec_volatile [(reg:SI 28)] UNSPEC_BLOCKAGE)] 4845 "" 4846 "" 4847 [(set_attr "type" "ghost")]) 4848 4849;; Initialize $gp for RTP PIC. Operand 0 is the __GOTT_BASE__ symbol 4850;; and operand 1 is the __GOTT_INDEX__ symbol. 4851(define_insn_and_split "loadgp_rtp_<mode>" 4852 [(set (match_operand:P 0 "register_operand" "=d") 4853 (unspec:P [(match_operand:P 1 "symbol_ref_operand") 4854 (match_operand:P 2 "symbol_ref_operand")] 4855 UNSPEC_LOADGP))] 4856 "mips_current_loadgp_style () == LOADGP_RTP" 4857 { return mips_must_initialize_gp_p () ? "#" : ""; } 4858 "&& mips_must_initialize_gp_p ()" 4859 [(set (match_dup 0) (high:P (match_dup 3))) 4860 (set (match_dup 0) (unspec:P [(match_dup 0) 4861 (match_dup 3)] UNSPEC_LOAD_GOT)) 4862 (set (match_dup 0) (unspec:P [(match_dup 0) 4863 (match_dup 4)] UNSPEC_LOAD_GOT))] 4864{ 4865 operands[3] = mips_unspec_address (operands[1], SYMBOL_ABSOLUTE); 4866 operands[4] = mips_unspec_address (operands[2], SYMBOL_HALF); 4867} 4868 [(set_attr "type" "ghost")]) 4869 4870;; Initialize the global pointer for MIPS16 code. Operand 0 is the 4871;; global pointer and operand 1 is the MIPS16 register that holds 4872;; the required value. 4873(define_insn_and_split "copygp_mips16" 4874 [(set (match_operand:SI 0 "register_operand" "=y") 4875 (unspec:SI [(match_operand:SI 1 "register_operand" "d")] 4876 UNSPEC_COPYGP))] 4877 "TARGET_MIPS16" 4878 { return mips_must_initialize_gp_p () ? "#" : ""; } 4879 "&& mips_must_initialize_gp_p ()" 4880 [(set (match_dup 0) (match_dup 1))] 4881 "" 4882 [(set_attr "type" "ghost")]) 4883 4884;; A placeholder for where the cprestore instruction should go, 4885;; if we decide we need one. Operand 0 and operand 1 are as for 4886;; "cprestore". Operand 2 is a register that holds the gp value. 4887;; 4888;; The "cprestore" pattern requires operand 2 to be pic_offset_table_rtx, 4889;; otherwise any register that holds the correct value will do. 4890(define_insn_and_split "potential_cprestore" 4891 [(set (match_operand:SI 0 "cprestore_save_slot_operand" "=X,X") 4892 (unspec:SI [(match_operand:SI 1 "const_int_operand" "I,i") 4893 (match_operand:SI 2 "register_operand" "d,d")] 4894 UNSPEC_POTENTIAL_CPRESTORE)) 4895 (clobber (match_operand:SI 3 "scratch_operand" "=X,&d"))] 4896 "!TARGET_CPRESTORE_DIRECTIVE || operands[2] == pic_offset_table_rtx" 4897 { return mips_must_initialize_gp_p () ? "#" : ""; } 4898 "mips_must_initialize_gp_p ()" 4899 [(const_int 0)] 4900{ 4901 mips_save_gp_to_cprestore_slot (operands[0], operands[1], 4902 operands[2], operands[3]); 4903 DONE; 4904} 4905 [(set_attr "type" "ghost")]) 4906 4907;; Emit a .cprestore directive, which normally expands to a single store 4908;; instruction. Operand 0 is a (possibly illegitimate) sp-based MEM 4909;; for the cprestore slot. Operand 1 is the offset of the slot from 4910;; the stack pointer. (This is redundant with operand 0, but it makes 4911;; things a little simpler.) 4912(define_insn "cprestore" 4913 [(set (match_operand:SI 0 "cprestore_save_slot_operand" "=X,X") 4914 (unspec:SI [(match_operand:SI 1 "const_int_operand" "I,i") 4915 (reg:SI 28)] 4916 UNSPEC_CPRESTORE))] 4917 "TARGET_CPRESTORE_DIRECTIVE" 4918{ 4919 if (mips_nomacro.nesting_level > 0 && which_alternative == 1) 4920 return ".set\tmacro\;.cprestore\t%1\;.set\tnomacro"; 4921 else 4922 return ".cprestore\t%1"; 4923} 4924 [(set_attr "type" "store") 4925 (set_attr "length" "4,12")]) 4926 4927(define_insn "use_cprestore" 4928 [(set (reg:SI CPRESTORE_SLOT_REGNUM) 4929 (match_operand:SI 0 "cprestore_load_slot_operand"))] 4930 "" 4931 "" 4932 [(set_attr "type" "ghost")]) 4933 4934;; Expand in-line code to clear the instruction cache between operand[0] and 4935;; operand[1]. 4936(define_expand "clear_cache" 4937 [(match_operand 0 "pmode_register_operand") 4938 (match_operand 1 "pmode_register_operand")] 4939 "" 4940 " 4941{ 4942 if (TARGET_SYNCI) 4943 { 4944 mips_expand_synci_loop (operands[0], operands[1]); 4945 emit_insn (gen_sync ()); 4946 emit_insn (Pmode == SImode 4947 ? gen_clear_hazard_si () 4948 : gen_clear_hazard_di ()); 4949 } 4950 else if (mips_cache_flush_func && mips_cache_flush_func[0]) 4951 { 4952 rtx len = gen_reg_rtx (Pmode); 4953 emit_insn (gen_sub3_insn (len, operands[1], operands[0])); 4954 MIPS_ICACHE_SYNC (operands[0], len); 4955 } 4956 DONE; 4957}") 4958 4959(define_insn "sync" 4960 [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)] 4961 "GENERATE_SYNC" 4962 { return mips_output_sync (); }) 4963 4964(define_insn "synci" 4965 [(unspec_volatile [(match_operand 0 "pmode_register_operand" "d")] 4966 UNSPEC_SYNCI)] 4967 "TARGET_SYNCI" 4968 "synci\t0(%0)") 4969 4970(define_insn "rdhwr_synci_step_<mode>" 4971 [(set (match_operand:P 0 "register_operand" "=d") 4972 (unspec_volatile [(const_int 1)] 4973 UNSPEC_RDHWR))] 4974 "ISA_HAS_SYNCI" 4975 "rdhwr\t%0,$1") 4976 4977(define_insn "clear_hazard_<mode>" 4978 [(unspec_volatile [(const_int 0)] UNSPEC_CLEAR_HAZARD) 4979 (clobber (reg:P RETURN_ADDR_REGNUM))] 4980 "ISA_HAS_SYNCI" 4981{ 4982 return "%(%<bal\t1f\n" 4983 "\tnop\n" 4984 "1:\t<d>addiu\t$31,$31,12\n" 4985 "\tjr.hb\t$31\n" 4986 "\tnop%>%)"; 4987} 4988 [(set_attr "length" "20")]) 4989 4990;; Cache operations for R4000-style caches. 4991(define_insn "mips_cache" 4992 [(set (mem:BLK (scratch)) 4993 (unspec:BLK [(match_operand:SI 0 "const_int_operand") 4994 (match_operand:QI 1 "address_operand" "p")] 4995 UNSPEC_MIPS_CACHE))] 4996 "ISA_HAS_CACHE" 4997 "cache\t%X0,%a1") 4998 4999;; Similar, but with the operands hard-coded to an R10K cache barrier 5000;; operation. We keep the pattern distinct so that we can identify 5001;; cache operations inserted by -mr10k-cache-barrier=, and so that 5002;; the operation is never inserted into a delay slot. 5003(define_insn "r10k_cache_barrier" 5004 [(set (mem:BLK (scratch)) 5005 (unspec:BLK [(const_int 0)] UNSPEC_R10K_CACHE_BARRIER))] 5006 "ISA_HAS_CACHE" 5007 "cache\t0x14,0(%$)" 5008 [(set_attr "can_delay" "no")]) 5009 5010;; Block moves, see mips.c for more details. 5011;; Argument 0 is the destination 5012;; Argument 1 is the source 5013;; Argument 2 is the length 5014;; Argument 3 is the alignment 5015 5016(define_expand "movmemsi" 5017 [(parallel [(set (match_operand:BLK 0 "general_operand") 5018 (match_operand:BLK 1 "general_operand")) 5019 (use (match_operand:SI 2 "")) 5020 (use (match_operand:SI 3 "const_int_operand"))])] 5021 "!TARGET_MIPS16 && !TARGET_MEMCPY" 5022{ 5023 if (mips_expand_block_move (operands[0], operands[1], operands[2])) 5024 DONE; 5025 else 5026 FAIL; 5027}) 5028 5029;; 5030;; .................... 5031;; 5032;; SHIFTS 5033;; 5034;; .................... 5035 5036(define_expand "<optab><mode>3" 5037 [(set (match_operand:GPR 0 "register_operand") 5038 (any_shift:GPR (match_operand:GPR 1 "register_operand") 5039 (match_operand:SI 2 "arith_operand")))] 5040 "" 5041{ 5042 /* On the mips16, a shift of more than 8 is a four byte instruction, 5043 so, for a shift between 8 and 16, it is just as fast to do two 5044 shifts of 8 or less. If there is a lot of shifting going on, we 5045 may win in CSE. Otherwise combine will put the shifts back 5046 together again. This can be called by mips_function_arg, so we must 5047 be careful not to allocate a new register if we've reached the 5048 reload pass. */ 5049 if (TARGET_MIPS16 5050 && optimize 5051 && CONST_INT_P (operands[2]) 5052 && INTVAL (operands[2]) > 8 5053 && INTVAL (operands[2]) <= 16 5054 && !reload_in_progress 5055 && !reload_completed) 5056 { 5057 rtx temp = gen_reg_rtx (<MODE>mode); 5058 5059 emit_insn (gen_<optab><mode>3 (temp, operands[1], GEN_INT (8))); 5060 emit_insn (gen_<optab><mode>3 (operands[0], temp, 5061 GEN_INT (INTVAL (operands[2]) - 8))); 5062 DONE; 5063 } 5064}) 5065 5066(define_insn "*<optab><mode>3" 5067 [(set (match_operand:GPR 0 "register_operand" "=d") 5068 (any_shift:GPR (match_operand:GPR 1 "register_operand" "d") 5069 (match_operand:SI 2 "arith_operand" "dI")))] 5070 "!TARGET_MIPS16" 5071{ 5072 if (CONST_INT_P (operands[2])) 5073 operands[2] = GEN_INT (INTVAL (operands[2]) 5074 & (GET_MODE_BITSIZE (<MODE>mode) - 1)); 5075 5076 return "<d><insn>\t%0,%1,%2"; 5077} 5078 [(set_attr "type" "shift") 5079 (set_attr "mode" "<MODE>")]) 5080 5081(define_insn "*<optab>si3_extend" 5082 [(set (match_operand:DI 0 "register_operand" "=d") 5083 (sign_extend:DI 5084 (any_shift:SI (match_operand:SI 1 "register_operand" "d") 5085 (match_operand:SI 2 "arith_operand" "dI"))))] 5086 "TARGET_64BIT && !TARGET_MIPS16" 5087{ 5088 if (CONST_INT_P (operands[2])) 5089 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); 5090 5091 return "<insn>\t%0,%1,%2"; 5092} 5093 [(set_attr "type" "shift") 5094 (set_attr "mode" "SI")]) 5095 5096(define_insn "*<optab>si3_mips16" 5097 [(set (match_operand:SI 0 "register_operand" "=d,d") 5098 (any_shift:SI (match_operand:SI 1 "register_operand" "0,d") 5099 (match_operand:SI 2 "arith_operand" "d,I")))] 5100 "TARGET_MIPS16" 5101{ 5102 if (which_alternative == 0) 5103 return "<insn>\t%0,%2"; 5104 5105 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); 5106 return "<insn>\t%0,%1,%2"; 5107} 5108 [(set_attr "type" "shift") 5109 (set_attr "mode" "SI") 5110 (set_attr_alternative "length" 5111 [(const_int 4) 5112 (if_then_else (match_operand 2 "m16_uimm3_b") 5113 (const_int 4) 5114 (const_int 8))])]) 5115 5116;; We need separate DImode MIPS16 patterns because of the irregularity 5117;; of right shifts. 5118(define_insn "*ashldi3_mips16" 5119 [(set (match_operand:DI 0 "register_operand" "=d,d") 5120 (ashift:DI (match_operand:DI 1 "register_operand" "0,d") 5121 (match_operand:SI 2 "arith_operand" "d,I")))] 5122 "TARGET_64BIT && TARGET_MIPS16" 5123{ 5124 if (which_alternative == 0) 5125 return "dsll\t%0,%2"; 5126 5127 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); 5128 return "dsll\t%0,%1,%2"; 5129} 5130 [(set_attr "type" "shift") 5131 (set_attr "mode" "DI") 5132 (set_attr_alternative "length" 5133 [(const_int 4) 5134 (if_then_else (match_operand 2 "m16_uimm3_b") 5135 (const_int 4) 5136 (const_int 8))])]) 5137 5138(define_insn "*ashrdi3_mips16" 5139 [(set (match_operand:DI 0 "register_operand" "=d,d") 5140 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0") 5141 (match_operand:SI 2 "arith_operand" "d,I")))] 5142 "TARGET_64BIT && TARGET_MIPS16" 5143{ 5144 if (CONST_INT_P (operands[2])) 5145 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); 5146 5147 return "dsra\t%0,%2"; 5148} 5149 [(set_attr "type" "shift") 5150 (set_attr "mode" "DI") 5151 (set_attr_alternative "length" 5152 [(const_int 4) 5153 (if_then_else (match_operand 2 "m16_uimm3_b") 5154 (const_int 4) 5155 (const_int 8))])]) 5156 5157(define_insn "*lshrdi3_mips16" 5158 [(set (match_operand:DI 0 "register_operand" "=d,d") 5159 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0") 5160 (match_operand:SI 2 "arith_operand" "d,I")))] 5161 "TARGET_64BIT && TARGET_MIPS16" 5162{ 5163 if (CONST_INT_P (operands[2])) 5164 operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); 5165 5166 return "dsrl\t%0,%2"; 5167} 5168 [(set_attr "type" "shift") 5169 (set_attr "mode" "DI") 5170 (set_attr_alternative "length" 5171 [(const_int 4) 5172 (if_then_else (match_operand 2 "m16_uimm3_b") 5173 (const_int 4) 5174 (const_int 8))])]) 5175 5176;; On the mips16, we can split a 4 byte shift into 2 2 byte shifts. 5177 5178(define_split 5179 [(set (match_operand:GPR 0 "d_operand") 5180 (any_shift:GPR (match_operand:GPR 1 "d_operand") 5181 (match_operand:GPR 2 "const_int_operand")))] 5182 "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE 5183 && INTVAL (operands[2]) > 8 5184 && INTVAL (operands[2]) <= 16" 5185 [(set (match_dup 0) (any_shift:GPR (match_dup 1) (const_int 8))) 5186 (set (match_dup 0) (any_shift:GPR (match_dup 0) (match_dup 2)))] 5187 { operands[2] = GEN_INT (INTVAL (operands[2]) - 8); }) 5188 5189;; If we load a byte on the mips16 as a bitfield, the resulting 5190;; sequence of instructions is too complicated for combine, because it 5191;; involves four instructions: a load, a shift, a constant load into a 5192;; register, and an and (the key problem here is that the mips16 does 5193;; not have and immediate). We recognize a shift of a load in order 5194;; to make it simple enough for combine to understand. 5195;; 5196;; The length here is the worst case: the length of the split version 5197;; will be more accurate. 5198(define_insn_and_split "" 5199 [(set (match_operand:SI 0 "register_operand" "=d") 5200 (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") 5201 (match_operand:SI 2 "immediate_operand" "I")))] 5202 "TARGET_MIPS16" 5203 "#" 5204 "" 5205 [(set (match_dup 0) (match_dup 1)) 5206 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))] 5207 "" 5208 [(set_attr "type" "load") 5209 (set_attr "mode" "SI") 5210 (set_attr "length" "16")]) 5211 5212(define_insn "rotr<mode>3" 5213 [(set (match_operand:GPR 0 "register_operand" "=d") 5214 (rotatert:GPR (match_operand:GPR 1 "register_operand" "d") 5215 (match_operand:SI 2 "arith_operand" "dI")))] 5216 "ISA_HAS_ROR" 5217{ 5218 if (CONST_INT_P (operands[2])) 5219 gcc_assert (INTVAL (operands[2]) >= 0 5220 && INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)); 5221 5222 return "<d>ror\t%0,%1,%2"; 5223} 5224 [(set_attr "type" "shift") 5225 (set_attr "mode" "<MODE>")]) 5226 5227;; 5228;; .................... 5229;; 5230;; CONDITIONAL BRANCHES 5231;; 5232;; .................... 5233 5234;; Conditional branches on floating-point equality tests. 5235 5236(define_insn "*branch_fp" 5237 [(set (pc) 5238 (if_then_else 5239 (match_operator 1 "equality_operator" 5240 [(match_operand:CC 2 "register_operand" "z") 5241 (const_int 0)]) 5242 (label_ref (match_operand 0 "" "")) 5243 (pc)))] 5244 "TARGET_HARD_FLOAT" 5245{ 5246 return mips_output_conditional_branch (insn, operands, 5247 MIPS_BRANCH ("b%F1", "%Z2%0"), 5248 MIPS_BRANCH ("b%W1", "%Z2%0")); 5249} 5250 [(set_attr "type" "branch")]) 5251 5252(define_insn "*branch_fp_inverted" 5253 [(set (pc) 5254 (if_then_else 5255 (match_operator 1 "equality_operator" 5256 [(match_operand:CC 2 "register_operand" "z") 5257 (const_int 0)]) 5258 (pc) 5259 (label_ref (match_operand 0 "" ""))))] 5260 "TARGET_HARD_FLOAT" 5261{ 5262 return mips_output_conditional_branch (insn, operands, 5263 MIPS_BRANCH ("b%W1", "%Z2%0"), 5264 MIPS_BRANCH ("b%F1", "%Z2%0")); 5265} 5266 [(set_attr "type" "branch")]) 5267 5268;; Conditional branches on ordered comparisons with zero. 5269 5270(define_insn "*branch_order<mode>" 5271 [(set (pc) 5272 (if_then_else 5273 (match_operator 1 "order_operator" 5274 [(match_operand:GPR 2 "register_operand" "d") 5275 (const_int 0)]) 5276 (label_ref (match_operand 0 "" "")) 5277 (pc)))] 5278 "!TARGET_MIPS16" 5279 { return mips_output_order_conditional_branch (insn, operands, false); } 5280 [(set_attr "type" "branch")]) 5281 5282(define_insn "*branch_order<mode>_inverted" 5283 [(set (pc) 5284 (if_then_else 5285 (match_operator 1 "order_operator" 5286 [(match_operand:GPR 2 "register_operand" "d") 5287 (const_int 0)]) 5288 (pc) 5289 (label_ref (match_operand 0 "" ""))))] 5290 "!TARGET_MIPS16" 5291 { return mips_output_order_conditional_branch (insn, operands, true); } 5292 [(set_attr "type" "branch")]) 5293 5294;; Conditional branch on equality comparison. 5295 5296(define_insn "*branch_equality<mode>" 5297 [(set (pc) 5298 (if_then_else 5299 (match_operator 1 "equality_operator" 5300 [(match_operand:GPR 2 "register_operand" "d") 5301 (match_operand:GPR 3 "reg_or_0_operand" "dJ")]) 5302 (label_ref (match_operand 0 "" "")) 5303 (pc)))] 5304 "!TARGET_MIPS16" 5305{ 5306 return mips_output_conditional_branch (insn, operands, 5307 MIPS_BRANCH ("b%C1", "%2,%z3,%0"), 5308 MIPS_BRANCH ("b%N1", "%2,%z3,%0")); 5309} 5310 [(set_attr "type" "branch")]) 5311 5312(define_insn "*branch_equality<mode>_inverted" 5313 [(set (pc) 5314 (if_then_else 5315 (match_operator 1 "equality_operator" 5316 [(match_operand:GPR 2 "register_operand" "d") 5317 (match_operand:GPR 3 "reg_or_0_operand" "dJ")]) 5318 (pc) 5319 (label_ref (match_operand 0 "" ""))))] 5320 "!TARGET_MIPS16" 5321{ 5322 return mips_output_conditional_branch (insn, operands, 5323 MIPS_BRANCH ("b%N1", "%2,%z3,%0"), 5324 MIPS_BRANCH ("b%C1", "%2,%z3,%0")); 5325} 5326 [(set_attr "type" "branch")]) 5327 5328;; MIPS16 branches 5329 5330(define_insn "*branch_equality<mode>_mips16" 5331 [(set (pc) 5332 (if_then_else 5333 (match_operator 0 "equality_operator" 5334 [(match_operand:GPR 1 "register_operand" "d,t") 5335 (const_int 0)]) 5336 (match_operand 2 "pc_or_label_operand" "") 5337 (match_operand 3 "pc_or_label_operand" "")))] 5338 "TARGET_MIPS16" 5339{ 5340 if (operands[2] != pc_rtx) 5341 { 5342 if (which_alternative == 0) 5343 return "b%C0z\t%1,%2"; 5344 else 5345 return "bt%C0z\t%2"; 5346 } 5347 else 5348 { 5349 if (which_alternative == 0) 5350 return "b%N0z\t%1,%3"; 5351 else 5352 return "bt%N0z\t%3"; 5353 } 5354} 5355 [(set_attr "type" "branch")]) 5356 5357(define_expand "cbranch<mode>4" 5358 [(set (pc) 5359 (if_then_else (match_operator 0 "comparison_operator" 5360 [(match_operand:GPR 1 "register_operand") 5361 (match_operand:GPR 2 "nonmemory_operand")]) 5362 (label_ref (match_operand 3 "")) 5363 (pc)))] 5364 "" 5365{ 5366 mips_expand_conditional_branch (operands); 5367 DONE; 5368}) 5369 5370(define_expand "cbranch<mode>4" 5371 [(set (pc) 5372 (if_then_else (match_operator 0 "comparison_operator" 5373 [(match_operand:SCALARF 1 "register_operand") 5374 (match_operand:SCALARF 2 "register_operand")]) 5375 (label_ref (match_operand 3 "")) 5376 (pc)))] 5377 "" 5378{ 5379 mips_expand_conditional_branch (operands); 5380 DONE; 5381}) 5382 5383;; Used to implement built-in functions. 5384(define_expand "condjump" 5385 [(set (pc) 5386 (if_then_else (match_operand 0) 5387 (label_ref (match_operand 1)) 5388 (pc)))]) 5389 5390;; Branch if bit is set/clear. 5391 5392(define_insn "*branch_bit<bbv><mode>" 5393 [(set (pc) 5394 (if_then_else 5395 (equality_op (zero_extract:GPR 5396 (match_operand:GPR 1 "register_operand" "d") 5397 (const_int 1) 5398 (match_operand 2 "const_int_operand" "")) 5399 (const_int 0)) 5400 (label_ref (match_operand 0 "")) 5401 (pc)))] 5402 "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)" 5403{ 5404 return 5405 mips_output_conditional_branch (insn, operands, 5406 MIPS_BRANCH ("bbit<bbv>", "%1,%2,%0"), 5407 MIPS_BRANCH ("bbit<bbinv>", "%1,%2,%0")); 5408} 5409 [(set_attr "type" "branch") 5410 (set_attr "branch_likely" "no")]) 5411 5412(define_insn "*branch_bit<bbv><mode>_inverted" 5413 [(set (pc) 5414 (if_then_else 5415 (equality_op (zero_extract:GPR 5416 (match_operand:GPR 1 "register_operand" "d") 5417 (const_int 1) 5418 (match_operand 2 "const_int_operand" "")) 5419 (const_int 0)) 5420 (pc) 5421 (label_ref (match_operand 0 ""))))] 5422 "ISA_HAS_BBIT && UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)" 5423{ 5424 return 5425 mips_output_conditional_branch (insn, operands, 5426 MIPS_BRANCH ("bbit<bbinv>", "%1,%2,%0"), 5427 MIPS_BRANCH ("bbit<bbv>", "%1,%2,%0")); 5428} 5429 [(set_attr "type" "branch") 5430 (set_attr "branch_likely" "no")]) 5431 5432;; 5433;; .................... 5434;; 5435;; SETTING A REGISTER FROM A COMPARISON 5436;; 5437;; .................... 5438 5439;; Destination is always set in SI mode. 5440 5441(define_expand "cstore<mode>4" 5442 [(set (match_operand:SI 0 "register_operand") 5443 (match_operator:SI 1 "mips_cstore_operator" 5444 [(match_operand:GPR 2 "register_operand") 5445 (match_operand:GPR 3 "nonmemory_operand")]))] 5446 "" 5447{ 5448 mips_expand_scc (operands); 5449 DONE; 5450}) 5451 5452(define_insn "*seq_zero_<GPR:mode><GPR2:mode>" 5453 [(set (match_operand:GPR2 0 "register_operand" "=d") 5454 (eq:GPR2 (match_operand:GPR 1 "register_operand" "d") 5455 (const_int 0)))] 5456 "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE" 5457 "sltu\t%0,%1,1" 5458 [(set_attr "type" "slt") 5459 (set_attr "mode" "<GPR:MODE>")]) 5460 5461(define_insn "*seq_zero_<GPR:mode><GPR2:mode>_mips16" 5462 [(set (match_operand:GPR2 0 "register_operand" "=t") 5463 (eq:GPR2 (match_operand:GPR 1 "register_operand" "d") 5464 (const_int 0)))] 5465 "TARGET_MIPS16 && !ISA_HAS_SEQ_SNE" 5466 "sltu\t%1,1" 5467 [(set_attr "type" "slt") 5468 (set_attr "mode" "<GPR:MODE>")]) 5469 5470;; Generate sltiu unless using seq results in better code. 5471(define_insn "*seq_<GPR:mode><GPR2:mode>_seq" 5472 [(set (match_operand:GPR2 0 "register_operand" "=d,d,d") 5473 (eq:GPR2 (match_operand:GPR 1 "register_operand" "%d,d,d") 5474 (match_operand:GPR 2 "reg_imm10_operand" "d,J,YB")))] 5475 "ISA_HAS_SEQ_SNE" 5476 "@ 5477 seq\t%0,%1,%2 5478 sltiu\t%0,%1,1 5479 seqi\t%0,%1,%2" 5480 [(set_attr "type" "slt") 5481 (set_attr "mode" "<GPR:MODE>")]) 5482 5483(define_insn "*sne_zero_<GPR:mode><GPR2:mode>" 5484 [(set (match_operand:GPR2 0 "register_operand" "=d") 5485 (ne:GPR2 (match_operand:GPR 1 "register_operand" "d") 5486 (const_int 0)))] 5487 "!TARGET_MIPS16 && !ISA_HAS_SEQ_SNE" 5488 "sltu\t%0,%.,%1" 5489 [(set_attr "type" "slt") 5490 (set_attr "mode" "<GPR:MODE>")]) 5491 5492;; Generate sltu unless using sne results in better code. 5493(define_insn "*sne_<GPR:mode><GPR2:mode>_sne" 5494 [(set (match_operand:GPR2 0 "register_operand" "=d,d,d") 5495 (ne:GPR2 (match_operand:GPR 1 "register_operand" "%d,d,d") 5496 (match_operand:GPR 2 "reg_imm10_operand" "d,J,YB")))] 5497 "ISA_HAS_SEQ_SNE" 5498 "@ 5499 sne\t%0,%1,%2 5500 sltu\t%0,%.,%1 5501 snei\t%0,%1,%2" 5502 [(set_attr "type" "slt") 5503 (set_attr "mode" "<GPR:MODE>")]) 5504 5505(define_insn "*sgt<u>_<GPR:mode><GPR2:mode>" 5506 [(set (match_operand:GPR2 0 "register_operand" "=d") 5507 (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d") 5508 (match_operand:GPR 2 "reg_or_0_operand" "dJ")))] 5509 "!TARGET_MIPS16" 5510 "slt<u>\t%0,%z2,%1" 5511 [(set_attr "type" "slt") 5512 (set_attr "mode" "<GPR:MODE>")]) 5513 5514(define_insn "*sgt<u>_<GPR:mode><GPR2:mode>_mips16" 5515 [(set (match_operand:GPR2 0 "register_operand" "=t") 5516 (any_gt:GPR2 (match_operand:GPR 1 "register_operand" "d") 5517 (match_operand:GPR 2 "register_operand" "d")))] 5518 "TARGET_MIPS16" 5519 "slt<u>\t%2,%1" 5520 [(set_attr "type" "slt") 5521 (set_attr "mode" "<GPR:MODE>")]) 5522 5523(define_insn "*sge<u>_<GPR:mode><GPR2:mode>" 5524 [(set (match_operand:GPR2 0 "register_operand" "=d") 5525 (any_ge:GPR2 (match_operand:GPR 1 "register_operand" "d") 5526 (const_int 1)))] 5527 "!TARGET_MIPS16" 5528 "slt<u>\t%0,%.,%1" 5529 [(set_attr "type" "slt") 5530 (set_attr "mode" "<GPR:MODE>")]) 5531 5532(define_insn "*slt<u>_<GPR:mode><GPR2:mode>" 5533 [(set (match_operand:GPR2 0 "register_operand" "=d") 5534 (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d") 5535 (match_operand:GPR 2 "arith_operand" "dI")))] 5536 "!TARGET_MIPS16" 5537 "slt<u>\t%0,%1,%2" 5538 [(set_attr "type" "slt") 5539 (set_attr "mode" "<GPR:MODE>")]) 5540 5541(define_insn "*slt<u>_<GPR:mode><GPR2:mode>_mips16" 5542 [(set (match_operand:GPR2 0 "register_operand" "=t,t") 5543 (any_lt:GPR2 (match_operand:GPR 1 "register_operand" "d,d") 5544 (match_operand:GPR 2 "arith_operand" "d,I")))] 5545 "TARGET_MIPS16" 5546 "slt<u>\t%1,%2" 5547 [(set_attr "type" "slt") 5548 (set_attr "mode" "<GPR:MODE>") 5549 (set_attr_alternative "length" 5550 [(const_int 4) 5551 (if_then_else (match_operand 2 "m16_uimm8_1") 5552 (const_int 4) 5553 (const_int 8))])]) 5554 5555(define_insn "*sle<u>_<GPR:mode><GPR2:mode>" 5556 [(set (match_operand:GPR2 0 "register_operand" "=d") 5557 (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d") 5558 (match_operand:GPR 2 "sle_operand" "")))] 5559 "!TARGET_MIPS16" 5560{ 5561 operands[2] = GEN_INT (INTVAL (operands[2]) + 1); 5562 return "slt<u>\t%0,%1,%2"; 5563} 5564 [(set_attr "type" "slt") 5565 (set_attr "mode" "<GPR:MODE>")]) 5566 5567(define_insn "*sle<u>_<GPR:mode><GPR2:mode>_mips16" 5568 [(set (match_operand:GPR2 0 "register_operand" "=t") 5569 (any_le:GPR2 (match_operand:GPR 1 "register_operand" "d") 5570 (match_operand:GPR 2 "sle_operand" "")))] 5571 "TARGET_MIPS16" 5572{ 5573 operands[2] = GEN_INT (INTVAL (operands[2]) + 1); 5574 return "slt<u>\t%1,%2"; 5575} 5576 [(set_attr "type" "slt") 5577 (set_attr "mode" "<GPR:MODE>") 5578 (set (attr "length") (if_then_else (match_operand 2 "m16_uimm8_m1_1") 5579 (const_int 4) 5580 (const_int 8)))]) 5581 5582;; 5583;; .................... 5584;; 5585;; FLOATING POINT COMPARISONS 5586;; 5587;; .................... 5588 5589(define_insn "s<code>_<mode>" 5590 [(set (match_operand:CC 0 "register_operand" "=z") 5591 (fcond:CC (match_operand:SCALARF 1 "register_operand" "f") 5592 (match_operand:SCALARF 2 "register_operand" "f")))] 5593 "" 5594 "c.<fcond>.<fmt>\t%Z0%1,%2" 5595 [(set_attr "type" "fcmp") 5596 (set_attr "mode" "FPSW")]) 5597 5598(define_insn "s<code>_<mode>" 5599 [(set (match_operand:CC 0 "register_operand" "=z") 5600 (swapped_fcond:CC (match_operand:SCALARF 1 "register_operand" "f") 5601 (match_operand:SCALARF 2 "register_operand" "f")))] 5602 "" 5603 "c.<swapped_fcond>.<fmt>\t%Z0%2,%1" 5604 [(set_attr "type" "fcmp") 5605 (set_attr "mode" "FPSW")]) 5606 5607;; 5608;; .................... 5609;; 5610;; UNCONDITIONAL BRANCHES 5611;; 5612;; .................... 5613 5614;; Unconditional branches. 5615 5616(define_expand "jump" 5617 [(set (pc) 5618 (label_ref (match_operand 0)))]) 5619 5620(define_insn "*jump_absolute" 5621 [(set (pc) 5622 (label_ref (match_operand 0)))] 5623 "!TARGET_MIPS16 && TARGET_ABSOLUTE_JUMPS" 5624 { return MIPS_ABSOLUTE_JUMP ("%*j\t%l0%/"); } 5625 [(set_attr "type" "jump")]) 5626 5627(define_insn "*jump_pic" 5628 [(set (pc) 5629 (label_ref (match_operand 0)))] 5630 "!TARGET_MIPS16 && !TARGET_ABSOLUTE_JUMPS" 5631{ 5632 if (get_attr_length (insn) <= 8) 5633 return "%*b\t%l0%/"; 5634 else 5635 { 5636 mips_output_load_label (operands[0]); 5637 return "%*jr\t%@%/%]"; 5638 } 5639} 5640 [(set_attr "type" "branch")]) 5641 5642;; We need a different insn for the mips16, because a mips16 branch 5643;; does not have a delay slot. 5644 5645(define_insn "*jump_mips16" 5646 [(set (pc) 5647 (label_ref (match_operand 0 "" "")))] 5648 "TARGET_MIPS16" 5649 "b\t%l0" 5650 [(set_attr "type" "branch")]) 5651 5652(define_expand "indirect_jump" 5653 [(set (pc) (match_operand 0 "register_operand"))] 5654 "" 5655{ 5656 operands[0] = force_reg (Pmode, operands[0]); 5657 if (Pmode == SImode) 5658 emit_jump_insn (gen_indirect_jumpsi (operands[0])); 5659 else 5660 emit_jump_insn (gen_indirect_jumpdi (operands[0])); 5661 DONE; 5662}) 5663 5664(define_insn "indirect_jump<mode>" 5665 [(set (pc) (match_operand:P 0 "register_operand" "d"))] 5666 "" 5667 "%*j\t%0%/" 5668 [(set_attr "type" "jump") 5669 (set_attr "mode" "none")]) 5670 5671(define_expand "tablejump" 5672 [(set (pc) 5673 (match_operand 0 "register_operand")) 5674 (use (label_ref (match_operand 1 "")))] 5675 "" 5676{ 5677 if (TARGET_MIPS16_SHORT_JUMP_TABLES) 5678 operands[0] = expand_binop (Pmode, add_optab, 5679 convert_to_mode (Pmode, operands[0], false), 5680 gen_rtx_LABEL_REF (Pmode, operands[1]), 5681 0, 0, OPTAB_WIDEN); 5682 else if (TARGET_GPWORD) 5683 operands[0] = expand_binop (Pmode, add_optab, operands[0], 5684 pic_offset_table_rtx, 0, 0, OPTAB_WIDEN); 5685 else if (TARGET_RTP_PIC) 5686 { 5687 /* When generating RTP PIC, we use case table entries that are relative 5688 to the start of the function. Add the function's address to the 5689 value we loaded. */ 5690 rtx start = get_hard_reg_initial_val (Pmode, PIC_FUNCTION_ADDR_REGNUM); 5691 operands[0] = expand_binop (ptr_mode, add_optab, operands[0], 5692 start, 0, 0, OPTAB_WIDEN); 5693 } 5694 5695 if (Pmode == SImode) 5696 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1])); 5697 else 5698 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1])); 5699 DONE; 5700}) 5701 5702(define_insn "tablejump<mode>" 5703 [(set (pc) 5704 (match_operand:P 0 "register_operand" "d")) 5705 (use (label_ref (match_operand 1 "" "")))] 5706 "" 5707 "%*j\t%0%/" 5708 [(set_attr "type" "jump") 5709 (set_attr "mode" "none")]) 5710 5711;; For TARGET_USE_GOT, we save the gp in the jmp_buf as well. 5712;; While it is possible to either pull it off the stack (in the 5713;; o32 case) or recalculate it given t9 and our target label, 5714;; it takes 3 or 4 insns to do so. 5715 5716(define_expand "builtin_setjmp_setup" 5717 [(use (match_operand 0 "register_operand"))] 5718 "TARGET_USE_GOT" 5719{ 5720 rtx addr; 5721 5722 addr = plus_constant (operands[0], GET_MODE_SIZE (Pmode) * 3); 5723 mips_emit_move (gen_rtx_MEM (Pmode, addr), pic_offset_table_rtx); 5724 DONE; 5725}) 5726 5727;; Restore the gp that we saved above. Despite the earlier comment, it seems 5728;; that older code did recalculate the gp from $25. Continue to jump through 5729;; $25 for compatibility (we lose nothing by doing so). 5730 5731(define_expand "builtin_longjmp" 5732 [(use (match_operand 0 "register_operand"))] 5733 "TARGET_USE_GOT" 5734{ 5735 /* The elements of the buffer are, in order: */ 5736 int W = GET_MODE_SIZE (Pmode); 5737 rtx fp = gen_rtx_MEM (Pmode, operands[0]); 5738 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 1*W)); 5739 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2*W)); 5740 rtx gpv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 3*W)); 5741 rtx pv = gen_rtx_REG (Pmode, PIC_FUNCTION_ADDR_REGNUM); 5742 /* Use gen_raw_REG to avoid being given pic_offset_table_rtx. 5743 The target is bound to be using $28 as the global pointer 5744 but the current function might not be. */ 5745 rtx gp = gen_raw_REG (Pmode, GLOBAL_POINTER_REGNUM); 5746 5747 /* This bit is similar to expand_builtin_longjmp except that it 5748 restores $gp as well. */ 5749 mips_emit_move (hard_frame_pointer_rtx, fp); 5750 mips_emit_move (pv, lab); 5751 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX); 5752 mips_emit_move (gp, gpv); 5753 emit_use (hard_frame_pointer_rtx); 5754 emit_use (stack_pointer_rtx); 5755 emit_use (gp); 5756 emit_indirect_jump (pv); 5757 DONE; 5758}) 5759 5760;; 5761;; .................... 5762;; 5763;; Function prologue/epilogue 5764;; 5765;; .................... 5766;; 5767 5768(define_expand "prologue" 5769 [(const_int 1)] 5770 "" 5771{ 5772 mips_expand_prologue (); 5773 DONE; 5774}) 5775 5776;; Block any insns from being moved before this point, since the 5777;; profiling call to mcount can use various registers that aren't 5778;; saved or used to pass arguments. 5779 5780(define_insn "blockage" 5781 [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)] 5782 "" 5783 "" 5784 [(set_attr "type" "ghost") 5785 (set_attr "mode" "none")]) 5786 5787(define_expand "epilogue" 5788 [(const_int 2)] 5789 "" 5790{ 5791 mips_expand_epilogue (false); 5792 DONE; 5793}) 5794 5795(define_expand "sibcall_epilogue" 5796 [(const_int 2)] 5797 "" 5798{ 5799 mips_expand_epilogue (true); 5800 DONE; 5801}) 5802 5803;; Trivial return. Make it look like a normal return insn as that 5804;; allows jump optimizations to work better. 5805 5806(define_expand "return" 5807 [(return)] 5808 "mips_can_use_return_insn ()" 5809 { mips_expand_before_return (); }) 5810 5811(define_insn "*return" 5812 [(return)] 5813 "mips_can_use_return_insn ()" 5814 "%*j\t$31%/" 5815 [(set_attr "type" "jump") 5816 (set_attr "mode" "none")]) 5817 5818;; Normal return. 5819 5820(define_insn "return_internal" 5821 [(return) 5822 (use (match_operand 0 "pmode_register_operand" ""))] 5823 "" 5824 "%*j\t%0%/" 5825 [(set_attr "type" "jump") 5826 (set_attr "mode" "none")]) 5827 5828;; Exception return. 5829(define_insn "mips_eret" 5830 [(return) 5831 (unspec_volatile [(const_int 0)] UNSPEC_ERET)] 5832 "" 5833 "eret" 5834 [(set_attr "type" "trap") 5835 (set_attr "mode" "none")]) 5836 5837;; Debug exception return. 5838(define_insn "mips_deret" 5839 [(return) 5840 (unspec_volatile [(const_int 0)] UNSPEC_DERET)] 5841 "" 5842 "deret" 5843 [(set_attr "type" "trap") 5844 (set_attr "mode" "none")]) 5845 5846;; Disable interrupts. 5847(define_insn "mips_di" 5848 [(unspec_volatile [(const_int 0)] UNSPEC_DI)] 5849 "" 5850 "di" 5851 [(set_attr "type" "trap") 5852 (set_attr "mode" "none")]) 5853 5854;; Execution hazard barrier. 5855(define_insn "mips_ehb" 5856 [(unspec_volatile [(const_int 0)] UNSPEC_EHB)] 5857 "" 5858 "ehb" 5859 [(set_attr "type" "trap") 5860 (set_attr "mode" "none")]) 5861 5862;; Read GPR from previous shadow register set. 5863(define_insn "mips_rdpgpr" 5864 [(set (match_operand:SI 0 "register_operand" "=d") 5865 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d")] 5866 UNSPEC_RDPGPR))] 5867 "" 5868 "rdpgpr\t%0,%1" 5869 [(set_attr "type" "move") 5870 (set_attr "mode" "SI")]) 5871 5872;; Move involving COP0 registers. 5873(define_insn "cop0_move" 5874 [(set (match_operand:SI 0 "register_operand" "=B,d") 5875 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "d,B")] 5876 UNSPEC_COP0))] 5877 "" 5878{ return mips_output_move (operands[0], operands[1]); } 5879 [(set_attr "type" "mtc,mfc") 5880 (set_attr "mode" "SI")]) 5881 5882;; This is used in compiling the unwind routines. 5883(define_expand "eh_return" 5884 [(use (match_operand 0 "general_operand"))] 5885 "" 5886{ 5887 if (GET_MODE (operands[0]) != word_mode) 5888 operands[0] = convert_to_mode (word_mode, operands[0], 0); 5889 if (TARGET_64BIT) 5890 emit_insn (gen_eh_set_lr_di (operands[0])); 5891 else 5892 emit_insn (gen_eh_set_lr_si (operands[0])); 5893 DONE; 5894}) 5895 5896;; Clobber the return address on the stack. We can't expand this 5897;; until we know where it will be put in the stack frame. 5898 5899(define_insn "eh_set_lr_si" 5900 [(unspec [(match_operand:SI 0 "register_operand" "d")] UNSPEC_EH_RETURN) 5901 (clobber (match_scratch:SI 1 "=&d"))] 5902 "! TARGET_64BIT" 5903 "#") 5904 5905(define_insn "eh_set_lr_di" 5906 [(unspec [(match_operand:DI 0 "register_operand" "d")] UNSPEC_EH_RETURN) 5907 (clobber (match_scratch:DI 1 "=&d"))] 5908 "TARGET_64BIT" 5909 "#") 5910 5911(define_split 5912 [(unspec [(match_operand 0 "register_operand")] UNSPEC_EH_RETURN) 5913 (clobber (match_scratch 1))] 5914 "reload_completed" 5915 [(const_int 0)] 5916{ 5917 mips_set_return_address (operands[0], operands[1]); 5918 DONE; 5919}) 5920 5921(define_expand "exception_receiver" 5922 [(const_int 0)] 5923 "TARGET_USE_GOT" 5924{ 5925 /* See the comment above load_call<mode> for details. */ 5926 emit_insn (gen_set_got_version ()); 5927 5928 /* If we have a call-clobbered $gp, restore it from its save slot. */ 5929 if (HAVE_restore_gp) 5930 emit_insn (gen_restore_gp ()); 5931 DONE; 5932}) 5933 5934(define_expand "nonlocal_goto_receiver" 5935 [(const_int 0)] 5936 "TARGET_USE_GOT" 5937{ 5938 /* See the comment above load_call<mode> for details. */ 5939 emit_insn (gen_set_got_version ()); 5940 DONE; 5941}) 5942 5943;; Restore $gp from its .cprestore stack slot. The instruction remains 5944;; volatile until all uses of $28 are exposed. 5945(define_insn_and_split "restore_gp" 5946 [(set (reg:SI 28) 5947 (unspec_volatile:SI [(const_int 0)] UNSPEC_RESTORE_GP)) 5948 (clobber (match_scratch:SI 0 "=&d"))] 5949 "TARGET_CALL_CLOBBERED_GP" 5950 "#" 5951 "&& epilogue_completed" 5952 [(const_int 0)] 5953{ 5954 mips_restore_gp_from_cprestore_slot (operands[0]); 5955 DONE; 5956} 5957 [(set_attr "type" "ghost")]) 5958 5959;; Move between $gp and its register save slot. 5960(define_insn_and_split "move_gp<mode>" 5961 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,m") 5962 (unspec:GPR [(match_operand:GPR 1 "move_operand" "m,d")] 5963 UNSPEC_MOVE_GP))] 5964 "" 5965 { return mips_must_initialize_gp_p () ? "#" : ""; } 5966 "mips_must_initialize_gp_p ()" 5967 [(const_int 0)] 5968{ 5969 mips_emit_move (operands[0], operands[1]); 5970 DONE; 5971} 5972 [(set_attr "type" "ghost")]) 5973 5974;; 5975;; .................... 5976;; 5977;; FUNCTION CALLS 5978;; 5979;; .................... 5980 5981;; Instructions to load a call address from the GOT. The address might 5982;; point to a function or to a lazy binding stub. In the latter case, 5983;; the stub will use the dynamic linker to resolve the function, which 5984;; in turn will change the GOT entry to point to the function's real 5985;; address. 5986;; 5987;; This means that every call, even pure and constant ones, can 5988;; potentially modify the GOT entry. And once a stub has been called, 5989;; we must not call it again. 5990;; 5991;; We represent this restriction using an imaginary, fixed, call-saved 5992;; register called GOT_VERSION_REGNUM. The idea is to make the register 5993;; live throughout the function and to change its value after every 5994;; potential call site. This stops any rtx value that uses the register 5995;; from being computed before an earlier call. To do this, we: 5996;; 5997;; - Ensure that the register is live on entry to the function, 5998;; so that it is never thought to be used uninitalized. 5999;; 6000;; - Ensure that the register is live on exit from the function, 6001;; so that it is live throughout. 6002;; 6003;; - Make each call (lazily-bound or not) use the current value 6004;; of GOT_VERSION_REGNUM, so that updates of the register are 6005;; not moved across call boundaries. 6006;; 6007;; - Add "ghost" definitions of the register to the beginning of 6008;; blocks reached by EH and ABNORMAL_CALL edges, because those 6009;; edges may involve calls that normal paths don't. (E.g. the 6010;; unwinding code that handles a non-call exception may change 6011;; lazily-bound GOT entries.) We do this by making the 6012;; exception_receiver and nonlocal_goto_receiver expanders emit 6013;; a set_got_version instruction. 6014;; 6015;; - After each call (lazily-bound or not), use a "ghost" 6016;; update_got_version instruction to change the register's value. 6017;; This instruction mimics the _possible_ effect of the dynamic 6018;; resolver during the call and it remains live even if the call 6019;; itself becomes dead. 6020;; 6021;; - Leave GOT_VERSION_REGNUM out of all register classes. 6022;; The register is therefore not a valid register_operand 6023;; and cannot be moved to or from other registers. 6024 6025(define_insn "load_call<mode>" 6026 [(set (match_operand:P 0 "register_operand" "=d") 6027 (unspec:P [(match_operand:P 1 "register_operand" "d") 6028 (match_operand:P 2 "immediate_operand" "") 6029 (reg:SI GOT_VERSION_REGNUM)] UNSPEC_LOAD_CALL))] 6030 "TARGET_USE_GOT" 6031 "<load>\t%0,%R2(%1)" 6032 [(set_attr "got" "load") 6033 (set_attr "mode" "<MODE>")]) 6034 6035(define_insn "set_got_version" 6036 [(set (reg:SI GOT_VERSION_REGNUM) 6037 (unspec_volatile:SI [(const_int 0)] UNSPEC_SET_GOT_VERSION))] 6038 "TARGET_USE_GOT" 6039 "" 6040 [(set_attr "type" "ghost")]) 6041 6042(define_insn "update_got_version" 6043 [(set (reg:SI GOT_VERSION_REGNUM) 6044 (unspec:SI [(reg:SI GOT_VERSION_REGNUM)] UNSPEC_UPDATE_GOT_VERSION))] 6045 "TARGET_USE_GOT" 6046 "" 6047 [(set_attr "type" "ghost")]) 6048 6049;; Sibling calls. All these patterns use jump instructions. 6050 6051;; If TARGET_SIBCALLS, call_insn_operand will only accept constant 6052;; addresses if a direct jump is acceptable. Since the 'S' constraint 6053;; is defined in terms of call_insn_operand, the same is true of the 6054;; constraints. 6055 6056;; When we use an indirect jump, we need a register that will be 6057;; preserved by the epilogue. Since TARGET_USE_PIC_FN_ADDR_REG forces 6058;; us to use $25 for this purpose -- and $25 is never clobbered by the 6059;; epilogue -- we might as well use it for !TARGET_USE_PIC_FN_ADDR_REG 6060;; as well. 6061 6062(define_expand "sibcall" 6063 [(parallel [(call (match_operand 0 "") 6064 (match_operand 1 "")) 6065 (use (match_operand 2 "")) ;; next_arg_reg 6066 (use (match_operand 3 ""))])] ;; struct_value_size_rtx 6067 "TARGET_SIBCALLS" 6068{ 6069 mips_expand_call (MIPS_CALL_SIBCALL, NULL_RTX, XEXP (operands[0], 0), 6070 operands[1], operands[2], false); 6071 DONE; 6072}) 6073 6074(define_insn "sibcall_internal" 6075 [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S")) 6076 (match_operand 1 "" ""))] 6077 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" 6078 { return MIPS_CALL ("j", operands, 0, 1); } 6079 [(set_attr "type" "call")]) 6080 6081(define_expand "sibcall_value" 6082 [(parallel [(set (match_operand 0 "") 6083 (call (match_operand 1 "") 6084 (match_operand 2 ""))) 6085 (use (match_operand 3 ""))])] ;; next_arg_reg 6086 "TARGET_SIBCALLS" 6087{ 6088 mips_expand_call (MIPS_CALL_SIBCALL, operands[0], XEXP (operands[1], 0), 6089 operands[2], operands[3], false); 6090 DONE; 6091}) 6092 6093(define_insn "sibcall_value_internal" 6094 [(set (match_operand 0 "register_operand" "") 6095 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S")) 6096 (match_operand 2 "" "")))] 6097 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" 6098 { return MIPS_CALL ("j", operands, 1, 2); } 6099 [(set_attr "type" "call")]) 6100 6101(define_insn "sibcall_value_multiple_internal" 6102 [(set (match_operand 0 "register_operand" "") 6103 (call (mem:SI (match_operand 1 "call_insn_operand" "j,S")) 6104 (match_operand 2 "" ""))) 6105 (set (match_operand 3 "register_operand" "") 6106 (call (mem:SI (match_dup 1)) 6107 (match_dup 2)))] 6108 "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" 6109 { return MIPS_CALL ("j", operands, 1, 2); } 6110 [(set_attr "type" "call")]) 6111 6112(define_expand "call" 6113 [(parallel [(call (match_operand 0 "") 6114 (match_operand 1 "")) 6115 (use (match_operand 2 "")) ;; next_arg_reg 6116 (use (match_operand 3 ""))])] ;; struct_value_size_rtx 6117 "" 6118{ 6119 mips_expand_call (MIPS_CALL_NORMAL, NULL_RTX, XEXP (operands[0], 0), 6120 operands[1], operands[2], false); 6121 DONE; 6122}) 6123 6124;; This instruction directly corresponds to an assembly-language "jal". 6125;; There are four cases: 6126;; 6127;; - -mno-abicalls: 6128;; Both symbolic and register destinations are OK. The pattern 6129;; always expands to a single mips instruction. 6130;; 6131;; - -mabicalls/-mno-explicit-relocs: 6132;; Again, both symbolic and register destinations are OK. 6133;; The call is treated as a multi-instruction black box. 6134;; 6135;; - -mabicalls/-mexplicit-relocs with n32 or n64: 6136;; Only "jal $25" is allowed. This expands to a single "jalr $25" 6137;; instruction. 6138;; 6139;; - -mabicalls/-mexplicit-relocs with o32 or o64: 6140;; Only "jal $25" is allowed. The call is actually two instructions: 6141;; "jalr $25" followed by an insn to reload $gp. 6142;; 6143;; In the last case, we can generate the individual instructions with 6144;; a define_split. There are several things to be wary of: 6145;; 6146;; - We can't expose the load of $gp before reload. If we did, 6147;; it might get removed as dead, but reload can introduce new 6148;; uses of $gp by rematerializing constants. 6149;; 6150;; - We shouldn't restore $gp after calls that never return. 6151;; It isn't valid to insert instructions between a noreturn 6152;; call and the following barrier. 6153;; 6154;; - The splitter deliberately changes the liveness of $gp. The unsplit 6155;; instruction preserves $gp and so have no effect on its liveness. 6156;; But once we generate the separate insns, it becomes obvious that 6157;; $gp is not live on entry to the call. 6158;; 6159;; ??? The operands[2] = insn check is a hack to make the original insn 6160;; available to the splitter. 6161(define_insn_and_split "call_internal" 6162 [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S")) 6163 (match_operand 1 "" "")) 6164 (clobber (reg:SI RETURN_ADDR_REGNUM))] 6165 "" 6166 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, 1); } 6167 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)" 6168 [(const_int 0)] 6169{ 6170 mips_split_call (operands[2], gen_call_split (operands[0], operands[1])); 6171 DONE; 6172} 6173 [(set_attr "jal" "indirect,direct")]) 6174 6175(define_insn "call_split" 6176 [(call (mem:SI (match_operand 0 "call_insn_operand" "cS")) 6177 (match_operand 1 "" "")) 6178 (clobber (reg:SI RETURN_ADDR_REGNUM)) 6179 (clobber (reg:SI 28))] 6180 "TARGET_SPLIT_CALLS" 6181 { return MIPS_CALL ("jal", operands, 0, 1); } 6182 [(set_attr "type" "call")]) 6183 6184;; A pattern for calls that must be made directly. It is used for 6185;; MIPS16 calls that the linker may need to redirect to a hard-float 6186;; stub; the linker relies on the call relocation type to detect when 6187;; such redirection is needed. 6188(define_insn_and_split "call_internal_direct" 6189 [(call (mem:SI (match_operand 0 "const_call_insn_operand")) 6190 (match_operand 1)) 6191 (const_int 1) 6192 (clobber (reg:SI RETURN_ADDR_REGNUM))] 6193 "" 6194 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 0, -1); } 6195 "reload_completed && TARGET_SPLIT_CALLS && (operands[2] = insn)" 6196 [(const_int 0)] 6197{ 6198 mips_split_call (operands[2], 6199 gen_call_direct_split (operands[0], operands[1])); 6200 DONE; 6201} 6202 [(set_attr "type" "call")]) 6203 6204(define_insn "call_direct_split" 6205 [(call (mem:SI (match_operand 0 "const_call_insn_operand")) 6206 (match_operand 1)) 6207 (const_int 1) 6208 (clobber (reg:SI RETURN_ADDR_REGNUM)) 6209 (clobber (reg:SI 28))] 6210 "TARGET_SPLIT_CALLS" 6211 { return MIPS_CALL ("jal", operands, 0, -1); } 6212 [(set_attr "type" "call")]) 6213 6214(define_expand "call_value" 6215 [(parallel [(set (match_operand 0 "") 6216 (call (match_operand 1 "") 6217 (match_operand 2 ""))) 6218 (use (match_operand 3 ""))])] ;; next_arg_reg 6219 "" 6220{ 6221 mips_expand_call (MIPS_CALL_NORMAL, operands[0], XEXP (operands[1], 0), 6222 operands[2], operands[3], false); 6223 DONE; 6224}) 6225 6226;; See comment for call_internal. 6227(define_insn_and_split "call_value_internal" 6228 [(set (match_operand 0 "register_operand" "") 6229 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S")) 6230 (match_operand 2 "" ""))) 6231 (clobber (reg:SI RETURN_ADDR_REGNUM))] 6232 "" 6233 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); } 6234 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)" 6235 [(const_int 0)] 6236{ 6237 mips_split_call (operands[3], 6238 gen_call_value_split (operands[0], operands[1], 6239 operands[2])); 6240 DONE; 6241} 6242 [(set_attr "jal" "indirect,direct")]) 6243 6244(define_insn "call_value_split" 6245 [(set (match_operand 0 "register_operand" "") 6246 (call (mem:SI (match_operand 1 "call_insn_operand" "cS")) 6247 (match_operand 2 "" ""))) 6248 (clobber (reg:SI RETURN_ADDR_REGNUM)) 6249 (clobber (reg:SI 28))] 6250 "TARGET_SPLIT_CALLS" 6251 { return MIPS_CALL ("jal", operands, 1, 2); } 6252 [(set_attr "type" "call")]) 6253 6254;; See call_internal_direct. 6255(define_insn_and_split "call_value_internal_direct" 6256 [(set (match_operand 0 "register_operand") 6257 (call (mem:SI (match_operand 1 "const_call_insn_operand")) 6258 (match_operand 2))) 6259 (const_int 1) 6260 (clobber (reg:SI RETURN_ADDR_REGNUM))] 6261 "" 6262 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, -1); } 6263 "reload_completed && TARGET_SPLIT_CALLS && (operands[3] = insn)" 6264 [(const_int 0)] 6265{ 6266 mips_split_call (operands[3], 6267 gen_call_value_direct_split (operands[0], operands[1], 6268 operands[2])); 6269 DONE; 6270} 6271 [(set_attr "type" "call")]) 6272 6273(define_insn "call_value_direct_split" 6274 [(set (match_operand 0 "register_operand") 6275 (call (mem:SI (match_operand 1 "const_call_insn_operand")) 6276 (match_operand 2))) 6277 (const_int 1) 6278 (clobber (reg:SI RETURN_ADDR_REGNUM)) 6279 (clobber (reg:SI 28))] 6280 "TARGET_SPLIT_CALLS" 6281 { return MIPS_CALL ("jal", operands, 1, -1); } 6282 [(set_attr "type" "call")]) 6283 6284;; See comment for call_internal. 6285(define_insn_and_split "call_value_multiple_internal" 6286 [(set (match_operand 0 "register_operand" "") 6287 (call (mem:SI (match_operand 1 "call_insn_operand" "c,S")) 6288 (match_operand 2 "" ""))) 6289 (set (match_operand 3 "register_operand" "") 6290 (call (mem:SI (match_dup 1)) 6291 (match_dup 2))) 6292 (clobber (reg:SI RETURN_ADDR_REGNUM))] 6293 "" 6294 { return TARGET_SPLIT_CALLS ? "#" : MIPS_CALL ("jal", operands, 1, 2); } 6295 "reload_completed && TARGET_SPLIT_CALLS && (operands[4] = insn)" 6296 [(const_int 0)] 6297{ 6298 mips_split_call (operands[4], 6299 gen_call_value_multiple_split (operands[0], operands[1], 6300 operands[2], operands[3])); 6301 DONE; 6302} 6303 [(set_attr "jal" "indirect,direct")]) 6304 6305(define_insn "call_value_multiple_split" 6306 [(set (match_operand 0 "register_operand" "") 6307 (call (mem:SI (match_operand 1 "call_insn_operand" "cS")) 6308 (match_operand 2 "" ""))) 6309 (set (match_operand 3 "register_operand" "") 6310 (call (mem:SI (match_dup 1)) 6311 (match_dup 2))) 6312 (clobber (reg:SI RETURN_ADDR_REGNUM)) 6313 (clobber (reg:SI 28))] 6314 "TARGET_SPLIT_CALLS" 6315 { return MIPS_CALL ("jal", operands, 1, 2); } 6316 [(set_attr "type" "call")]) 6317 6318;; Call subroutine returning any type. 6319 6320(define_expand "untyped_call" 6321 [(parallel [(call (match_operand 0 "") 6322 (const_int 0)) 6323 (match_operand 1 "") 6324 (match_operand 2 "")])] 6325 "" 6326{ 6327 int i; 6328 6329 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx)); 6330 6331 for (i = 0; i < XVECLEN (operands[2], 0); i++) 6332 { 6333 rtx set = XVECEXP (operands[2], 0, i); 6334 mips_emit_move (SET_DEST (set), SET_SRC (set)); 6335 } 6336 6337 emit_insn (gen_blockage ()); 6338 DONE; 6339}) 6340 6341;; 6342;; .................... 6343;; 6344;; MISC. 6345;; 6346;; .................... 6347;; 6348 6349 6350(define_insn "prefetch" 6351 [(prefetch (match_operand:QI 0 "address_operand" "p") 6352 (match_operand 1 "const_int_operand" "n") 6353 (match_operand 2 "const_int_operand" "n"))] 6354 "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS" 6355{ 6356 if (TARGET_LOONGSON_2EF) 6357 /* Loongson 2[ef] use load to $0 to perform prefetching. */ 6358 return "ld\t$0,%a0"; 6359 operands[1] = mips_prefetch_cookie (operands[1], operands[2]); 6360 return "pref\t%1,%a0"; 6361} 6362 [(set_attr "type" "prefetch")]) 6363 6364(define_insn "*prefetch_indexed_<mode>" 6365 [(prefetch (plus:P (match_operand:P 0 "register_operand" "d") 6366 (match_operand:P 1 "register_operand" "d")) 6367 (match_operand 2 "const_int_operand" "n") 6368 (match_operand 3 "const_int_operand" "n"))] 6369 "ISA_HAS_PREFETCHX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 6370{ 6371 operands[2] = mips_prefetch_cookie (operands[2], operands[3]); 6372 return "prefx\t%2,%1(%0)"; 6373} 6374 [(set_attr "type" "prefetchx")]) 6375 6376(define_insn "nop" 6377 [(const_int 0)] 6378 "" 6379 "%(nop%)" 6380 [(set_attr "type" "nop") 6381 (set_attr "mode" "none")]) 6382 6383;; Like nop, but commented out when outside a .set noreorder block. 6384(define_insn "hazard_nop" 6385 [(const_int 1)] 6386 "" 6387 { 6388 if (mips_noreorder.nesting_level > 0) 6389 return "nop"; 6390 else 6391 return "#nop"; 6392 } 6393 [(set_attr "type" "nop")]) 6394 6395;; MIPS4 Conditional move instructions. 6396 6397(define_insn "*mov<GPR:mode>_on_<MOVECC:mode>" 6398 [(set (match_operand:GPR 0 "register_operand" "=d,d") 6399 (if_then_else:GPR 6400 (match_operator:MOVECC 4 "equality_operator" 6401 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>") 6402 (const_int 0)]) 6403 (match_operand:GPR 2 "reg_or_0_operand" "dJ,0") 6404 (match_operand:GPR 3 "reg_or_0_operand" "0,dJ")))] 6405 "ISA_HAS_CONDMOVE" 6406 "@ 6407 mov%T4\t%0,%z2,%1 6408 mov%t4\t%0,%z3,%1" 6409 [(set_attr "type" "condmove") 6410 (set_attr "mode" "<GPR:MODE>")]) 6411 6412(define_insn "*mov<SCALARF:mode>_on_<MOVECC:mode>" 6413 [(set (match_operand:SCALARF 0 "register_operand" "=f,f") 6414 (if_then_else:SCALARF 6415 (match_operator:MOVECC 4 "equality_operator" 6416 [(match_operand:MOVECC 1 "register_operand" "<MOVECC:reg>,<MOVECC:reg>") 6417 (const_int 0)]) 6418 (match_operand:SCALARF 2 "register_operand" "f,0") 6419 (match_operand:SCALARF 3 "register_operand" "0,f")))] 6420 "ISA_HAS_FP_CONDMOVE" 6421 "@ 6422 mov%T4.<fmt>\t%0,%2,%1 6423 mov%t4.<fmt>\t%0,%3,%1" 6424 [(set_attr "type" "condmove") 6425 (set_attr "mode" "<SCALARF:MODE>")]) 6426 6427;; These are the main define_expand's used to make conditional moves. 6428 6429(define_expand "mov<mode>cc" 6430 [(set (match_dup 4) (match_operand 1 "comparison_operator")) 6431 (set (match_operand:GPR 0 "register_operand") 6432 (if_then_else:GPR (match_dup 5) 6433 (match_operand:GPR 2 "reg_or_0_operand") 6434 (match_operand:GPR 3 "reg_or_0_operand")))] 6435 "ISA_HAS_CONDMOVE" 6436{ 6437 mips_expand_conditional_move (operands); 6438 DONE; 6439}) 6440 6441(define_expand "mov<mode>cc" 6442 [(set (match_dup 4) (match_operand 1 "comparison_operator")) 6443 (set (match_operand:SCALARF 0 "register_operand") 6444 (if_then_else:SCALARF (match_dup 5) 6445 (match_operand:SCALARF 2 "register_operand") 6446 (match_operand:SCALARF 3 "register_operand")))] 6447 "ISA_HAS_FP_CONDMOVE" 6448{ 6449 mips_expand_conditional_move (operands); 6450 DONE; 6451}) 6452 6453;; 6454;; .................... 6455;; 6456;; mips16 inline constant tables 6457;; 6458;; .................... 6459;; 6460 6461(define_insn "consttable_int" 6462 [(unspec_volatile [(match_operand 0 "consttable_operand" "") 6463 (match_operand 1 "const_int_operand" "")] 6464 UNSPEC_CONSTTABLE_INT)] 6465 "TARGET_MIPS16" 6466{ 6467 assemble_integer (operands[0], INTVAL (operands[1]), 6468 BITS_PER_UNIT * INTVAL (operands[1]), 1); 6469 return ""; 6470} 6471 [(set (attr "length") (symbol_ref "INTVAL (operands[1])"))]) 6472 6473(define_insn "consttable_float" 6474 [(unspec_volatile [(match_operand 0 "consttable_operand" "")] 6475 UNSPEC_CONSTTABLE_FLOAT)] 6476 "TARGET_MIPS16" 6477{ 6478 REAL_VALUE_TYPE d; 6479 6480 gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE); 6481 REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]); 6482 assemble_real (d, GET_MODE (operands[0]), 6483 GET_MODE_BITSIZE (GET_MODE (operands[0]))); 6484 return ""; 6485} 6486 [(set (attr "length") 6487 (symbol_ref "GET_MODE_SIZE (GET_MODE (operands[0]))"))]) 6488 6489(define_insn "align" 6490 [(unspec_volatile [(match_operand 0 "const_int_operand" "")] UNSPEC_ALIGN)] 6491 "" 6492 ".align\t%0" 6493 [(set (attr "length") (symbol_ref "(1 << INTVAL (operands[0])) - 1"))]) 6494 6495(define_split 6496 [(match_operand 0 "small_data_pattern")] 6497 "reload_completed" 6498 [(match_dup 0)] 6499 { operands[0] = mips_rewrite_small_data (operands[0]); }) 6500 6501;; 6502;; .................... 6503;; 6504;; MIPS16e Save/Restore 6505;; 6506;; .................... 6507;; 6508 6509(define_insn "*mips16e_save_restore" 6510 [(match_parallel 0 "" 6511 [(set (match_operand:SI 1 "register_operand") 6512 (plus:SI (match_dup 1) 6513 (match_operand:SI 2 "const_int_operand")))])] 6514 "operands[1] == stack_pointer_rtx 6515 && mips16e_save_restore_pattern_p (operands[0], INTVAL (operands[2]), NULL)" 6516 { return mips16e_output_save_restore (operands[0], INTVAL (operands[2])); } 6517 [(set_attr "type" "arith") 6518 (set_attr "extended_mips16" "yes")]) 6519 6520;; Thread-Local Storage 6521 6522;; The TLS base pointer is accessed via "rdhwr $3, $29". No current 6523;; MIPS architecture defines this register, and no current 6524;; implementation provides it; instead, any OS which supports TLS is 6525;; expected to trap and emulate this instruction. rdhwr is part of the 6526;; MIPS 32r2 specification, but we use it on any architecture because 6527;; we expect it to be emulated. Use .set to force the assembler to 6528;; accept it. 6529;; 6530;; We do not use a constraint to force the destination to be $3 6531;; because $3 can appear explicitly as a function return value. 6532;; If we leave the use of $3 implicit in the constraints until 6533;; reload, we may end up making a $3 return value live across 6534;; the instruction, leading to a spill failure when reloading it. 6535(define_insn_and_split "tls_get_tp_<mode>" 6536 [(set (match_operand:P 0 "register_operand" "=d") 6537 (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP)) 6538 (clobber (reg:P TLS_GET_TP_REGNUM))] 6539 "HAVE_AS_TLS && !TARGET_MIPS16" 6540 "#" 6541 "&& reload_completed" 6542 [(set (reg:P TLS_GET_TP_REGNUM) 6543 (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP)) 6544 (set (match_dup 0) (reg:P TLS_GET_TP_REGNUM))] 6545 "" 6546 [(set_attr "type" "unknown") 6547 ; Since rdhwr always generates a trap for now, putting it in a delay 6548 ; slot would make the kernel's emulation of it much slower. 6549 (set_attr "can_delay" "no") 6550 (set_attr "mode" "<MODE>") 6551 (set_attr "length" "8")]) 6552 6553(define_insn "*tls_get_tp_<mode>_split" 6554 [(set (reg:P TLS_GET_TP_REGNUM) 6555 (unspec:P [(const_int 0)] UNSPEC_TLS_GET_TP))] 6556 "HAVE_AS_TLS && !TARGET_MIPS16" 6557 ".set\tpush\;.set\tmips32r2\t\;rdhwr\t$3,$29\;.set\tpop" 6558 [(set_attr "type" "unknown") 6559 ; See tls_get_tp_<mode> 6560 (set_attr "can_delay" "no") 6561 (set_attr "mode" "<MODE>")]) 6562 6563;; Synchronization instructions. 6564 6565(include "sync.md") 6566 6567; The MIPS Paired-Single Floating Point and MIPS-3D Instructions. 6568 6569(include "mips-ps-3d.md") 6570 6571; The MIPS DSP Instructions. 6572 6573(include "mips-dsp.md") 6574 6575; The MIPS DSP REV 2 Instructions. 6576 6577(include "mips-dspr2.md") 6578 6579; MIPS fixed-point instructions. 6580(include "mips-fixed.md") 6581 6582; ST-Microelectronics Loongson-2E/2F-specific patterns. 6583(include "loongson.md") 6584