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