diff options
Diffstat (limited to 'gcc/config/mips/mips.md')
-rw-r--r-- | gcc/config/mips/mips.md | 3780 |
1 files changed, 1559 insertions, 2221 deletions
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index a477d8799a0..c42c9d893a8 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -27,11 +27,7 @@ ;; Must include new entries for fmadd in addition to existing entries. (define_constants - [(UNSPEC_ULW 0) - (UNSPEC_USW 1) - (UNSPEC_ULD 2) - (UNSPEC_USD 3) - (UNSPEC_GET_FNADDR 4) + [(UNSPEC_GET_FNADDR 4) (UNSPEC_HILO_DELAY 5) (UNSPEC_BLOCKAGE 6) (UNSPEC_LOADGP 7) @@ -47,7 +43,29 @@ (UNSPEC_CONSTTABLE_DF 17) (UNSPEC_ALIGN_2 18) (UNSPEC_ALIGN_4 19) - (UNSPEC_ALIGN_8 20)]) + (UNSPEC_ALIGN_8 20) + (UNSPEC_HIGH 22) + (UNSPEC_LWL 23) + (UNSPEC_LWR 24) + (UNSPEC_SWL 25) + (UNSPEC_SWR 26) + (UNSPEC_LDL 27) + (UNSPEC_LDR 28) + (UNSPEC_SDL 29) + (UNSPEC_SDR 30) + + ;; Constants used in relocation unspecs. RELOC_GOT_PAGE and RELOC_GOT_DISP + ;; are really only available for n32 and n64. However, it is convenient + ;; to reuse them for SVR4 PIC, where they represent the local and global + ;; forms of R_MIPS_GOT16. + (RELOC_GPREL16 100) + (RELOC_GOT_HI 101) + (RELOC_GOT_LO 102) + (RELOC_GOT_PAGE 103) + (RELOC_GOT_DISP 104) + (RELOC_CALL16 105) + (RELOC_CALL_HI 106) + (RELOC_CALL_LO 107)]) ;; .................... @@ -56,17 +74,35 @@ ;; ;; .................... +;; For jal instructions, this attribute is DIRECT when the target address +;; is symbolic and INDIRECT when it is a register. +(define_attr "jal" "unset,direct,indirect" + (const_string "unset")) + +;; True for multi-instruction jal macros. jal is always a macro +;; in SVR4 PIC since it includes an instruction to restore $gp. +;; Direct jals are also macros in NewABI PIC since they load the +;; target address into $25. +(define_attr "jal_macro" "no,yes" + (cond [(eq_attr "jal" "direct") + (symbol_ref "TARGET_ABICALLS != 0") + (eq_attr "jal" "indirect") + (symbol_ref "(TARGET_ABICALLS && !TARGET_NEWABI) != 0")] + (const_string "no"))) + ;; Classification of each insn. ;; branch conditional branch ;; jump unconditional jump ;; call unconditional call ;; load load instruction(s) ;; store store instruction(s) +;; prefetch memory prefetch ;; move data movement within same register set ;; xfer transfer to/from coprocessor ;; hilo transfer of hi/lo registers ;; arith integer arithmetic instruction ;; darith double precision integer arithmetic instructions +;; const load constant ;; imul integer multiply ;; imadd integer multiply-add ;; idiv integer divide @@ -83,14 +119,19 @@ ;; frsqrt floating point reciprocal square root ;; multi multiword sequence (or user asm statements) ;; nop no operation - (define_attr "type" - "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,imadd,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop" - (const_string "unknown")) + "unknown,branch,jump,call,load,store,prefetch,move,xfer,hilo,const,arith,darith,imul,imadd,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop" + (cond [(eq_attr "jal" "!unset") + (const_string "call")] + (const_string "unknown"))) ;; Main data type used by the insn (define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown")) +;; Is this an extended instruction in mips16 mode? +(define_attr "extended_mips16" "no,yes" + (const_string "no")) + ;; Length (in # of bytes). A conditional branch is allowed only to a ;; location within a signed 18-bit offset of the delay slot. If that ;; provides too smal a range, we use the `j' instruction. This @@ -110,6 +151,27 @@ (const_int 0)) (const_int 24) ] (const_int 12)) + (eq_attr "type" "const") + (symbol_ref "mips_const_insns (operands[1]) * 4") + (eq_attr "type" "load") + (symbol_ref "mips_fetch_insns (operands[1]) * 4") + (eq_attr "type" "store") + (symbol_ref "mips_fetch_insns (operands[0]) * 4") + ;; In the worst case, a call macro will take 8 instructions: + ;; + ;; lui $25,%call_hi(FOO) + ;; addu $25,$25,$28 + ;; lw $25,%call_lo(FOO)($25) + ;; nop + ;; jalr $25 + ;; nop + ;; lw $gp,X($sp) + ;; nop + (eq_attr "jal_macro" "yes") + (const_int 32) + (and (eq_attr "extended_mips16" "yes") + (ne (symbol_ref "TARGET_MIPS16") (const_int 0))) + (const_int 8) ] (const_int 4))) ;; Attribute describing the processor. This attribute must match exactly @@ -140,15 +202,14 @@ (const_string "yes") (const_string "no"))) +;; Is it a single instruction? +(define_attr "single_insn" "no,yes" + (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)")) + ;; Can the instruction be put into a delay slot? (define_attr "can_delay" "no,yes" (if_then_else (and (eq_attr "dslot" "no") - ; ADJUST_INSN_LENGTH divides length by 2 on mips16, - ; so cope with it here. - (ior (and (eq (symbol_ref "mips16") (const_int 0)) - (eq_attr "length" "4")) - (and (ne (symbol_ref "mips16") (const_int 0)) - (eq_attr "length" "2")))) + (eq_attr "single_insn" "yes")) (const_string "yes") (const_string "no"))) @@ -165,10 +226,6 @@ (define_asm_attributes [(set_attr "type" "multi")]) -;; whether or not generating calls to position independent functions -(define_attr "abicalls" "no,yes" - (const (symbol_ref "mips_abicalls_attr"))) - ;; ......................... @@ -182,15 +239,15 @@ [(eq_attr "can_delay" "yes") (nil) (and (eq_attr "branch_likely" "yes") - (and (eq_attr "dslot" "no") - (eq_attr "length" "4")))]) + (eq_attr "can_delay" "yes"))]) (define_delay (eq_attr "type" "jump") [(eq_attr "can_delay" "yes") (nil) (nil)]) -(define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no")) +(define_delay (and (eq_attr "type" "call") + (eq_attr "jal_macro" "no")) [(eq_attr "can_delay" "yes") (nil) (nil)]) @@ -615,9 +672,9 @@ (set_attr "mode" "SF")]) (define_expand "addsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") - (match_operand:SI 2 "arith_operand" "dI")))] + [(set (match_operand:SI 0 "register_operand" "") + (plus:SI (match_operand:SI 1 "reg_or_0_operand" "") + (match_operand:SI 2 "arith_operand" "")))] "" " { @@ -653,14 +710,16 @@ }") (define_insn "addsi3_internal" - [(set (match_operand:SI 0 "register_operand" "=d") - (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") - (match_operand:SI 2 "arith_operand" "dI")))] + [(set (match_operand:SI 0 "register_operand" "=d,d") + (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ") + (match_operand:SI 2 "arith_operand" "d,Q")))] "! TARGET_MIPS16 && (TARGET_GAS || GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" - "addu\\t%0,%z1,%2" + "@ + addu\\t%0,%z1,%2 + addiu\\t%0,%z1,%2" [(set_attr "type" "arith") (set_attr "mode" "SI")]) @@ -695,7 +754,7 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=d,d,d") (plus:SI (match_operand:SI 1 "register_operand" "0,d,d") - (match_operand:SI 2 "arith_operand" "IQ,O,d")))] + (match_operand:SI 2 "arith_operand" "Q,O,d")))] "TARGET_MIPS16 && (GET_CODE (operands[1]) != REG || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER @@ -798,8 +857,8 @@ (define_expand "adddi3" [(parallel [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "se_register_operand" "") - (match_operand:DI 2 "se_arith_operand" ""))) + (plus:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "arith_operand" ""))) (clobber (match_dup 3))])] "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)" " @@ -987,20 +1046,17 @@ "") (define_insn "adddi3_internal_3" - [(set (match_operand:DI 0 "register_operand" "=d") - (plus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ") - (match_operand:DI 2 "se_arith_operand" "dI")))] + [(set (match_operand:DI 0 "register_operand" "=d,d") + (plus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ,dJ") + (match_operand:DI 2 "arith_operand" "d,Q")))] "TARGET_64BIT && !TARGET_MIPS16 && (TARGET_GAS || GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" - "* -{ - return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) - ? \"dsubu\\t%0,%z1,%n2\" - : \"daddu\\t%0,%z1,%2\"; -}" + "@ + daddu\\t%0,%z1,%2 + daddiu\\t%0,%z1,%2" [(set_attr "type" "darith") (set_attr "mode" "DI")]) @@ -1035,7 +1091,7 @@ (define_insn "" [(set (match_operand:DI 0 "register_operand" "=d,d,d") (plus:DI (match_operand:DI 1 "register_operand" "0,d,d") - (match_operand:DI 2 "arith_operand" "IQ,O,d")))] + (match_operand:DI 2 "arith_operand" "Q,O,d")))] "TARGET_MIPS16 && TARGET_64BIT && (GET_CODE (operands[1]) != REG || REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER @@ -1137,27 +1193,24 @@ }") (define_insn "addsi3_internal_2" - [(set (match_operand:DI 0 "register_operand" "=d") - (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") - (match_operand:SI 2 "arith_operand" "dI"))))] + [(set (match_operand:DI 0 "register_operand" "=d,d") + (sign_extend:DI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ,dJ") + (match_operand:SI 2 "arith_operand" "d,Q"))))] "TARGET_64BIT && !TARGET_MIPS16 && (TARGET_GAS || GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" - "* -{ - return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) - ? \"subu\\t%0,%z1,%n2\" - : \"addu\\t%0,%z1,%2\"; -}" + "@ + addu\\t%0,%z1,%2 + addiu\\t%0,%z1,%2" [(set_attr "type" "arith") (set_attr "mode" "SI")]) (define_insn "" [(set (match_operand:DI 0 "register_operand" "=d,d,d") (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d") - (match_operand:SI 2 "arith_operand" "I,O,d"))))] + (match_operand:SI 2 "arith_operand" "Q,O,d"))))] "TARGET_MIPS16 && TARGET_64BIT" "* { @@ -1353,8 +1406,8 @@ (define_expand "subdi3" [(parallel [(set (match_operand:DI 0 "register_operand" "=d") - (minus:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d"))) + (minus:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d"))) (clobber (match_dup 3))])] "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)" " @@ -1501,8 +1554,8 @@ (define_insn "subdi3_internal_3" [(set (match_operand:DI 0 "register_operand" "=d") - (minus:DI (match_operand:DI 1 "se_reg_or_0_operand" "dJ") - (match_operand:DI 2 "se_arith_operand" "dI")))] + (minus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ") + (match_operand:DI 2 "arith_operand" "dI")))] "TARGET_64BIT && !TARGET_MIPS16 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" "* @@ -1816,6 +1869,38 @@ [(set_attr "type" "imul") (set_attr "mode" "SI")]) +;; If a register gets allocated to LO, and we spill to memory, the reload +;; will include a move from LO to a GPR. Merge it into the multiplication +;; if it can set the GPR directly. +;; +;; Operand 0: LO +;; Operand 1: GPR (1st multiplication operand) +;; Operand 2: GPR (2nd multiplication operand) +;; Operand 3: HI +;; Operand 4: HILO +;; Operand 5: GPR (destination) +(define_peephole2 + [(parallel + [(set (match_operand:SI 0 "register_operand" "") + (mult:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "register_operand" ""))) + (clobber (match_operand:SI 3 "register_operand" "")) + (clobber (scratch:SI)) + (clobber (match_operand:SI 4 "register_operand" ""))]) + (set (match_operand:SI 5 "register_operand" "") + (match_dup 0))] + "GENERATE_MULT3_SI + && true_regnum (operands[0]) == LO_REGNUM + && GP_REG_P (true_regnum (operands[5])) + && peep2_reg_dead_p (2, operands[0])" + [(parallel + [(set (match_dup 5) + (mult:SI (match_dup 1) + (match_dup 2))) + (clobber (match_dup 3)) + (clobber (match_dup 0)) + (clobber (match_dup 4))])]) + (define_insn "mulsi3_internal" [(set (match_operand:SI 0 "register_operand" "=l") (mult:SI (match_operand:SI 1 "register_operand" "d") @@ -1872,30 +1957,15 @@ (clobber (match_scratch:SI 6 "=a,a,a")) (clobber (match_scratch:SI 7 "=X,X,d"))] "(TARGET_MIPS3900 - || TARGET_MIPS5400 - || TARGET_MIPS5500 || ISA_HAS_MADD_MSUB) && !TARGET_MIPS16" "* { static const char *const madd[] = { \"madd\\t%1,%2\", \"madd\\t%0,%1,%2\" }; - static const char *const macc[] = { \"macc\\t$0,%1,%2\", \"macc\\t%0,%1,%2\" }; if (which_alternative == 2) return \"#\"; if (ISA_HAS_MADD_MSUB && which_alternative != 0) return \"#\"; - - if (TARGET_MIPS5400) - return macc[which_alternative]; - - if (TARGET_MIPS5500) - { - if (which_alternative == 0) - return madd[0]; - else - return macc[which_alternative]; - } - return madd[which_alternative]; }" [(set_attr "type" "imadd,imadd,multi") @@ -1946,13 +2016,169 @@ (set (match_dup 0) (match_dup 3))] "") +(define_insn "*macc" + [(set (match_operand:SI 0 "register_operand" "=l,d") + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d") + (match_operand:SI 2 "register_operand" "d,d")) + (match_operand:SI 3 "register_operand" "0,l"))) + (clobber (match_scratch:SI 4 "=h,h")) + (clobber (match_scratch:SI 5 "=X,3")) + (clobber (match_scratch:SI 6 "=a,a"))] + "ISA_HAS_MACC" + "* +{ + if (which_alternative == 1) + return \"macc\\t%0,%1,%2\"; + else if (TARGET_MIPS5500) + return \"madd\\t%1,%2\"; + else + return \"macc\\t%.,%1,%2\"; +}" + [(set_attr "type" "imadd") + (set_attr "mode" "SI")]) + +;; Pattern generated by define_peephole2 below +(define_insn "*macc2" + [(set (match_operand:SI 0 "register_operand" "=l") + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d") + (match_operand:SI 2 "register_operand" "d")) + (match_dup 0))) + (set (match_operand:SI 3 "register_operand" "=d") + (plus:SI (mult:SI (match_dup 1) + (match_dup 2)) + (match_dup 0))) + (clobber (match_scratch:SI 4 "=h")) + (clobber (match_scratch:SI 5 "=a"))] + "ISA_HAS_MACC && reload_completed" + "macc\\t%3,%1,%2" + [(set_attr "type" "imadd") + (set_attr "mode" "SI")]) + +;; Convert macc $0,<r1>,<r2> & mflo <r3> into macc <r3>,<r1>,<r2> +;; +;; Operand 0: LO +;; Operand 1: GPR (1st multiplication operand) +;; Operand 2: GPR (2nd multiplication operand) +;; Operand 3: HI +;; Operand 4: HILO +;; Operand 5: GPR (destination) +(define_peephole2 + [(parallel + [(set (match_operand:SI 0 "register_operand" "") + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "register_operand" "")) + (match_dup 0))) + (clobber (match_operand:SI 3 "register_operand" "")) + (clobber (scratch:SI)) + (clobber (match_operand:SI 4 "register_operand" ""))]) + (set (match_operand:SI 5 "register_operand" "") + (match_dup 0))] + "ISA_HAS_MACC + && true_regnum (operands[0]) == LO_REGNUM + && GP_REG_P (true_regnum (operands[5]))" + [(parallel [(set (match_dup 0) + (plus:SI (mult:SI (match_dup 1) + (match_dup 2)) + (match_dup 0))) + (set (match_dup 5) + (plus:SI (mult:SI (match_dup 1) + (match_dup 2)) + (match_dup 0))) + (clobber (match_dup 3)) + (clobber (match_dup 4))])] + "") + +;; When we have a three-address multiplication instruction, it should +;; be faster to do a separate multiply and add, rather than moving +;; something into LO in order to use a macc instruction. +;; +;; This peephole needs a scratch register to cater for the case when one +;; of the multiplication operands is the same as the destination. +;; +;; Operand 0: GPR (scratch) +;; Operand 1: LO +;; Operand 2: GPR (addend) +;; Operand 3: GPR (destination) +;; Operand 4: GPR (1st multiplication operand) +;; Operand 5: GPR (2nd multiplication operand) +;; Operand 6: HI +;; Operand 7: HILO +(define_peephole2 + [(match_scratch:SI 0 "d") + (set (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "register_operand" "")) + (match_dup 0) + (parallel + [(set (match_operand:SI 3 "register_operand" "") + (plus:SI (mult:SI (match_operand:SI 4 "register_operand" "") + (match_operand:SI 5 "register_operand" "")) + (match_dup 1))) + (clobber (match_operand:SI 6 "register_operand" "")) + (clobber (match_dup 1)) + (clobber (match_operand:SI 7 "register_operand" ""))])] + "ISA_HAS_MACC && GENERATE_MULT3_SI + && true_regnum (operands[1]) == LO_REGNUM + && peep2_reg_dead_p (2, operands[1]) + && GP_REG_P (true_regnum (operands[3]))" + [(parallel [(set (match_dup 0) + (mult:SI (match_dup 4) + (match_dup 5))) + (clobber (match_dup 6)) + (clobber (match_dup 1)) + (clobber (match_dup 7))]) + (set (match_dup 3) + (plus:SI (match_dup 0) + (match_dup 2)))] + "") + +;; Same as above, except LO is the initial target of the macc. +;; +;; Operand 0: GPR (scratch) +;; Operand 1: LO +;; Operand 2: GPR (addend) +;; Operand 3: GPR (1st multiplication operand) +;; Operand 4: GPR (2nd multiplication operand) +;; Operand 5: HI +;; Operand 6: HILO +;; Operand 7: GPR (destination) +(define_peephole2 + [(match_scratch:SI 0 "d") + (set (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "register_operand" "")) + (match_dup 0) + (parallel + [(set (match_dup 1) + (plus:SI (mult:SI (match_operand:SI 3 "register_operand" "") + (match_operand:SI 4 "register_operand" "")) + (match_dup 1))) + (clobber (match_operand:SI 5 "register_operand" "")) + (clobber (scratch:SI)) + (clobber (match_operand:SI 6 "register_operand" ""))]) + (match_dup 0) + (set (match_operand:SI 7 "register_operand" "") + (match_dup 1))] + "ISA_HAS_MACC && GENERATE_MULT3_SI + && true_regnum (operands[1]) == LO_REGNUM + && peep2_reg_dead_p (3, operands[1]) + && GP_REG_P (true_regnum (operands[7]))" + [(parallel [(set (match_dup 0) + (mult:SI (match_dup 3) + (match_dup 4))) + (clobber (match_dup 5)) + (clobber (match_dup 1)) + (clobber (match_dup 6))]) + (set (match_dup 7) + (plus:SI (match_dup 0) + (match_dup 2)))] + "") + (define_insn "*mul_sub_si" [(set (match_operand:SI 0 "register_operand" "=l,*d,*d") (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d") (mult:SI (match_operand:SI 2 "register_operand" "d,d,d") (match_operand:SI 3 "register_operand" "d,d,d")))) (clobber (match_scratch:SI 4 "=h,h,h")) - (clobber (match_scratch:SI 5 "=X,3,l")) + (clobber (match_scratch:SI 5 "=X,1,l")) (clobber (match_scratch:SI 6 "=a,a,a")) (clobber (match_scratch:SI 7 "=X,X,d"))] "ISA_HAS_MADD_MSUB" @@ -2017,55 +2243,37 @@ (clobber (match_scratch:SI 3 "=h,h")) (clobber (match_scratch:SI 4 "=a,a")) (clobber (match_scratch:SI 5 "=X,l"))] - "ISA_HAS_MULS && TARGET_64BIT" + "ISA_HAS_MULS" "@ muls\\t$0,%1,%2 muls\\t%0,%1,%2" [(set_attr "type" "imul") (set_attr "mode" "SI")]) -;; See comments above for mul_acc_si. (define_insn "*msac" - [(set (match_operand:SI 0 "register_operand" "=l,*d,*d") - (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d") - (mult:SI (match_operand:SI 2 "register_operand" "d,d,d") - (match_operand:SI 3 "register_operand" "d,d,d")))) - (clobber (match_scratch:SI 4 "=h,h,h")) - (clobber (match_scratch:SI 5 "=X,1,l")) - (clobber (match_scratch:SI 6 "=a,a,a")) - (clobber (match_scratch:SI 7 "=X,X,d"))] - "ISA_HAS_MSAC && TARGET_64BIT" - "@ - msac\\t$0,%2,%3 - msac\\t%0,%2,%3 - #" - [(set_attr "type" "imadd,imadd,multi") - (set_attr "mode" "SI") - (set_attr "length" "4,4,8")]) - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (minus:SI (match_operand:SI 1 "register_operand" "") - (mult:SI (match_operand:SI 2 "register_operand" "") - (match_operand:SI 3 "register_operand" "")))) - (clobber (match_scratch:SI 4 "")) - (clobber (match_scratch:SI 5 "")) - (clobber (match_scratch:SI 6 "")) - (clobber (match_scratch:SI 7 ""))] - "reload_completed && !TARGET_DEBUG_D_MODE - && GP_REG_P (true_regnum (operands[0])) - && GP_REG_P (true_regnum (operands[1]))" - [(parallel [(set (match_dup 7) - (mult:SI (match_dup 2) (match_dup 3))) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (clobber (match_dup 6))]) - (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 7)))] - "") + [(set (match_operand:SI 0 "register_operand" "=l,d") + (minus:SI (match_operand:SI 1 "register_operand" "0,l") + (mult:SI (match_operand:SI 2 "register_operand" "d,d") + (match_operand:SI 3 "register_operand" "d,d")))) + (clobber (match_scratch:SI 4 "=h,h")) + (clobber (match_scratch:SI 5 "=X,1")) + (clobber (match_scratch:SI 6 "=a,a"))] + "ISA_HAS_MSAC" + "* +{ + if (which_alternative == 1) + return \"msac\\t%0,%2,%3\"; + else if (TARGET_MIPS5500) + return \"msub\\t%2,%3\"; + else + return \"msac\\t$0,%2,%3\"; +}" + [(set_attr "type" "imadd") + (set_attr "mode" "SI")]) (define_expand "muldi3" [(set (match_operand:DI 0 "register_operand" "=l") - (mult:DI (match_operand:DI 1 "se_register_operand" "d") + (mult:DI (match_operand:DI 1 "register_operand" "d") (match_operand:DI 2 "register_operand" "d"))) (clobber (match_scratch:DI 3 "=h")) (clobber (match_scratch:DI 4 "=a"))] @@ -2080,14 +2288,9 @@ DONE; }") -;; Don't accept both operands using se_register_operand, because if -;; both operands are sign extended we would prefer to use mult in the -;; mulsidi3 pattern. Commutativity should permit either operand to be -;; sign extended. - (define_insn "muldi3_internal" [(set (match_operand:DI 0 "register_operand" "=l") - (mult:DI (match_operand:DI 1 "se_register_operand" "d") + (mult:DI (match_operand:DI 1 "register_operand" "d") (match_operand:DI 2 "register_operand" "d"))) (clobber (match_scratch:DI 3 "=h")) (clobber (match_scratch:DI 4 "=a"))] @@ -2098,7 +2301,7 @@ (define_insn "muldi3_internal2" [(set (match_operand:DI 0 "register_operand" "=d") - (mult:DI (match_operand:DI 1 "se_register_operand" "d") + (mult:DI (match_operand:DI 1 "register_operand" "d") (match_operand:DI 2 "register_operand" "d"))) (clobber (match_scratch:DI 3 "=h")) (clobber (match_scratch:DI 4 "=l")) @@ -2136,16 +2339,34 @@ "" " { - rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx); if (TARGET_64BIT) - emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2], - dummy, dummy)); + emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2])); else - emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2], - dummy, dummy)); + emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2])); DONE; }") +(define_insn "mulsidi3_internal" + [(set (match_operand:DI 0 "register_operand" "=x") + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))) + (clobber (match_scratch:SI 3 "=a"))] + "!TARGET_64BIT" + "mult\\t%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "SI")]) + +(define_insn "mulsidi3_64bit" + [(set (match_operand:DI 0 "register_operand" "=a") + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "d")))) + (clobber (match_scratch:DI 3 "=l")) + (clobber (match_scratch:DI 4 "=h"))] + "TARGET_64BIT" + "mult\\t%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "SI")]) + (define_expand "umulsidi3" [(set (match_operand:DI 0 "register_operand" "=x") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) @@ -2153,249 +2374,253 @@ "" " { - rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx); if (TARGET_64BIT) - emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2], - dummy, dummy)); + emit_insn (gen_umulsidi3_64bit (operands[0], operands[1], operands[2])); else - emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2], - dummy, dummy)); + emit_insn (gen_umulsidi3_internal (operands[0], operands[1], operands[2])); + DONE; }") -(define_insn "mulsidi3_internal" + +(define_insn "umulsidi3_internal" [(set (match_operand:DI 0 "register_operand" "=x") - (mult:DI (match_operator:DI 3 "extend_operator" - [(match_operand:SI 1 "register_operand" "d")]) - (match_operator:DI 4 "extend_operator" - [(match_operand:SI 2 "register_operand" "d")]))) - (clobber (match_scratch:SI 5 "=a"))] - "!TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])" - "* -{ - if (GET_CODE (operands[3]) == SIGN_EXTEND) - return \"mult\\t%1,%2\"; - return \"multu\\t%1,%2\"; -}" + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) + (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))) + (clobber (match_scratch:SI 3 "=a"))] + "!TARGET_64BIT" + "multu\\t%1,%2" [(set_attr "type" "imul") (set_attr "mode" "SI")]) -(define_insn "mulsidi3_64bit" +(define_insn "umulsidi3_64bit" [(set (match_operand:DI 0 "register_operand" "=a") - (mult:DI (match_operator:DI 3 "extend_operator" - [(match_operand:SI 1 "register_operand" "d")]) - (match_operator:DI 4 "extend_operator" - [(match_operand:SI 2 "register_operand" "d")]))) - (clobber (match_scratch:DI 5 "=l")) - (clobber (match_scratch:DI 6 "=h"))] - "TARGET_64BIT && GET_CODE (operands[3]) == GET_CODE (operands[4])" - "* -{ - if (GET_CODE (operands[3]) == SIGN_EXTEND) - return \"mult\\t%1,%2\"; - return \"multu\\t%1,%2\"; -}" + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) + (zero_extend:DI (match_operand:SI 2 "register_operand" "d")))) + (clobber (match_scratch:DI 3 "=l")) + (clobber (match_scratch:DI 4 "=h"))] + "TARGET_64BIT" + "multu\\t%1,%2" [(set_attr "type" "imul") (set_attr "mode" "SI")]) -;; widening multiply with accumulator and/or negation -;; These don't match yet for zero-extending; too complex for combine? -;; Possible additions we should have: -;; "=x" variants for when !TARGET_64BIT ? -;; all-d alternatives with splits like pure SImode versions +;; Widening multiply with negation. It isn't worth using this pattern +;; for 64-bit code since the reload sequence for HILO_REGNUM is so long. (define_insn "*muls_di" - [(set (match_operand:DI 0 "register_operand" "=a") + [(set (match_operand:DI 0 "register_operand" "=x") (neg:DI - (mult:DI (match_operator:DI 3 "extend_operator" - [(match_operand:SI 1 "register_operand" "d")]) - (match_operator:DI 4 "extend_operator" - [(match_operand:SI 2 "register_operand" "d")])))) - (clobber (match_scratch:SI 5 "=h")) - (clobber (match_scratch:SI 6 "=l"))] - "TARGET_64BIT - && ISA_HAS_MULS - && GET_CODE (operands[3]) == GET_CODE (operands[4])" + (mult:DI + (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))) + (clobber (match_scratch:SI 3 "=a"))] + "!TARGET_64BIT && ISA_HAS_MULS" + "muls\\t$0,%1,%2" + [(set_attr "type" "imul") + (set_attr "length" "4") + (set_attr "mode" "SI")]) + +(define_insn "*umuls_di" + [(set (match_operand:DI 0 "register_operand" "=x") + (neg:DI + (mult:DI + (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) + (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))) + (clobber (match_scratch:SI 3 "=a"))] + "!TARGET_64BIT && ISA_HAS_MULS" + "mulsu\\t$0,%1,%2" + [(set_attr "type" "imul") + (set_attr "length" "4") + (set_attr "mode" "SI")]) + +;; Not used for 64-bit code: see comment for *muls_di. +(define_insn "*smsac_di" + [(set (match_operand:DI 0 "register_operand" "=x") + (minus:DI (match_operand:DI 3 "register_operand" "0") + (mult:DI + (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))) + (clobber (match_scratch:SI 4 "=a"))] + "!TARGET_64BIT && ISA_HAS_MSAC" "* { - if (GET_CODE (operands[3]) == SIGN_EXTEND) - return \"muls\\t$0,%1,%2\"; + if (TARGET_MIPS5500) + return \"msub\\t%1,%2\"; else - return \"mulsu\\t$0,%1,%2\"; + return \"msac\\t$0,%1,%2\"; }" - [(set_attr "type" "imul") + [(set_attr "type" "imadd") (set_attr "length" "4") (set_attr "mode" "SI")]) -(define_insn "*msac_di" - [(set (match_operand:DI 0 "register_operand" "=a") - (minus:DI (match_operand:DI 3 "register_operand" "0") - (mult:DI (match_operator:DI 4 "extend_operator" - [(match_operand:SI 1 "register_operand" "d")]) - (match_operator:DI 5 "extend_operator" - [(match_operand:SI 2 "register_operand" "d")])))) - (clobber (match_scratch:SI 6 "=h")) - (clobber (match_scratch:SI 7 "=l"))] - "TARGET_64BIT - && ISA_HAS_MSAC - && GET_CODE (operands[4]) == GET_CODE (operands[5])" +(define_insn "*umsac_di" + [(set (match_operand:DI 0 "register_operand" "=x") + (minus:DI (match_operand:DI 3 "register_operand" "0") + (mult:DI + (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) + (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))) + (clobber (match_scratch:SI 4 "=a"))] + "!TARGET_64BIT && ISA_HAS_MSAC" "* { - if (GET_CODE (operands[4]) == SIGN_EXTEND) - { - if (TARGET_MIPS5500) - return \"msub\\t%1,%2\"; - else - return \"msac\\t$0,%1,%2\"; - } + if (TARGET_MIPS5500) + return \"msubu\\t%1,%2\"; else - { - if (TARGET_MIPS5500) - return \"msubu\\t%1,%2\"; - else return \"msacu\\t$0,%1,%2\"; - } }" [(set_attr "type" "imadd") (set_attr "length" "4") (set_attr "mode" "SI")]) ;; _highpart patterns -(define_expand "smulsi3_highpart" +(define_expand "umulsi3_highpart" [(set (match_operand:SI 0 "register_operand" "=h") (truncate:SI - (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) - (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))) - (const_int 32))))] + (lshiftrt:DI + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) + (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))) + (const_int 32))))] "" " { - rtx dummy = gen_rtx (SIGN_EXTEND, DImode, const0_rtx); - rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx); -#ifndef NO_MD_PROTOTYPES - rtx (*genfn) PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx)); -#else - rtx (*genfn) (); -#endif - if (ISA_HAS_MULHI && TARGET_64BIT) - genfn = gen_xmulsi3_highpart_mulhi; - else - genfn = gen_xmulsi3_highpart_internal; - emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy, - dummy, dummy2)); + if (ISA_HAS_MULHI) + emit_insn (gen_umulsi3_highpart_mulhi_internal (operands[0], operands[1], + operands[2])); + else + emit_insn (gen_umulsi3_highpart_internal (operands[0], operands[1], + operands[2])); DONE; }") -(define_expand "umulsi3_highpart" +(define_insn "umulsi3_highpart_internal" [(set (match_operand:SI 0 "register_operand" "=h") (truncate:SI - (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) - (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))) - (const_int 32))))] + (lshiftrt:DI + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) + (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))) + (const_int 32)))) + (clobber (match_scratch:SI 3 "=l")) + (clobber (match_scratch:SI 4 "=a"))] + "!ISA_HAS_MULHI" + "multu\\t%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "SI") + (set_attr "length" "4")]) + +(define_insn "umulsi3_highpart_mulhi_internal" + [(set (match_operand:SI 0 "register_operand" "=h,d") + (truncate:SI + (lshiftrt:DI + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d")) + (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d"))) + (const_int 32)))) + (clobber (match_scratch:SI 3 "=l,l")) + (clobber (match_scratch:SI 4 "=a,a")) + (clobber (match_scratch:SI 5 "=X,h"))] + "ISA_HAS_MULHI" + "@ + multu\\t%1,%2 + mulhiu\\t%0,%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "SI") + (set_attr "length" "4")]) + +(define_insn "umulsi3_highpart_neg_mulhi_internal" + [(set (match_operand:SI 0 "register_operand" "=h,d") + (truncate:SI + (lshiftrt:DI + (neg:DI + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d,d")) + (zero_extend:DI (match_operand:SI 2 "register_operand" "d,d")))) + (const_int 32)))) + (clobber (match_scratch:SI 3 "=l,l")) + (clobber (match_scratch:SI 4 "=a,a")) + (clobber (match_scratch:SI 5 "=X,h"))] + "ISA_HAS_MULHI" + "@ + mulshiu\\t%.,%1,%2 + mulshiu\\t%0,%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "SI") + (set_attr "length" "4")]) + +(define_expand "smulsi3_highpart" + [(set (match_operand:SI 0 "register_operand" "=h") + (truncate:SI + (lshiftrt:DI + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))) + (const_int 32))))] "" " { - rtx dummy = gen_rtx (ZERO_EXTEND, DImode, const0_rtx); - rtx dummy2 = gen_rtx_LSHIFTRT (DImode, const0_rtx, const0_rtx); -#ifndef NO_MD_PROTOTYPES - rtx (*genfn) PARAMS ((rtx, rtx, rtx, rtx, rtx, rtx)); -#else - rtx (*genfn) (); -#endif - if (ISA_HAS_MULHI && TARGET_64BIT) - genfn = gen_xmulsi3_highpart_mulhi; + if (ISA_HAS_MULHI) + emit_insn (gen_smulsi3_highpart_mulhi_internal (operands[0], operands[1], + operands[2])); else - genfn = gen_xmulsi3_highpart_internal; - emit_insn ((*genfn) (operands[0], operands[1], operands[2], dummy, - dummy, dummy2)); + emit_insn (gen_smulsi3_highpart_internal (operands[0], operands[1], + operands[2])); DONE; }") -(define_insn "xmulsi3_highpart_internal" +(define_insn "smulsi3_highpart_internal" [(set (match_operand:SI 0 "register_operand" "=h") (truncate:SI - (match_operator:DI 5 "highpart_shift_operator" - [(mult:DI (match_operator:DI 3 "extend_operator" - [(match_operand:SI 1 "register_operand" "d")]) - (match_operator:DI 4 "extend_operator" - [(match_operand:SI 2 "register_operand" "d")])) - (const_int 32)]))) - (clobber (match_scratch:SI 6 "=l")) - (clobber (match_scratch:SI 7 "=a"))] - "GET_CODE (operands[3]) == GET_CODE (operands[4])" - "* -{ - if (GET_CODE (operands[3]) == SIGN_EXTEND) - return \"mult\\t%1,%2\"; - else - return \"multu\\t%1,%2\"; -}" + (lshiftrt:DI + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))) + (const_int 32)))) + (clobber (match_scratch:SI 3 "=l")) + (clobber (match_scratch:SI 4 "=a"))] + "!ISA_HAS_MULHI" + "mult\\t%1,%2" [(set_attr "type" "imul") - (set_attr "mode" "SI")]) + (set_attr "mode" "SI") + (set_attr "length" "4")]) -(define_insn "xmulsi3_highpart_mulhi" +(define_insn "smulsi3_highpart_mulhi_internal" [(set (match_operand:SI 0 "register_operand" "=h,d") (truncate:SI - (match_operator:DI 5 "highpart_shift_operator" - [(mult:DI (match_operator:DI 3 "extend_operator" - [(match_operand:SI 1 "register_operand" "d,d")]) - (match_operator:DI 4 "extend_operator" - [(match_operand:SI 2 "register_operand" "d,d")])) - (const_int 32)]))) - (clobber (match_scratch:SI 6 "=l,l")) - (clobber (match_scratch:SI 7 "=a,a")) - (clobber (match_scratch:SI 8 "=X,h"))] - "ISA_HAS_MULHI - && TARGET_64BIT - && GET_CODE (operands[3]) == GET_CODE (operands[4])" - "* -{ - static char const *const sign[] = { \"mult\\t%1,%2\", \"mulhi\\t%0,%1,%2\" }; - static char const *const zero[] = { \"multu\\t%1,%2\", \"mulhiu\\t%0,%1,%2\" }; - if (GET_CODE (operands[3]) == SIGN_EXTEND) - return sign[which_alternative]; - else - return zero[which_alternative]; -}" - [(set_attr "type" "imul") - (set_attr "mode" "SI") - (set_attr "length" "4")]) + (lshiftrt:DI + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d"))) + (const_int 32)))) + (clobber (match_scratch:SI 3 "=l,l")) + (clobber (match_scratch:SI 4 "=a,a")) + (clobber (match_scratch:SI 5 "=X,h"))] + "ISA_HAS_MULHI" + "@ + mult\\t%1,%2 + mulhi\\t%0,%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "SI") + (set_attr "length" "4")]) -(define_insn "*xmulsi3_neg_highpart_mulhi" +(define_insn "smulsi3_highpart_neg_mulhi_internal" [(set (match_operand:SI 0 "register_operand" "=h,d") (truncate:SI - (match_operator:DI 5 "highpart_shift_operator" - [(neg:DI - (mult:DI (match_operator:DI 3 "extend_operator" - [(match_operand:SI 1 "register_operand" "d,d")]) - (match_operator:DI 4 "extend_operator" - [(match_operand:SI 2 "register_operand" "d,d")]))) - (const_int 32)]))) - (clobber (match_scratch:SI 6 "=l,l")) - (clobber (match_scratch:SI 7 "=a,a")) - (clobber (match_scratch:SI 8 "=X,h"))] - "ISA_HAS_MULHI - && TARGET_64BIT - && GET_CODE (operands[3]) == GET_CODE (operands[4])" - "* -{ - static char const *const sign[] = { \"mulshi\\t$0,%1,%2\", \"mulshi\\t%0,%1,%2\" }; - static char const *const zero[] = { \"mulshiu\\t$0,%1,%2\", \"mulshiu\\t%0,%1,%2\" }; - if (GET_CODE (operands[3]) == SIGN_EXTEND) - return sign[which_alternative]; - else - return zero[which_alternative]; -}" - [(set_attr "type" "imul") - (set_attr "mode" "SI") - (set_attr "length" "4")]) - + (lshiftrt:DI + (neg:DI + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d,d")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "d,d")))) + (const_int 32)))) + (clobber (match_scratch:SI 3 "=l,l")) + (clobber (match_scratch:SI 4 "=a,a")) + (clobber (match_scratch:SI 5 "=X,h"))] + "ISA_HAS_MULHI" + "@ + mulshi\\t%.,%1,%2 + mulshi\\t%0,%1,%2" + [(set_attr "type" "imul") + (set_attr "mode" "SI")]) (define_insn "smuldi3_highpart" [(set (match_operand:DI 0 "register_operand" "=h") (truncate:DI - (lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "se_register_operand" "d")) - (sign_extend:TI (match_operand:DI 2 "se_register_operand" "d"))) - (const_int 64)))) + (lshiftrt:TI + (mult:TI + (sign_extend:TI (match_operand:DI 1 "register_operand" "d")) + (sign_extend:TI (match_operand:DI 2 "register_operand" "d"))) + (const_int 64)))) (clobber (match_scratch:DI 3 "=l")) (clobber (match_scratch:DI 4 "=a"))] "TARGET_64BIT" @@ -2406,9 +2631,11 @@ (define_insn "umuldi3_highpart" [(set (match_operand:DI 0 "register_operand" "=h") (truncate:DI - (lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "se_register_operand" "d")) - (zero_extend:TI (match_operand:DI 2 "se_register_operand" "d"))) - (const_int 64)))) + (lshiftrt:TI + (mult:TI + (zero_extend:TI (match_operand:DI 1 "register_operand" "d")) + (zero_extend:TI (match_operand:DI 2 "register_operand" "d"))) + (const_int 64)))) (clobber (match_scratch:DI 3 "=l")) (clobber (match_scratch:DI 4 "=a"))] "TARGET_64BIT" @@ -2416,6 +2643,7 @@ [(set_attr "type" "imul") (set_attr "mode" "DI")]) + ;; The R4650 supports a 32 bit multiply/ 64 bit accumulate ;; instruction. The HI/LO registers are used as a 64 bit accumulator. @@ -2431,71 +2659,49 @@ [(set_attr "type" "imadd") (set_attr "mode" "SI")]) -(define_insn "*mul_acc_di" - [(set (match_operand:DI 0 "register_operand" "+x") - (plus:DI (mult:DI (match_operator:DI 3 "extend_operator" - [(match_operand:SI 1 "register_operand" "d")]) - (match_operator:DI 4 "extend_operator" - [(match_operand:SI 2 "register_operand" "d")])) - (match_dup 0))) - (clobber (match_scratch:SI 5 "=a"))] - "TARGET_MAD - && ! TARGET_64BIT - && GET_CODE (operands[3]) == GET_CODE (operands[4])" +;; Only use this pattern in 32-bit code: see *muls_di. +(define_insn "*umul_acc_di" + [(set (match_operand:DI 0 "register_operand" "=x") + (plus:DI + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d")) + (zero_extend:DI (match_operand:SI 2 "register_operand" "d"))) + (match_operand:DI 3 "register_operand" "0"))) + (clobber (match_scratch:SI 4 "=a"))] + "(TARGET_MAD || ISA_HAS_MACC) + && !TARGET_64BIT" "* { - if (GET_CODE (operands[3]) == SIGN_EXTEND) - return \"mad\\t%1,%2\"; - else + if (TARGET_MAD) return \"madu\\t%1,%2\"; + else if (TARGET_MIPS5500) + return \"maddu\\t%1,%2\"; + else + return \"maccu\\t%.,%1,%2\"; }" - [(set_attr "type" "imadd") - (set_attr "mode" "SI")]) + [(set_attr "type" "imadd") + (set_attr "mode" "SI")]) -(define_insn "*mul_acc_64bit_di" - [(set (match_operand:DI 0 "register_operand" "+a") - (plus:DI (mult:DI (match_operator:DI 3 "extend_operator" - [(match_operand:SI 1 "register_operand" "d")]) - (match_operator:DI 4 "extend_operator" - [(match_operand:SI 2 "register_operand" "d")])) - (match_dup 0))) - (clobber (match_scratch:SI 5 "=h")) - (clobber (match_scratch:SI 6 "=l"))] - "TARGET_MAD - && TARGET_64BIT - && GET_CODE (operands[3]) == GET_CODE (operands[4])" + +(define_insn "*smul_acc_di" + [(set (match_operand:DI 0 "register_operand" "=x") + (plus:DI + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")) + (sign_extend:DI (match_operand:SI 2 "register_operand" "d"))) + (match_operand:DI 3 "register_operand" "0"))) + (clobber (match_scratch:SI 4 "=a"))] + "(TARGET_MAD || ISA_HAS_MACC) + && !TARGET_64BIT" "* { if (TARGET_MAD) - { - if (GET_CODE (operands[3]) == SIGN_EXTEND) - return \"mad\\t%1,%2\"; - else - return \"madu\\t%1,%2\"; - } - else if (ISA_HAS_MACC) - { - if (GET_CODE (operands[3]) == SIGN_EXTEND) - { - if (TARGET_MIPS5500) - return \"madd\\t%1,%2\"; - else - return \"macc\\t$0,%1,%2\"; - } - else - { - if (TARGET_MIPS5500) - return \"maddu\\t%1,%2\"; - else - return \"maccu\\t$0,%1,%2\"; - } - } + return \"mad\\t%1,%2\"; + else if (TARGET_MIPS5500) + return \"madd\\t%1,%2\"; else - abort (); - + return \"macc\\t%.,%1,%2\"; }" - [(set_attr "type" "imadd") - (set_attr "mode" "SI")]) + [(set_attr "type" "imadd") + (set_attr "mode" "SI")]) ;; Floating point multiply accumulate instructions. @@ -2689,8 +2895,8 @@ (define_expand "divmoddi4" [(set (match_operand:DI 0 "register_operand" "=d") - (div:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d"))) + (div:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d"))) (set (match_operand:DI 3 "register_operand" "=d") (mod:DI (match_dup 1) (match_dup 2))) @@ -2724,8 +2930,8 @@ (define_insn "divmoddi4_internal" [(set (match_operand:DI 0 "register_operand" "=l") - (div:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d"))) + (div:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d"))) (set (match_operand:DI 3 "register_operand" "=h") (mod:DI (match_dup 1) (match_dup 2))) @@ -2775,8 +2981,8 @@ (define_expand "udivmoddi4" [(set (match_operand:DI 0 "register_operand" "=d") - (udiv:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d"))) + (udiv:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d"))) (set (match_operand:DI 3 "register_operand" "=d") (umod:DI (match_dup 1) (match_dup 2))) @@ -2800,8 +3006,8 @@ (define_insn "udivmoddi4_internal" [(set (match_operand:DI 0 "register_operand" "=l") - (udiv:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d"))) + (udiv:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d"))) (set (match_operand:DI 3 "register_operand" "=h") (umod:DI (match_dup 1) (match_dup 2))) @@ -2914,6 +3120,7 @@ " { emit_insn (gen_divsi3_internal (operands[0], operands[1], operands[2])); + if (!TARGET_NO_CHECK_ZERO_DIV) { emit_insn (gen_div_trap (operands[2], @@ -2949,8 +3156,8 @@ (define_expand "divdi3" [(set (match_operand:DI 0 "register_operand" "=l") - (div:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d"))) + (div:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d"))) (clobber (match_scratch:DI 3 "=h")) (clobber (match_scratch:DI 4 "=a"))] "TARGET_64BIT && !optimize" @@ -2979,8 +3186,8 @@ (define_insn "divdi3_internal" [(set (match_operand:DI 0 "register_operand" "=l") - (div:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_nonmemory_operand" "di"))) + (div:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "nonmemory_operand" "di"))) (clobber (match_scratch:SI 3 "=h")) (clobber (match_scratch:SI 4 "=a"))] "TARGET_64BIT && !optimize" @@ -3033,8 +3240,8 @@ (define_expand "moddi3" [(set (match_operand:DI 0 "register_operand" "=h") - (mod:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d"))) + (mod:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d"))) (clobber (match_scratch:DI 3 "=l")) (clobber (match_scratch:DI 4 "=a"))] "TARGET_64BIT && !optimize" @@ -3063,8 +3270,8 @@ (define_insn "moddi3_internal" [(set (match_operand:DI 0 "register_operand" "=h") - (mod:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_nonmemory_operand" "di"))) + (mod:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "nonmemory_operand" "di"))) (clobber (match_scratch:SI 3 "=l")) (clobber (match_scratch:SI 4 "=a"))] "TARGET_64BIT && !optimize" @@ -3105,8 +3312,8 @@ (define_expand "udivdi3" [(set (match_operand:DI 0 "register_operand" "=l") - (udiv:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "di"))) + (udiv:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "di"))) (clobber (match_scratch:DI 3 "=h")) (clobber (match_scratch:DI 4 "=a"))] "TARGET_64BIT && !optimize" @@ -3125,8 +3332,8 @@ (define_insn "udivdi3_internal" [(set (match_operand:DI 0 "register_operand" "=l") - (udiv:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_nonmemory_operand" "di"))) + (udiv:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "nonmemory_operand" "di"))) (clobber (match_scratch:SI 3 "=h")) (clobber (match_scratch:SI 4 "=a"))] "TARGET_64BIT && !optimize" @@ -3167,8 +3374,8 @@ (define_expand "umoddi3" [(set (match_operand:DI 0 "register_operand" "=h") - (umod:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "di"))) + (umod:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "di"))) (clobber (match_scratch:DI 3 "=l")) (clobber (match_scratch:DI 4 "=a"))] "TARGET_64BIT && !optimize" @@ -3187,8 +3394,8 @@ (define_insn "umoddi3_internal" [(set (match_operand:DI 0 "register_operand" "=h") - (umod:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_nonmemory_operand" "di"))) + (umod:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "nonmemory_operand" "di"))) (clobber (match_scratch:SI 3 "=l")) (clobber (match_scratch:SI 4 "=a"))] "TARGET_64BIT && !optimize" @@ -3274,7 +3481,7 @@ (define_insn "absdi2" [(set (match_operand:DI 0 "register_operand" "=d") - (abs:DI (match_operand:DI 1 "se_register_operand" "d")))] + (abs:DI (match_operand:DI 1 "register_operand" "d")))] "TARGET_64BIT && !TARGET_MIPS16" "* { @@ -3360,7 +3567,7 @@ move\\t%0,%z4\\n\\ (define_insn "ffsdi2" [(set (match_operand:DI 0 "register_operand" "=&d") - (ffs:DI (match_operand:DI 1 "se_register_operand" "d"))) + (ffs:DI (match_operand:DI 1 "register_operand" "d"))) (clobber (match_scratch:DI 2 "=&d")) (clobber (match_scratch:DI 3 "=&d"))] "TARGET_64BIT && !TARGET_MIPS16" @@ -3418,7 +3625,7 @@ move\\t%0,%z4\\n\\ (define_expand "negdi2" [(parallel [(set (match_operand:DI 0 "register_operand" "=d") - (neg:DI (match_operand:DI 1 "se_register_operand" "d"))) + (neg:DI (match_operand:DI 1 "register_operand" "d"))) (clobber (match_dup 2))])] "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16" " @@ -3448,7 +3655,7 @@ move\\t%0,%z4\\n\\ (define_insn "negdi2_internal_2" [(set (match_operand:DI 0 "register_operand" "=d") - (neg:DI (match_operand:DI 1 "se_register_operand" "d")))] + (neg:DI (match_operand:DI 1 "register_operand" "d")))] "TARGET_64BIT && !TARGET_MIPS16" "* { @@ -3490,40 +3697,16 @@ move\\t%0,%z4\\n\\ (define_insn "one_cmpldi2" [(set (match_operand:DI 0 "register_operand" "=d") - (not:DI (match_operand:DI 1 "se_register_operand" "d")))] - "" + (not:DI (match_operand:DI 1 "register_operand" "d")))] + "TARGET_64BIT" "* { if (TARGET_MIPS16) - { - if (TARGET_64BIT) - return \"not\\t%0,%1\"; - return \"not\\t%M0,%M1\;not\\t%L0,%L1\"; - } - operands[2] = const0_rtx; - if (TARGET_64BIT) - return \"nor\\t%0,%z2,%1\"; - return \"nor\\t%M0,%z2,%M1\;nor\\t%L0,%z2,%L1\"; + return \"not\\t%0,%1\"; + return \"nor\\t%0,%.,%1\"; }" [(set_attr "type" "darith") - (set_attr "mode" "DI") - (set (attr "length") - (if_then_else (ge (symbol_ref "mips_isa") (const_int 3)) - (const_int 4) - (const_int 8)))]) - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (not:DI (match_operand:DI 1 "register_operand" "")))] - "reload_completed && !TARGET_64BIT - && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE - && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) - && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1]))" - - [(set (subreg:SI (match_dup 0) 0) (not:SI (subreg:SI (match_dup 1) 0))) - (set (subreg:SI (match_dup 0) 4) (not:SI (subreg:SI (match_dup 1) 4)))] - "") - + (set_attr "mode" "DI")]) ;; ;; .................... @@ -3571,10 +3754,10 @@ move\\t%0,%z4\\n\\ (set_attr "mode" "SI")]) (define_expand "anddi3" - [(set (match_operand:DI 0 "register_operand" "=d") - (and:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d")))] - "TARGET_64BIT || !TARGET_DEBUG_G_MODE" + [(set (match_operand:DI 0 "register_operand" "") + (and:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "uns_arith_operand" "")))] + "TARGET_64BIT" " { if (TARGET_MIPS16) @@ -3585,64 +3768,23 @@ move\\t%0,%z4\\n\\ }") (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=d") - (and:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d")))] - "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16" - "* -{ - if (TARGET_64BIT) - return \"and\\t%0,%1,%2\"; - return \"and\\t%M0,%M1,%M2\;and\\t%L0,%L1,%L2\"; -}" - [(set_attr "type" "darith") - (set_attr "mode" "DI") - (set (attr "length") - (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0)) - (const_int 4) - (const_int 8)))]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=d") - (and:DI (match_operand:DI 1 "se_register_operand" "0") - (match_operand:DI 2 "se_register_operand" "d")))] - "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16" - "* -{ - if (TARGET_64BIT) - return \"and\\t%0,%2\"; - return \"and\\t%M0,%M2\;and\\t%L0,%L2\"; -}" - [(set_attr "type" "darith") - (set_attr "mode" "DI") - (set (attr "length") - (if_then_else (ge (symbol_ref "mips_isa") (const_int 3)) - (const_int 4) - (const_int 8)))]) - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (and:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" "")))] - "reload_completed && !TARGET_64BIT - && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE - && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) - && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) - && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" - - [(set (subreg:SI (match_dup 0) 0) (and:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0))) - (set (subreg:SI (match_dup 0) 4) (and:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))] - "") - -(define_insn "anddi3_internal1" [(set (match_operand:DI 0 "register_operand" "=d,d") - (and:DI (match_operand:DI 1 "se_register_operand" "%d,d") - (match_operand:DI 2 "se_uns_arith_operand" "d,K")))] + (and:DI (match_operand:DI 1 "register_operand" "d,d") + (match_operand:DI 2 "uns_arith_operand" "d,K")))] "TARGET_64BIT && !TARGET_MIPS16" "@ and\\t%0,%1,%2 andi\\t%0,%1,%x2" - [(set_attr "type" "arith") + [(set_attr "type" "darith") + (set_attr "mode" "DI")]) + +(define_insn "" + [(set (match_operand:DI 0 "register_operand" "=d") + (and:DI (match_operand:DI 1 "register_operand" "0") + (match_operand:DI 2 "register_operand" "d")))] + "TARGET_64BIT && TARGET_MIPS16" + "and\\t%0,%2" + [(set_attr "type" "darith") (set_attr "mode" "DI")]) (define_expand "iorsi3" @@ -3679,65 +3821,39 @@ move\\t%0,%z4\\n\\ [(set_attr "type" "arith") (set_attr "mode" "SI")]) -;;; ??? There is no iordi3 pattern which accepts 'K' constants when -;;; TARGET_64BIT - (define_expand "iordi3" - [(set (match_operand:DI 0 "register_operand" "=d") - (ior:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d")))] - "TARGET_64BIT || !TARGET_DEBUG_G_MODE" - "") + [(set (match_operand:DI 0 "register_operand" "") + (ior:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "uns_arith_operand" "")))] + "TARGET_64BIT" + " +{ + if (TARGET_MIPS16) + { + operands[1] = force_reg (DImode, operands[1]); + operands[2] = force_reg (DImode, operands[2]); + } +}") (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=d") - (ior:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d")))] - "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16" - "* -{ - if (TARGET_64BIT) - return \"or\\t%0,%1,%2\"; - return \"or\\t%M0,%M1,%M2\;or\\t%L0,%L1,%L2\"; -}" + [(set (match_operand:DI 0 "register_operand" "=d,d") + (ior:DI (match_operand:DI 1 "register_operand" "d,d") + (match_operand:DI 2 "uns_arith_operand" "d,K")))] + "TARGET_64BIT && !TARGET_MIPS16" + "@ + or\t%0,%1,%2 + ori\t%0,%1,%x2" [(set_attr "type" "darith") - (set_attr "mode" "DI") - (set (attr "length") - (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0)) - (const_int 4) - (const_int 8)))]) + (set_attr "mode" "DI")]) (define_insn "" [(set (match_operand:DI 0 "register_operand" "=d") - (ior:DI (match_operand:DI 1 "se_register_operand" "0") - (match_operand:DI 2 "se_register_operand" "d")))] - "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && TARGET_MIPS16" - "* -{ - if (TARGET_64BIT) - return \"or\\t%0,%2\"; - return \"or\\t%M0,%M2\;or\\t%L0,%L2\"; -}" + (ior:DI (match_operand:DI 1 "register_operand" "0") + (match_operand:DI 2 "register_operand" "d")))] + "TARGET_64BIT && TARGET_MIPS16" + "or\t%0,%2" [(set_attr "type" "darith") - (set_attr "mode" "DI") - (set (attr "length") - (if_then_else (ge (symbol_ref "mips_isa") (const_int 3)) - (const_int 4) - (const_int 8)))]) - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (ior:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" "")))] - "reload_completed && !TARGET_64BIT - && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE - && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) - && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) - && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" - - [(set (subreg:SI (match_dup 0) 0) (ior:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0))) - (set (subreg:SI (match_dup 0) 4) (ior:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))] - "") + (set_attr "mode" "DI")]) (define_expand "xorsi3" [(set (match_operand:SI 0 "register_operand" "=d,d") @@ -3775,47 +3891,35 @@ move\\t%0,%z4\\n\\ (const_int 8)) (const_int 4)])]) -;; ??? If delete the 32-bit long long patterns, then could merge this with -;; the following xordi3_internal pattern. (define_expand "xordi3" - [(set (match_operand:DI 0 "register_operand" "=d") - (xor:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d")))] - "TARGET_64BIT || !TARGET_DEBUG_G_MODE" - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=d") - (xor:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d")))] - "(TARGET_64BIT || !TARGET_DEBUG_G_MODE) && !TARGET_MIPS16" - "* + [(set (match_operand:DI 0 "register_operand" "") + (xor:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "uns_arith_operand" "")))] + "TARGET_64BIT" + " { - if (TARGET_64BIT) - return \"xor\\t%0,%1,%2\"; - return \"xor\\t%M0,%M1,%M2\;xor\\t%L0,%L1,%L2\"; -}" - [(set_attr "type" "darith") - (set_attr "mode" "DI") - (set (attr "length") - (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0)) - (const_int 4) - (const_int 8)))]) + if (TARGET_MIPS16) + { + operands[1] = force_reg (DImode, operands[1]); + operands[2] = force_reg (DImode, operands[2]); + } +}") (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=d") - (xor:DI (match_operand:DI 1 "se_register_operand" "0") - (match_operand:DI 2 "se_register_operand" "d")))] - "!TARGET_64BIT && TARGET_MIPS16" - "xor\\t%M0,%M2\;xor\\t%L0,%L2" + [(set (match_operand:DI 0 "register_operand" "=d,d") + (xor:DI (match_operand:DI 1 "register_operand" "d,d") + (match_operand:DI 2 "uns_arith_operand" "d,K")))] + "TARGET_64BIT && !TARGET_MIPS16" + "@ + xor\t%0,%1,%2 + xori\t%0,%1,%x2" [(set_attr "type" "darith") - (set_attr "mode" "DI") - (set_attr "length" "8")]) + (set_attr "mode" "DI")]) (define_insn "" [(set (match_operand:DI 0 "register_operand" "=d,t,t") - (xor:DI (match_operand:DI 1 "se_register_operand" "%0,d,d") - (match_operand:DI 2 "se_uns_arith_operand" "d,K,d")))] + (xor:DI (match_operand:DI 1 "register_operand" "%0,d,d") + (match_operand:DI 2 "uns_arith_operand" "d,K,d")))] "TARGET_64BIT && TARGET_MIPS16" "@ xor\\t%0,%2 @@ -3830,29 +3934,6 @@ move\\t%0,%z4\\n\\ (const_int 8)) (const_int 4)])]) -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (xor:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" "")))] - "reload_completed && !TARGET_64BIT - && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE - && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) - && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) - && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" - - [(set (subreg:SI (match_dup 0) 0) (xor:SI (subreg:SI (match_dup 1) 0) (subreg:SI (match_dup 2) 0))) - (set (subreg:SI (match_dup 0) 4) (xor:SI (subreg:SI (match_dup 1) 4) (subreg:SI (match_dup 2) 4)))] - "") - -(define_insn "xordi3_immed" - [(set (match_operand:DI 0 "register_operand" "=d") - (xor:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_uns_arith_operand" "K")))] - "TARGET_64BIT && !TARGET_MIPS16" - "xori\\t%0,%1,%x2" - [(set_attr "type" "arith") - (set_attr "mode" "DI")]) - (define_insn "*norsi3" [(set (match_operand:SI 0 "register_operand" "=d") (and:SI (not:SI (match_operand:SI 1 "register_operand" "d")) @@ -3864,35 +3945,12 @@ move\\t%0,%z4\\n\\ (define_insn "*nordi3" [(set (match_operand:DI 0 "register_operand" "=d") - (and:DI (not:DI (match_operand:DI 1 "se_register_operand" "d")) - (not:DI (match_operand:DI 2 "se_register_operand" "d"))))] - "!TARGET_MIPS16" - "* -{ - if (TARGET_64BIT) - return \"nor\\t%0,%z1,%z2\"; - return \"nor\\t%M0,%M1,%M2\;nor\\t%L0,%L1,%L2\"; -}" + (and:DI (not:DI (match_operand:DI 1 "register_operand" "d")) + (not:DI (match_operand:DI 2 "register_operand" "d"))))] + "TARGET_64BIT && !TARGET_MIPS16" + "nor\\t%0,%z1,%z2" [(set_attr "type" "darith") - (set_attr "mode" "DI") - (set (attr "length") - (if_then_else (ne (symbol_ref "TARGET_64BIT") (const_int 0)) - (const_int 4) - (const_int 8)))]) - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (and:DI (not:DI (match_operand:DI 1 "register_operand" "")) - (not:DI (match_operand:DI 2 "register_operand" ""))))] - "reload_completed && !TARGET_MIPS16 && !TARGET_64BIT - && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE - && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) - && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) - && GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))" - - [(set (subreg:SI (match_dup 0) 0) (and:SI (not:SI (subreg:SI (match_dup 1) 0)) (not:SI (subreg:SI (match_dup 2) 0)))) - (set (subreg:SI (match_dup 0) 4) (and:SI (not:SI (subreg:SI (match_dup 1) 4)) (not:SI (subreg:SI (match_dup 2) 4))))] - "") + (set_attr "mode" "DI")]) ;; ;; .................... @@ -3901,6 +3959,8 @@ move\\t%0,%z4\\n\\ ;; ;; .................... + + (define_insn "truncdfsf2" [(set (match_operand:SF 0 "register_operand" "=f") (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))] @@ -3909,155 +3969,136 @@ move\\t%0,%z4\\n\\ [(set_attr "type" "fcvt") (set_attr "mode" "SF")]) +;; Integer truncation patterns. Truncating SImode values to smaller +;; modes is a no-op, as it is for most other GCC ports. Truncating +;; DImode values to SImode is not a no-op for TARGET_64BIT since we +;; need to make sure that the lower 32 bits are properly sign-extended +;; (see TRULY_NOOP_TRUNCATION). Truncating DImode values into modes +;; smaller than SImode is equivalent to two separate truncations: +;; +;; A B +;; DI ---> HI == DI ---> SI ---> HI +;; DI ---> QI == DI ---> SI ---> QI +;; +;; Step A needs a real instruction but step B does not. + (define_insn "truncdisi2" - [(set (match_operand:SI 0 "register_operand" "=d") - (truncate:SI (match_operand:DI 1 "se_register_operand" "d")))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,m") + (truncate:SI (match_operand:DI 1 "register_operand" "d,d")))] "TARGET_64BIT" - "* -{ - if (TARGET_MIPS16) - return \"dsll\\t%0,%1,32\;dsra\\t%0,32\"; - return \"dsll\\t%0,%1,32\;dsra\\t%0,%0,32\"; -}" - [(set_attr "type" "darith") - (set_attr "mode" "SI") - (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0)) - (const_int 8) - (const_int 16)))]) + "@ + sll\t%0,%1,0 + sw\t%1,%0" + [(set_attr "type" "darith") + (set_attr "mode" "SI") + (set_attr "extended_mips16" "yes,*")]) (define_insn "truncdihi2" - [(set (match_operand:HI 0 "register_operand" "=d") - (truncate:HI (match_operand:DI 1 "se_register_operand" "d")))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,m") + (truncate:HI (match_operand:DI 1 "register_operand" "d,d")))] "TARGET_64BIT" - "* -{ - if (TARGET_MIPS16) - return \"dsll\\t%0,%1,48\;dsra\\t%0,48\"; - return \"andi\\t%0,%1,0xffff\"; -}" - [(set_attr "type" "darith") - (set_attr "mode" "HI") - (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0)) - (const_int 4) - (const_int 16)))]) + "@ + sll\t%0,%1,0 + sh\t%1,%0" + [(set_attr "type" "darith") + (set_attr "mode" "SI") + (set_attr "extended_mips16" "yes,*")]) + (define_insn "truncdiqi2" - [(set (match_operand:QI 0 "register_operand" "=d") - (truncate:QI (match_operand:DI 1 "se_register_operand" "d")))] + [(set (match_operand:QI 0 "nonimmediate_operand" "=d,m") + (truncate:QI (match_operand:DI 1 "register_operand" "d,d")))] "TARGET_64BIT" - "* -{ - if (TARGET_MIPS16) - return \"dsll\\t%0,%1,56\;dsra\\t%0,56\"; - return \"andi\\t%0,%1,0x00ff\"; -}" - [(set_attr "type" "darith") - (set_attr "mode" "QI") - (set (attr "length") (if_then_else (eq (symbol_ref "mips16") (const_int 0)) - (const_int 4) - (const_int 16)))]) + "@ + sll\t%0,%1,0 + sb\t%1,%0" + [(set_attr "type" "darith") + (set_attr "mode" "SI") + (set_attr "extended_mips16" "yes,*")]) ;; Combiner patterns to optimize shift/truncate combinations. + (define_insn "" [(set (match_operand:SI 0 "register_operand" "=d") - (truncate:SI (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "small_int" "I"))))] - "TARGET_64BIT && !TARGET_MIPS16" - "* -{ - int shift_amt = INTVAL (operands[2]) & 0x3f; - - if (shift_amt < 32) - { - operands[2] = GEN_INT (32 - shift_amt); - return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\"; - } - else - { - operands[2] = GEN_INT (shift_amt); - return \"dsra\\t%0,%1,%2\"; - } -}" - [(set_attr "type" "darith") - (set_attr "mode" "SI") - (set_attr "length" "8")]) + (truncate:SI (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "small_int" "I"))))] + "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) >= 32" + "dsra\\t%0,%1,%2" + [(set_attr "type" "darith") + (set_attr "mode" "SI")]) (define_insn "" [(set (match_operand:SI 0 "register_operand" "=d") - (truncate:SI (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "small_int" "I"))))] + (truncate:SI (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") + (const_int 32))))] "TARGET_64BIT && !TARGET_MIPS16" - "* -{ - int shift_amt = INTVAL (operands[2]) & 0x3f; + "dsra\\t%0,%1,32" + [(set_attr "type" "darith") + (set_attr "mode" "SI")]) - if (shift_amt < 32) - { - operands[2] = GEN_INT (32 - shift_amt); - return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\"; - } - else if (shift_amt == 32) - return \"dsra\\t%0,%1,32\"; - else - { - operands[2] = GEN_INT (shift_amt); - return \"dsrl\\t%0,%1,%2\"; - } -}" - [(set_attr "type" "darith") - (set_attr "mode" "SI") - (set_attr "length" "8")]) -(define_insn "" +;; Combiner patterns for truncate/sign_extend combinations. They use +;; the shift/truncate patterns above. + +(define_insn_and_split "" [(set (match_operand:SI 0 "register_operand" "=d") - (truncate:SI (ashift:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "small_int" "I"))))] - "TARGET_64BIT" - "* -{ - int shift_amt = INTVAL (operands[2]) & 0x3f; + (sign_extend:SI + (truncate:HI (match_operand:DI 1 "register_operand" "d"))))] + "TARGET_64BIT && !TARGET_MIPS16" + "#" + "&& reload_completed" + [(set (match_dup 2) + (ashift:DI (match_dup 1) + (const_int 48))) + (set (match_dup 0) + (truncate:SI (ashiftrt:DI (match_dup 2) + (const_int 48))))] + { operands[2] = gen_lowpart (DImode, operands[0]); }) + +(define_insn_and_split "" + [(set (match_operand:SI 0 "register_operand" "=d") + (sign_extend:SI + (truncate:QI (match_operand:DI 1 "register_operand" "d"))))] + "TARGET_64BIT && !TARGET_MIPS16" + "#" + "&& reload_completed" + [(set (match_dup 2) + (ashift:DI (match_dup 1) + (const_int 56))) + (set (match_dup 0) + (truncate:SI (ashiftrt:DI (match_dup 2) + (const_int 56))))] + { operands[2] = gen_lowpart (DImode, operands[0]); }) - if (shift_amt < 32) - { - operands[2] = GEN_INT (32 + shift_amt); - if (TARGET_MIPS16) - return \"dsll\\t%0,%1,%2\;dsra\\t%0,32\"; - return \"dsll\\t%0,%1,%2\;dsra\\t%0,%0,32\"; - } - else - return \"move\\t%0,%.\"; -}" - [(set_attr "type" "darith") - (set_attr "mode" "SI") - (set_attr "length" "8")]) ;; Combiner patterns to optimize truncate/zero_extend combinations. (define_insn "" [(set (match_operand:SI 0 "register_operand" "=d") - (zero_extend:SI (truncate:HI - (match_operand:DI 1 "se_register_operand" "d"))))] + (zero_extend:SI (truncate:HI + (match_operand:DI 1 "register_operand" "d"))))] "TARGET_64BIT && !TARGET_MIPS16" "andi\\t%0,%1,0xffff" - [(set_attr "type" "darith") - (set_attr "mode" "SI")]) + [(set_attr "type" "darith") + (set_attr "mode" "SI")]) (define_insn "" [(set (match_operand:SI 0 "register_operand" "=d") - (zero_extend:SI (truncate:QI - (match_operand:DI 1 "se_register_operand" "d"))))] + (zero_extend:SI (truncate:QI + (match_operand:DI 1 "register_operand" "d"))))] "TARGET_64BIT && !TARGET_MIPS16" "andi\\t%0,%1,0xff" - [(set_attr "type" "darith") - (set_attr "mode" "SI")]) + [(set_attr "type" "darith") + (set_attr "mode" "SI")]) (define_insn "" [(set (match_operand:HI 0 "register_operand" "=d") - (zero_extend:HI (truncate:QI - (match_operand:DI 1 "se_register_operand" "d"))))] + (zero_extend:HI (truncate:QI + (match_operand:DI 1 "register_operand" "d"))))] "TARGET_64BIT && !TARGET_MIPS16" "andi\\t%0,%1,0xff" - [(set_attr "type" "darith") - (set_attr "mode" "HI")]) + [(set_attr "type" "darith") + (set_attr "mode" "HI")]) + ;; ;; .................... @@ -4069,39 +4110,31 @@ move\\t%0,%z4\\n\\ ;; Extension insns. ;; Those for integer source operand are ordered widest source type first. -(define_expand "zero_extendsidi2" - [(set (match_operand:DI 0 "register_operand" "") - (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))] +(define_insn_and_split "zero_extendsidi2" + [(set (match_operand:DI 0 "register_operand" "=d") + (zero_extend:DI (match_operand:SI 1 "register_operand" "d")))] "TARGET_64BIT" - " -{ - if ((optimize || TARGET_MIPS16) && GET_CODE (operands[1]) == MEM) - operands[1] = force_not_mem (operands[1]); - - if (GET_CODE (operands[1]) != MEM) - { - rtx op1 = gen_lowpart (DImode, operands[1]); - rtx temp = gen_reg_rtx (DImode); - rtx shift = GEN_INT (32); - - emit_insn (gen_ashldi3 (temp, op1, shift)); - emit_insn (gen_lshrdi3 (operands[0], temp, shift)); - DONE; - } -}") + "#" + "&& reload_completed" + [(set (match_dup 0) + (ashift:DI (match_dup 1) (const_int 32))) + (set (match_dup 0) + (lshiftrt:DI (match_dup 0) (const_int 32)))] + "operands[1] = gen_lowpart (DImode, operands[1]);" + [(set_attr "type" "arith") + (set_attr "mode" "DI")]) -(define_insn "zero_extendsidi2_internal" - [(set (match_operand:DI 0 "register_operand" "=d,d") - (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))] +(define_insn "*zero_extendsidi2_mem" + [(set (match_operand:DI 0 "register_operand" "=d") + (zero_extend:DI (match_operand:SI 1 "memory_operand" "m")))] "TARGET_64BIT && !TARGET_MIPS16" - "* return mips_move_1word (operands, insn, TRUE);" - [(set_attr "type" "load") - (set_attr "mode" "DI") - (set_attr "length" "4,8")]) + "lwu\t%0,%1" + [(set_attr "type" "load") + (set_attr "mode" "DI")]) (define_expand "zero_extendhisi2" [(set (match_operand:SI 0 "register_operand" "") - (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] "" " { @@ -4116,32 +4149,27 @@ move\\t%0,%z4\\n\\ }") (define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d,d,d") - (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))] + [(set (match_operand:SI 0 "register_operand" "=d,d") + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))] "!TARGET_MIPS16" - "* -{ - if (which_alternative == 0) - return \"andi\\t%0,%1,0xffff\"; - else - return mips_move_1word (operands, insn, TRUE); -}" - [(set_attr "type" "arith,load,load") - (set_attr "mode" "SI") - (set_attr "length" "4,4,8")]) + "@ + andi\t%0,%1,0xffff + lhu\t%0,%1" + [(set_attr "type" "arith,load") + (set_attr "mode" "SI") + (set_attr "length" "4,*")]) (define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d,d") - (zero_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))] + [(set (match_operand:SI 0 "register_operand" "=d") + (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] "TARGET_MIPS16" - "* return mips_move_1word (operands, insn, TRUE);" - [(set_attr "type" "load,load") - (set_attr "mode" "SI") - (set_attr "length" "4,8")]) + "lhu\t%0,%1" + [(set_attr "type" "load") + (set_attr "mode" "SI")]) (define_expand "zero_extendhidi2" [(set (match_operand:DI 0 "register_operand" "") - (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))] + (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))] "TARGET_64BIT" " { @@ -4156,28 +4184,23 @@ move\\t%0,%z4\\n\\ }") (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=d,d,d") - (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))] + [(set (match_operand:DI 0 "register_operand" "=d,d") + (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))] "TARGET_64BIT && !TARGET_MIPS16" - "* -{ - if (which_alternative == 0) - return \"andi\\t%0,%1,0xffff\"; - else - return mips_move_1word (operands, insn, TRUE); -}" - [(set_attr "type" "arith,load,load") - (set_attr "mode" "DI") - (set_attr "length" "4,4,8")]) + "@ + andi\t%0,%1,0xffff + lhu\t%0,%1" + [(set_attr "type" "arith,load") + (set_attr "mode" "DI") + (set_attr "length" "4,*")]) (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=d,d") - (zero_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))] + [(set (match_operand:DI 0 "register_operand" "=d") + (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))] "TARGET_64BIT && TARGET_MIPS16" - "* return mips_move_1word (operands, insn, TRUE);" - [(set_attr "type" "load,load") - (set_attr "mode" "DI") - (set_attr "length" "4,8")]) + "lhu\t%0,%1" + [(set_attr "type" "load") + (set_attr "mode" "DI")]) (define_expand "zero_extendqihi2" [(set (match_operand:HI 0 "register_operand" "") @@ -4197,28 +4220,23 @@ move\\t%0,%z4\\n\\ }") (define_insn "" - [(set (match_operand:HI 0 "register_operand" "=d,d,d") - (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))] + [(set (match_operand:HI 0 "register_operand" "=d,d") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] "!TARGET_MIPS16" - "* -{ - if (which_alternative == 0) - return \"andi\\t%0,%1,0x00ff\"; - else - return mips_move_1word (operands, insn, TRUE); -}" - [(set_attr "type" "arith,load,load") - (set_attr "mode" "HI") - (set_attr "length" "4,4,8")]) + "@ + andi\t%0,%1,0x00ff + lbu\t%0,%1" + [(set_attr "type" "arith,load") + (set_attr "mode" "HI") + (set_attr "length" "4,*")]) (define_insn "" - [(set (match_operand:HI 0 "register_operand" "=d,d") - (zero_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))] + [(set (match_operand:HI 0 "register_operand" "=d") + (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))] "TARGET_MIPS16" - "* return mips_move_1word (operands, insn, TRUE);" - [(set_attr "type" "load,load") - (set_attr "mode" "HI") - (set_attr "length" "4,8")]) + "lbu\t%0,%1" + [(set_attr "type" "load") + (set_attr "mode" "HI")]) (define_expand "zero_extendqisi2" [(set (match_operand:SI 0 "register_operand" "") @@ -4237,28 +4255,23 @@ move\\t%0,%z4\\n\\ }") (define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d,d,d") - (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))] + [(set (match_operand:SI 0 "register_operand" "=d,d") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] "!TARGET_MIPS16" - "* -{ - if (which_alternative == 0) - return \"andi\\t%0,%1,0x00ff\"; - else - return mips_move_1word (operands, insn, TRUE); -}" - [(set_attr "type" "arith,load,load") - (set_attr "mode" "SI") - (set_attr "length" "4,4,8")]) + "@ + andi\t%0,%1,0x00ff + lbu\t%0,%1" + [(set_attr "type" "arith,load") + (set_attr "mode" "SI") + (set_attr "length" "4,*")]) (define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d,d") - (zero_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))] + [(set (match_operand:SI 0 "register_operand" "=d") + (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))] "TARGET_MIPS16" - "* return mips_move_1word (operands, insn, TRUE);" - [(set_attr "type" "load,load") - (set_attr "mode" "SI") - (set_attr "length" "4,8")]) + "lbu\t%0,%1" + [(set_attr "type" "load") + (set_attr "mode" "SI")]) (define_expand "zero_extendqidi2" [(set (match_operand:DI 0 "register_operand" "") @@ -4277,19 +4290,15 @@ move\\t%0,%z4\\n\\ }") (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=d,d,d") - (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))] + [(set (match_operand:DI 0 "register_operand" "=d,d") + (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] "TARGET_64BIT && !TARGET_MIPS16" - "* -{ - if (which_alternative == 0) - return \"andi\\t%0,%1,0x00ff\"; - else - return mips_move_1word (operands, insn, TRUE); -}" - [(set_attr "type" "arith,load,load") - (set_attr "mode" "DI") - (set_attr "length" "4,4,8")]) + "@ + andi\t%0,%1,0x00ff + lbu\t%0,%1" + [(set_attr "type" "arith,load") + (set_attr "mode" "DI") + (set_attr "length" "4,*")]) ;; These can be created when a paradoxical subreg operand with an implicit ;; sign_extend operator is reloaded. Because of the subreg, this is really @@ -4297,26 +4306,24 @@ move\\t%0,%z4\\n\\ ;; ??? It might be possible to eliminate the need for these patterns by adding ;; more support to reload for implicit sign_extend operators. (define_insn "*paradoxical_extendhidi2" - [(set (match_operand:DI 0 "register_operand" "=d,d") + [(set (match_operand:DI 0 "register_operand" "=d") (sign_extend:DI - (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))] + (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)))] "TARGET_64BIT" "* { return mips_move_1word (operands, insn, TRUE); }" - [(set_attr "type" "load,load") - (set_attr "mode" "DI") - (set_attr "length" "4,8")]) + [(set_attr "type" "load") + (set_attr "mode" "DI")]) (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=d,d") - (zero_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))] + [(set (match_operand:DI 0 "register_operand" "=d") + (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))] "TARGET_64BIT && TARGET_MIPS16" - "* return mips_move_1word (operands, insn, TRUE);" - [(set_attr "type" "load,load") - (set_attr "mode" "DI") - (set_attr "length" "4,8")]) + "lbu\t%0,%1" + [(set_attr "type" "load") + (set_attr "mode" "DI")]) ;; ;; .................... @@ -4328,203 +4335,219 @@ move\\t%0,%z4\\n\\ ;; Extension insns. ;; Those for integer source operand are ordered widest source type first. -;; In 64 bit mode, 32 bit values in general registers are always -;; correctly sign extended. That means that if the target is a -;; general register, we can sign extend from SImode to DImode just by -;; doing a move. The matching define_insns are *movdi_internal2_extend -;; and *movdi_internal2_mips16. - (define_expand "extendsidi2" [(set (match_operand:DI 0 "register_operand" "") - (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))] + (sign_extend:DI (match_operand:SI 1 "move_operand" "")))] "TARGET_64BIT" - "") + " +{ + if (symbolic_operand (operands[1], SImode)) + { + emit_move_insn (operands[0], convert_memory_address (DImode, operands[1])); + DONE; + } + +}") + +(define_insn "*extendsidi2" + [(set (match_operand:DI 0 "register_operand" "=d,d") + (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))] + "TARGET_64BIT" + "@ + sll\t%0,%1,0 + lw\t%0,%1" + [(set_attr "type" "arith,load") + (set_attr "mode" "DI") + (set_attr "extended_mips16" "yes,*")]) ;; These patterns originally accepted general_operands, however, slightly ;; better code is generated by only accepting register_operands, and then ;; letting combine generate the lh and lb insns. +;; These expanders originally put values in registers first. We split +;; all non-mem patterns after reload. + (define_expand "extendhidi2" [(set (match_operand:DI 0 "register_operand" "") - (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))] + (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))] "TARGET_64BIT" - " -{ - if (optimize && GET_CODE (operands[1]) == MEM) - operands[1] = force_not_mem (operands[1]); + "") - if (GET_CODE (operands[1]) != MEM) - { - rtx op1 = gen_lowpart (DImode, operands[1]); - rtx temp = gen_reg_rtx (DImode); - rtx shift = GEN_INT (48); +(define_insn "*extendhidi2" + [(set (match_operand:DI 0 "register_operand" "=d") + (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))] + "TARGET_64BIT" + "#") - emit_insn (gen_ashldi3 (temp, op1, shift)); - emit_insn (gen_ashrdi3 (operands[0], temp, shift)); - DONE; - } -}") +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (sign_extend:DI (match_operand:HI 1 "register_operand" "")))] + "TARGET_64BIT && reload_completed" + [(set (match_dup 0) + (ashift:DI (match_dup 1) (const_int 48))) + (set (match_dup 0) + (ashiftrt:DI (match_dup 0) (const_int 48)))] + "operands[1] = gen_lowpart (DImode, operands[1]);") -(define_insn "extendhidi2_internal" - [(set (match_operand:DI 0 "register_operand" "=d,d") - (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))] +(define_insn "*extendhidi2_mem" + [(set (match_operand:DI 0 "register_operand" "=d") + (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))] "TARGET_64BIT" - "* return mips_move_1word (operands, insn, FALSE);" - [(set_attr "type" "load") - (set_attr "mode" "DI") - (set_attr "length" "4,8")]) + "lh\t%0,%1" + [(set_attr "type" "load") + (set_attr "mode" "DI")]) (define_expand "extendhisi2" [(set (match_operand:SI 0 "register_operand" "") - (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] "" " -{ - if (ISA_HAS_SEB_SEH) - { - emit_insn (gen_extendhisi2_hw (operands[0], - force_reg (HImode, operands[1]))); - DONE; - } + if (ISA_HAS_SEB_SEH) + { + emit_insn (gen_extendhisi2_hw (operands[0], + force_reg (HImode, operands[1]))); + DONE; + } +") - if (optimize && GET_CODE (operands[1]) == MEM) - operands[1] = force_not_mem (operands[1]); +(define_insn "*extendhisi2" + [(set (match_operand:SI 0 "register_operand" "=d") + (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))] + "" + "#") - if (GET_CODE (operands[1]) != MEM) - { - rtx op1 = gen_lowpart (SImode, operands[1]); - rtx temp = gen_reg_rtx (SImode); - rtx shift = GEN_INT (16); +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] + "reload_completed" + [(set (match_dup 0) + (ashift:SI (match_dup 1) (const_int 16))) + (set (match_dup 0) + (ashiftrt:SI (match_dup 0) (const_int 16)))] + "operands[1] = gen_lowpart (SImode, operands[1]);") - emit_insn (gen_ashlsi3 (temp, op1, shift)); - emit_insn (gen_ashrsi3 (operands[0], temp, shift)); - DONE; - } -}") +(define_insn "extendhisi2_mem" + [(set (match_operand:SI 0 "register_operand" "=d") + (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))] + "" + "lh\t%0,%1" + [(set_attr "type" "load") + (set_attr "mode" "SI")]) -(define_insn "extendhisi2_hw" +(define_insn "extendhisi2_hw" [(set (match_operand:SI 0 "register_operand" "=r") - (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))] - "ISA_HAS_SEB_SEH" + (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))] + "ISA_HAS_SEB_SEH" "seh\\t%0,%1" [(set_attr "type" "arith") (set_attr "mode" "SI")]) -(define_insn "extendhisi2_internal" - [(set (match_operand:SI 0 "register_operand" "=d,d") - (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))] - "" - "* return mips_move_1word (operands, insn, FALSE);" - [(set_attr "type" "load") - (set_attr "mode" "SI") - (set_attr "length" "4,8")]) - (define_expand "extendqihi2" [(set (match_operand:HI 0 "register_operand" "") - (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] + (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] "" - " -{ - if (optimize && GET_CODE (operands[1]) == MEM) - operands[1] = force_not_mem (operands[1]); + "") - if (GET_CODE (operands[1]) != MEM) - { - rtx op0 = gen_lowpart (SImode, operands[0]); - rtx op1 = gen_lowpart (SImode, operands[1]); - rtx temp = gen_reg_rtx (SImode); - rtx shift = GEN_INT (24); +(define_insn "*extendqihi2" + [(set (match_operand:HI 0 "register_operand" "=d") + (sign_extend:HI (match_operand:QI 1 "register_operand" "d")))] + "" + "#") - emit_insn (gen_ashlsi3 (temp, op1, shift)); - emit_insn (gen_ashrsi3 (op0, temp, shift)); - DONE; - } -}") +(define_split + [(set (match_operand:HI 0 "register_operand" "") + (sign_extend:HI (match_operand:QI 1 "register_operand" "")))] + "reload_completed" + [(set (match_dup 0) + (ashift:SI (match_dup 1) (const_int 24))) + (set (match_dup 0) + (ashiftrt:SI (match_dup 0) (const_int 24)))] + "operands[0] = gen_lowpart (SImode, operands[0]); + operands[1] = gen_lowpart (SImode, operands[1]);") -(define_insn "extendqihi2_internal" - [(set (match_operand:HI 0 "register_operand" "=d,d") - (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))] +(define_insn "*extendqihi2_internal_mem" + [(set (match_operand:HI 0 "register_operand" "=d") + (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))] "" - "* return mips_move_1word (operands, insn, FALSE);" - [(set_attr "type" "load") - (set_attr "mode" "SI") - (set_attr "length" "4,8")]) + "lb\t%0,%1" + [(set_attr "type" "load") + (set_attr "mode" "SI")]) (define_expand "extendqisi2" [(set (match_operand:SI 0 "register_operand" "") - (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] + (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] "" " -{ - if (ISA_HAS_SEB_SEH) - { - emit_insn (gen_extendqisi2_hw (operands[0], - force_reg (QImode, operands[1]))); - DONE; - } - if (optimize && GET_CODE (operands[1]) == MEM) - operands[1] = force_not_mem (operands[1]); + if (ISA_HAS_SEB_SEH) + { + emit_insn (gen_extendqisi2_hw (operands[0], + force_reg (QImode, operands[1]))); + DONE; + } +") - if (GET_CODE (operands[1]) != MEM) - { - rtx op1 = gen_lowpart (SImode, operands[1]); - rtx temp = gen_reg_rtx (SImode); - rtx shift = GEN_INT (24); +(define_insn "*extendqisi2" + [(set (match_operand:SI 0 "register_operand" "=d") + (sign_extend:SI (match_operand:QI 1 "register_operand" "d")))] + "" + "#") - emit_insn (gen_ashlsi3 (temp, op1, shift)); - emit_insn (gen_ashrsi3 (operands[0], temp, shift)); - DONE; - } -}") +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (sign_extend:SI (match_operand:QI 1 "register_operand" "")))] + "reload_completed" + [(set (match_dup 0) + (ashift:SI (match_dup 1) (const_int 24))) + (set (match_dup 0) + (ashiftrt:SI (match_dup 0) (const_int 24)))] + "operands[1] = gen_lowpart (SImode, operands[1]);") -(define_insn "extendqisi2_hw" +(define_insn "*extendqisi2_mem" + [(set (match_operand:SI 0 "register_operand" "=d") + (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] + "" + "lb\t%0,%1" + [(set_attr "type" "load") + (set_attr "mode" "SI")]) + +(define_insn "extendqisi2_hw" [(set (match_operand:SI 0 "register_operand" "=r") - (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))] - "ISA_HAS_SEB_SEH" + (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))] + "ISA_HAS_SEB_SEH" "seb\\t%0,%1" [(set_attr "type" "arith") (set_attr "mode" "SI")]) -(define_insn "extendqisi2_insn" - [(set (match_operand:SI 0 "register_operand" "=d,d") - (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))] - "" - "* return mips_move_1word (operands, insn, FALSE);" - [(set_attr "type" "load") - (set_attr "mode" "SI") - (set_attr "length" "4,8")]) - (define_expand "extendqidi2" [(set (match_operand:DI 0 "register_operand" "") - (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))] + (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))] "TARGET_64BIT" - " -{ - if (optimize && GET_CODE (operands[1]) == MEM) - operands[1] = force_not_mem (operands[1]); + "") - if (GET_CODE (operands[1]) != MEM) - { - rtx op1 = gen_lowpart (DImode, operands[1]); - rtx temp = gen_reg_rtx (DImode); - rtx shift = GEN_INT (56); +(define_insn "*extendqidi2" + [(set (match_operand:DI 0 "register_operand" "=d") + (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))] + "TARGET_64BIT" + "#") - emit_insn (gen_ashldi3 (temp, op1, shift)); - emit_insn (gen_ashrdi3 (operands[0], temp, shift)); - DONE; - } -}") +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (sign_extend:DI (match_operand:QI 1 "register_operand" "")))] + "TARGET_64BIT && reload_completed" + [(set (match_dup 0) + (ashift:DI (match_dup 1) (const_int 56))) + (set (match_dup 0) + (ashiftrt:DI (match_dup 0) (const_int 56)))] + "operands[1] = gen_lowpart (DImode, operands[1]);") -(define_insn "extendqidi2_insn" - [(set (match_operand:DI 0 "register_operand" "=d,d") - (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))] +(define_insn "*extendqidi2_mem" + [(set (match_operand:DI 0 "register_operand" "=d") + (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))] "TARGET_64BIT" - "* return mips_move_1word (operands, insn, FALSE);" - [(set_attr "type" "load") - (set_attr "mode" "DI") - (set_attr "length" "4,8")]) - + "lb\t%0,%1" + [(set_attr "type" "load") + (set_attr "mode" "DI")]) (define_insn "extendsfdf2" [(set (match_operand:DF 0 "register_operand" "=f") @@ -4868,300 +4891,188 @@ move\\t%0,%z4\\n\\ ;; ;; .................... -;; Bit field extract patterns which use lwl/lwr. +;; Bit field extract patterns which use lwl/lwr or ldl/ldr. -;; ??? There could be HImode variants for the ulh/ulhu/ush macros. -;; It isn't clear whether this will give better code. - -;; Only specify the mode operand 1, the rest are assumed to be word_mode. (define_expand "extv" [(set (match_operand 0 "register_operand" "") (sign_extract (match_operand:QI 1 "memory_operand" "") (match_operand 2 "immediate_operand" "") (match_operand 3 "immediate_operand" "")))] "!TARGET_MIPS16" - " -{ - /* If the field does not start on a byte boundary, then fail. */ - if (INTVAL (operands[3]) % 8 != 0) - FAIL; - - /* MIPS I and MIPS II can only handle a 32bit field. */ - if (!TARGET_64BIT && INTVAL (operands[2]) != 32) - FAIL; - - /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */ - if (TARGET_64BIT - && INTVAL (operands[2]) != 64 - && INTVAL (operands[2]) != 32) - FAIL; - - /* This can happen for a 64 bit target, when extracting a value from - a 64 bit union member. extract_bit_field doesn't verify that our - source matches the predicate, so we force it to be a MEM here. */ - if (GET_CODE (operands[1]) != MEM) - FAIL; - - /* Change the mode to BLKmode for aliasing purposes. */ - operands[1] = adjust_address (operands[1], BLKmode, 0); - set_mem_size (operands[1], GEN_INT (INTVAL (operands[2]) / BITS_PER_UNIT)); - - /* Otherwise, emit a l[wd]l/l[wd]r pair to load the value. */ - if (INTVAL (operands[2]) == 64) - emit_insn (gen_movdi_uld (operands[0], operands[1])); - else - { - if (TARGET_64BIT) - { - operands[0] = gen_lowpart (SImode, operands[0]); - if (operands[0] == NULL_RTX) - FAIL; - } - emit_insn (gen_movsi_ulw (operands[0], operands[1])); - } - DONE; -}") + { + if (mips_expand_unaligned_load (operands[0], operands[1], + INTVAL (operands[2]), + INTVAL (operands[3]))) + DONE; + else + FAIL; + }) -;; Only specify the mode operand 1, the rest are assumed to be word_mode. (define_expand "extzv" [(set (match_operand 0 "register_operand" "") (zero_extract (match_operand:QI 1 "memory_operand" "") (match_operand 2 "immediate_operand" "") (match_operand 3 "immediate_operand" "")))] "!TARGET_MIPS16" - " -{ - /* If the field does not start on a byte boundary, then fail. */ - if (INTVAL (operands[3]) % 8 != 0) - FAIL; - - /* MIPS I and MIPS II can only handle a 32bit field. */ - if (!TARGET_64BIT && INTVAL (operands[2]) != 32) - FAIL; - - /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */ - if (TARGET_64BIT - && INTVAL (operands[2]) != 64 - && INTVAL (operands[2]) != 32) - FAIL; - - /* This can happen for a 64 bit target, when extracting a value from - a 64 bit union member. extract_bit_field doesn't verify that our - source matches the predicate, so we force it to be a MEM here. */ - if (GET_CODE (operands[1]) != MEM) - FAIL; - - /* Change the mode to BLKmode for aliasing purposes. */ - operands[1] = adjust_address (operands[1], BLKmode, 0); - set_mem_size (operands[1], GEN_INT (INTVAL (operands[2]) / BITS_PER_UNIT)); - - /* Otherwise, emit a lwl/lwr pair to load the value. */ - if (INTVAL (operands[2]) == 64) - emit_insn (gen_movdi_uld (operands[0], operands[1])); - else - { - if (TARGET_64BIT) - { - operands[0] = gen_lowpart (SImode, operands[0]); - if (operands[0] == NULL_RTX) - FAIL; - } - emit_insn (gen_movsi_ulw (operands[0], operands[1])); - } - DONE; -}") + { + if (mips_expand_unaligned_load (operands[0], operands[1], + INTVAL (operands[2]), + INTVAL (operands[3]))) + DONE; + else + FAIL; + }) -;; Only specify the mode operands 0, the rest are assumed to be word_mode. (define_expand "insv" [(set (zero_extract (match_operand:QI 0 "memory_operand" "") (match_operand 1 "immediate_operand" "") (match_operand 2 "immediate_operand" "")) - (match_operand 3 "register_operand" ""))] + (match_operand 3 "reg_or_0_operand" ""))] "!TARGET_MIPS16" - " -{ - /* If the field does not start on a byte boundary, then fail. */ - if (INTVAL (operands[2]) % 8 != 0) - FAIL; - - /* MIPS I and MIPS II can only handle a 32bit field. */ - if (!TARGET_64BIT && INTVAL (operands[1]) != 32) - FAIL; - - /* MIPS III and MIPS IV can handle both 32bit and 64bit fields. */ - if (TARGET_64BIT - && INTVAL (operands[1]) != 64 - && INTVAL (operands[1]) != 32) - FAIL; - - /* This can happen for a 64 bit target, when storing into a 32 bit union - member. store_bit_field doesn't verify that our target matches the - predicate, so we force it to be a MEM here. */ - if (GET_CODE (operands[0]) != MEM) - FAIL; - - /* Change the mode to BLKmode for aliasing purposes. */ - operands[0] = adjust_address (operands[0], BLKmode, 0); - set_mem_size (operands[0], GEN_INT (INTVAL (operands[1]) / BITS_PER_UNIT)); - - /* Otherwise, emit a s[wd]l/s[wd]r pair to load the value. */ - if (INTVAL (operands[1]) == 64) - emit_insn (gen_movdi_usd (operands[0], operands[3])); - else - { - if (TARGET_64BIT) - { - operands[3] = gen_lowpart (SImode, operands[3]); - if (operands[3] == NULL_RTX) - FAIL; - } - emit_insn (gen_movsi_usw (operands[0], operands[3])); - } - DONE; -}") + { + if (mips_expand_unaligned_store (operands[0], operands[3], + INTVAL (operands[1]), + INTVAL (operands[2]))) + DONE; + else + FAIL; + }) -;; unaligned word moves generated by the bit field patterns +;; Unaligned word moves generated by the bit field patterns. +;; +;; As far as the rtl is concerned, both the left-part and right-part +;; instructions can access the whole field. However, the real operand +;; refers to just the first or the last byte (depending onendianness). +;; We therefore use two memory operands to each instruction, one to +;; describe the rtl effect and one to use in the assembly output. -(define_insn "movsi_ulw" - [(set (match_operand:SI 0 "register_operand" "=&d,&d") - (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")] - UNSPEC_ULW))] +(define_insn "mov_lwl" + [(set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(match_operand:BLK 1 "general_operand" "m") + (match_operand:QI 2 "general_operand" "m")] + UNSPEC_LWL))] "!TARGET_MIPS16" - "* -{ - rtx offset = const0_rtx; - rtx addr = XEXP (operands[1], 0); - rtx mem_addr = eliminate_constant_term (addr, &offset); - const char *ret; - - if (TARGET_STATS) - mips_count_memory_refs (operands[1], 2); - - /* The stack/frame pointers are always aligned, so we can convert - to the faster lw if we are referencing an aligned stack location. */ - - if ((INTVAL (offset) & 3) == 0 - && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx)) - ret = \"lw\\t%0,%1\"; - else - ret = \"ulw\\t%0,%1\"; - - return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn); -}" - [(set_attr "type" "load,load") - (set_attr "mode" "SI") - (set_attr "length" "8,16")]) + "lwl\t%0,%2" + [(set_attr "type" "load") + (set_attr "mode" "SI")]) -(define_insn "movsi_usw" - [(set (match_operand:BLK 0 "memory_operand" "=R,o") - (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")] - UNSPEC_USW))] +(define_insn "mov_lwr" + [(set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(match_operand:BLK 1 "general_operand" "m") + (match_operand:QI 2 "general_operand" "m") + (match_operand:SI 3 "register_operand" "0")] + UNSPEC_LWR))] "!TARGET_MIPS16" - "* -{ - rtx offset = const0_rtx; - rtx addr = XEXP (operands[0], 0); - rtx mem_addr = eliminate_constant_term (addr, &offset); + "lwr\t%0,%2" + [(set_attr "type" "load") + (set_attr "mode" "SI")]) - if (TARGET_STATS) - mips_count_memory_refs (operands[0], 2); - /* The stack/frame pointers are always aligned, so we can convert - to the faster sw if we are referencing an aligned stack location. */ +(define_insn "mov_swl" + [(set (match_operand:BLK 0 "memory_operand" "=m") + (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ") + (match_operand:QI 2 "general_operand" "m")] + UNSPEC_SWL))] + "!TARGET_MIPS16" + "swl\t%z1,%2" + [(set_attr "type" "store") + (set_attr "mode" "SI")]) - if ((INTVAL (offset) & 3) == 0 - && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx)) - return \"sw\\t%z1,%0\"; +(define_insn "mov_swr" + [(set (match_operand:BLK 0 "memory_operand" "+m") + (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ") + (match_operand:QI 2 "general_operand" "m") + (match_dup 0)] + UNSPEC_SWR))] + "!TARGET_MIPS16" + "swr\t%z1,%2" + [(set_attr "type" "store") + (set_attr "mode" "SI")]) - return \"usw\\t%z1,%0\"; -}" - [(set_attr "type" "store") - (set_attr "mode" "SI") - (set_attr "length" "8,16")]) -;; Bit field extract patterns which use ldl/ldr. +(define_insn "mov_ldl" + [(set (match_operand:DI 0 "register_operand" "=d") + (unspec:DI [(match_operand:BLK 1 "general_operand" "m") + (match_operand:QI 2 "general_operand" "m")] + UNSPEC_LDL))] + "TARGET_64BIT && !TARGET_MIPS16" + "ldl\t%0,%2" + [(set_attr "type" "load") + (set_attr "mode" "DI")]) -;; unaligned double word moves generated by the bit field patterns +(define_insn "mov_ldr" + [(set (match_operand:DI 0 "register_operand" "=d") + (unspec:DI [(match_operand:BLK 1 "general_operand" "m") + (match_operand:QI 2 "general_operand" "m") + (match_operand:DI 3 "register_operand" "0")] + UNSPEC_LDR))] + "TARGET_64BIT && !TARGET_MIPS16" + "ldr\t%0,%2" + [(set_attr "type" "load") + (set_attr "mode" "DI")]) -(define_insn "movdi_uld" - [(set (match_operand:DI 0 "register_operand" "=&d,&d") - (unspec:DI [(match_operand:BLK 1 "general_operand" "R,o")] - UNSPEC_ULD))] - "" - "* -{ - rtx offset = const0_rtx; - rtx addr = XEXP (operands[1], 0); - rtx mem_addr = eliminate_constant_term (addr, &offset); - const char *ret; - if (TARGET_STATS) - mips_count_memory_refs (operands[1], 2); +(define_insn "mov_sdl" + [(set (match_operand:BLK 0 "memory_operand" "=m") + (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ") + (match_operand:QI 2 "general_operand" "m")] + UNSPEC_SDL))] + "TARGET_64BIT && !TARGET_MIPS16" + "sdl\t%z1,%2" + [(set_attr "type" "store") + (set_attr "mode" "DI")]) - /* The stack/frame pointers are always aligned, so we can convert - to the faster lw if we are referencing an aligned stack location. */ +(define_insn "mov_sdr" + [(set (match_operand:BLK 0 "memory_operand" "+m") + (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ") + (match_operand:QI 2 "general_operand" "m") + (match_dup 0)] + UNSPEC_SDR))] + "TARGET_64BIT && !TARGET_MIPS16" + "sdr\t%z1,%2" + [(set_attr "type" "store") + (set_attr "mode" "DI")]) - if ((INTVAL (offset) & 7) == 0 - && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx)) - ret = \"ld\\t%0,%1\"; - else - ret = \"uld\\t%0,%1\"; - return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn); -}" - [(set_attr "type" "load,load") - (set_attr "mode" "SI") - (set_attr "length" "8,16")]) +;; Instructions for loading a relocation expression using "lui". -(define_insn "movdi_usd" - [(set (match_operand:BLK 0 "memory_operand" "=R,o") - (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")] - UNSPEC_USD))] +(define_insn "luisi" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec:SI [(match_operand 1 "const_arith_operand" "")] UNSPEC_HIGH))] "" - "* -{ - rtx offset = const0_rtx; - rtx addr = XEXP (operands[0], 0); - rtx mem_addr = eliminate_constant_term (addr, &offset); - - if (TARGET_STATS) - mips_count_memory_refs (operands[0], 2); - - /* The stack/frame pointers are always aligned, so we can convert - to the faster sw if we are referencing an aligned stack location. */ - - if ((INTVAL (offset) & 7) == 0 - && (mem_addr == stack_pointer_rtx || mem_addr == frame_pointer_rtx)) - return \"sd\\t%z1,%0\"; + "lui\t%0,%1" + [(set_attr "type" "arith")]) - return \"usd\\t%z1,%0\"; -}" - [(set_attr "type" "store") - (set_attr "mode" "SI") - (set_attr "length" "8,16")]) +(define_insn "luidi" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand 1 "const_arith_operand" "")] UNSPEC_HIGH))] + "TARGET_64BIT" + "lui\t%0,%1" + [(set_attr "type" "arith")]) -;; These two patterns support loading addresses with two instructions instead -;; of using the macro instruction la. -;; ??? mips_move_1word has support for HIGH, so this pattern may be -;; unnecessary. +;; Instructions for adding the low 16 bits of an address to a register. +;; Operand 2 is the address: print_operand works out which relocation +;; should be applied. -(define_insn "high" - [(set (match_operand:SI 0 "register_operand" "=r") - (high:SI (match_operand:SI 1 "immediate_operand" "")))] - "mips_split_addresses && !TARGET_MIPS16" - "lui\\t%0,%%hi(%1) # high" - [(set_attr "type" "move")]) - -(define_insn "low" +(define_insn "lowsi" [(set (match_operand:SI 0 "register_operand" "=r") (lo_sum:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "immediate_operand" "")))] - "mips_split_addresses && !TARGET_MIPS16" - "addiu\\t%0,%1,%%lo(%2) # low" + "!TARGET_MIPS16" + "addiu\\t%0,%1,%R2" [(set_attr "type" "arith") (set_attr "mode" "SI")]) +(define_insn "lowdi" + [(set (match_operand:DI 0 "register_operand" "=r") + (lo_sum:DI (match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "immediate_operand" "")))] + "!TARGET_MIPS16 && TARGET_64BIT" + "daddiu\\t%0,%1,%R2" + [(set_attr "type" "arith") + (set_attr "mode" "DI")]) + ;; 64-bit integer moves ;; Unlike most other insns, the move insns can't be split with @@ -5170,21 +5081,12 @@ move\\t%0,%z4\\n\\ (define_expand "movdi" [(set (match_operand:DI 0 "nonimmediate_operand" "") - (match_operand:DI 1 "general_operand" ""))] + (match_operand:DI 1 "" ""))] "" " { - if (mips_split_addresses && mips_check_split (operands[1], DImode)) - { - enum machine_mode mode = GET_MODE (operands[0]); - rtx tem = ((reload_in_progress | reload_completed) - ? operands[0] : gen_reg_rtx (mode)); - - emit_insn (gen_rtx_SET (VOIDmode, tem, - gen_rtx_HIGH (mode, operands[1]))); - - operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]); - } + if (mips_legitimize_move (DImode, operands[0], operands[1])) + DONE; /* If we are generating embedded PIC code, and we are referring to a symbol in the .text section, we must use an offset from the start @@ -5202,73 +5104,6 @@ move\\t%0,%z4\\n\\ emit_move_insn (operands[0], force_reg (DImode, temp)); DONE; } - - /* If operands[1] is a constant address illegal for pic, then we need to - handle it just like LEGITIMIZE_ADDRESS does. */ - if (flag_pic && pic_address_needs_scratch (operands[1])) - { - rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0)); - rtx temp2 = XEXP (XEXP (operands[1], 0), 1); - - if (! SMALL_INT (temp2)) - temp2 = force_reg (DImode, temp2); - - emit_move_insn (operands[0], gen_rtx_PLUS (DImode, temp, temp2)); - DONE; - } - - /* On the mips16, we can handle a GP relative reference by adding in - $gp. We need to check the name to see whether this is a string - constant. */ - if (TARGET_MIPS16 - && register_operand (operands[0], DImode) - && GET_CODE (operands[1]) == SYMBOL_REF - && SYMBOL_REF_FLAG (operands[1])) - { - const char *name = XSTR (operands[1], 0); - - if (name[0] != '*' - || strncmp (name + 1, LOCAL_LABEL_PREFIX, - sizeof LOCAL_LABEL_PREFIX - 1) != 0) - { - rtx base_reg; - - if (reload_in_progress || reload_completed) - { - /* In movsi we use the constant table here. However, in - this case, we're better off copying $28 into a - register and adding, because the constant table entry - would be 8 bytes. */ - base_reg = operands[0]; - emit_move_insn (base_reg, - gen_rtx (CONST, DImode, - gen_rtx (REG, DImode, - GP_REG_FIRST + 28))); - } - else - { - base_reg = gen_reg_rtx (Pmode); - emit_move_insn (base_reg, mips16_gp_pseudo_reg ()); - } - - emit_move_insn (operands[0], - gen_rtx (PLUS, Pmode, base_reg, - mips16_gp_offset (operands[1]))); - DONE; - } - } - - if ((reload_in_progress | reload_completed) == 0 - && !register_operand (operands[0], DImode) - && !register_operand (operands[1], DImode) - && (TARGET_MIPS16 - || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0) - && operands[1] != CONST0_RTX (DImode)))) - { - rtx temp = force_reg (DImode, operands[1]); - emit_move_insn (operands[0], temp); - DONE; - } }") ;; For mips16, we need a special case to handle storing $31 into @@ -5276,7 +5111,7 @@ move\\t%0,%z4\\n\\ ;; instruction can be generated by save_restore_insns. (define_insn "" - [(set (match_operand:DI 0 "memory_operand" "=R,m") + [(set (match_operand:DI 0 "memory_operand" "=m") (reg:DI 31))] "TARGET_MIPS16 && TARGET_64BIT" "* @@ -5285,32 +5120,31 @@ move\\t%0,%z4\\n\\ return mips_move_2words (operands, insn); }" [(set_attr "type" "store") - (set_attr "mode" "DI") - (set_attr "length" "4,8")]) + (set_attr "mode" "DI")]) (define_insn "movdi_internal" - [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R") - (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*x,*B*C*D,*B*C*D,*d,*m") + (match_operand:DI 1 "general_operand" "d,iF,m,d,J,*x,*d,*d,*m,*B*C*D,*B*C*D"))] "!TARGET_64BIT && !TARGET_MIPS16 && (register_operand (operands[0], DImode) || register_operand (operands[1], DImode) || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0) || operands[1] == CONST0_RTX (DImode))" "* return mips_move_2words (operands, insn); " - [(set_attr "type" "move,arith,load,load,store,store,hilo,hilo,hilo,xfer,load,load,xfer,store,store") + [(set_attr "type" "move,arith,load,store,hilo,hilo,hilo,xfer,load,xfer,store") (set_attr "mode" "DI") - (set_attr "length" "8,16,8,16,8,16,8,8,8,8,8,8,8,8,8")]) + (set_attr "length" "8,16,*,*,8,8,8,8,*,8,*")]) (define_insn "" - [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,To,*d") - (match_operand:DI 1 "general_operand" "d,d,y,K,N,R,To,d,d,*x"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d") + (match_operand:DI 1 "general_operand" "d,d,y,K,N,m,d,*x"))] "!TARGET_64BIT && TARGET_MIPS16 && (register_operand (operands[0], DImode) || register_operand (operands[1], DImode))" "* return mips_move_2words (operands, insn);" - [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo") + [(set_attr "type" "move,move,move,arith,arith,load,store,hilo") (set_attr "mode" "DI") - (set_attr "length" "8,8,8,8,12,8,16,8,16,8")]) + (set_attr "length" "8,8,8,8,12,*,*,8")]) (define_split [(set (match_operand:DI 0 "register_operand" "") @@ -5325,17 +5159,17 @@ move\\t%0,%z4\\n\\ "") (define_insn "movdi_internal2" - [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,m,*f,*f,*f,*f,*d,*R,*m,*x,*d,*x,*a,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R") - (match_operand:DI 1 "move_operand" "d,IKL,Mnis,R,m,dJ,dJ,*f,*d*J,*R,*m,*f,*f,*f,*J,*x,*d,*J,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*x,*d,*x,*a,*B*C*D,*B*C*D,*d,*m") + (match_operand:DI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*J,*x,*d,*J,*d,*m,*B*C*D,*B*C*D"))] "TARGET_64BIT && !TARGET_MIPS16 && (register_operand (operands[0], DImode) || register_operand (operands[1], DImode) || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0) || operands[1] == CONST0_RTX (DImode))" "* return mips_move_2words (operands, insn); " - [(set_attr "type" "move,arith,arith,load,load,store,store,move,xfer,load,load,xfer,store,store,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store") + [(set_attr "type" "move,const,const,load,store,move,xfer,load,xfer,store,hilo,hilo,hilo,hilo,xfer,load,xfer,store") (set_attr "mode" "DI") - (set_attr "length" "4,4,8,4,8,4,8,4,4,4,8,4,4,8,4,4,4,8,8,8,8,8,8,8")]) + (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,8,8,*,8,*")]) ;; Sign-extended operands are reloaded using this instruction, so the ;; constraints must handle every SImode source operand X and destination @@ -5349,27 +5183,15 @@ move\\t%0,%z4\\n\\ ;; This pattern is essentially a trimmed-down version of movdi_internal2. ;; The main difference is that dJ -> f and f -> d are the only constraints ;; involving float registers. See mips_secondary_reload_class for details. -(define_insn "*movdi_internal2_extend" - [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,m,*d,*f,*x,*d,*x,*a,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R") - (sign_extend:DI (match_operand:SI 1 "move_operand" "d,IKL,Mnis,R,m,dJ,dJ,*f,*d*J,*J,*x,*d,*J,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D")))] - "TARGET_64BIT && !TARGET_MIPS16 - && (register_operand (operands[0], DImode) - || register_operand (operands[1], DImode) - || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0) - || operands[1] == CONST0_RTX (DImode))" - "* return mips_sign_extend (insn, operands[0], operands[1]);" - [(set_attr "type" "move,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store") - (set_attr "mode" "DI") - (set_attr "length" "4,4,8,4,8,4,8,4,4,4,4,4,8,8,8,8,8,8,8")]) (define_insn "*movdi_internal2_mips16" - [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d") - (match_operand:DI 1 "movdi_operand" "d,d,y,K,N,s,R,m,d,d,*x"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d") + (match_operand:DI 1 "move_operand" "d,d,y,K,N,U,m,d,*x"))] "TARGET_64BIT && TARGET_MIPS16 && (register_operand (operands[0], DImode) - || se_register_operand (operands[1], DImode))" + || register_operand (operands[1], DImode))" "* return mips_move_2words (operands, insn);" - [(set_attr "type" "move,move,move,arith,arith,arith,load,load,store,store,hilo") + [(set_attr "type" "move,move,move,arith,arith,const,load,store,hilo") (set_attr "mode" "DI") (set_attr_alternative "length" [(const_int 4) @@ -5381,15 +5203,12 @@ move\\t%0,%z4\\n\\ (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "") (const_int 8) (const_int 12)) - (if_then_else (match_operand:VOID 1 "m16_usym5_4" "") - (const_int 4) - (const_int 8)) - (const_int 4) - (const_int 8) - (const_int 4) - (const_int 8) + (const_string "*") + (const_string "*") + (const_string "*") (const_int 4)])]) + ;; On the mips16, we can split ld $r,N($r) into an add and a load, ;; when the original load is a 4 byte instruction but the add and the ;; load are 2 2 byte instructions. @@ -5518,7 +5337,7 @@ move\\t%0,%z4\\n\\ (define_expand "reload_outdi" [(set (match_operand:DI 0 "general_operand" "=b") - (match_operand:DI 1 "se_register_operand" "b")) + (match_operand:DI 1 "register_operand" "b")) (clobber (match_operand:TI 2 "register_operand" "=&d"))] "TARGET_64BIT" " @@ -5598,44 +5417,18 @@ move\\t%0,%z4\\n\\ ;; 32-bit Integer moves -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "large_int" ""))] - "!TARGET_DEBUG_D_MODE && !TARGET_MIPS16" - [(set (match_dup 0) - (match_dup 2)) - (set (match_dup 0) - (ior:SI (match_dup 0) - (match_dup 3)))] - " -{ - operands[2] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1]) - & BITMASK_UPPER16, - SImode)); - operands[3] = GEN_INT (INTVAL (operands[1]) & BITMASK_LOWER16); -}") - ;; Unlike most other insns, the move insns can't be split with ;; different predicates, because register spilling and other parts of ;; the compiler, have memoized the insn number already. (define_expand "movsi" [(set (match_operand:SI 0 "nonimmediate_operand" "") - (match_operand:SI 1 "general_operand" ""))] + (match_operand:SI 1 "" ""))] "" " { - if (mips_split_addresses && mips_check_split (operands[1], SImode)) - { - enum machine_mode mode = GET_MODE (operands[0]); - rtx tem = ((reload_in_progress | reload_completed) - ? operands[0] : gen_reg_rtx (mode)); - - emit_insn (gen_rtx_SET (VOIDmode, tem, - gen_rtx_HIGH (mode, operands[1]))); - - operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]); - } + if (mips_legitimize_move (SImode, operands[0], operands[1])) + DONE; /* If we are generating embedded PIC code, and we are referring to a symbol in the .text section, we must use an offset from the start @@ -5653,73 +5446,6 @@ move\\t%0,%z4\\n\\ emit_move_insn (operands[0], force_reg (SImode, temp)); DONE; } - - /* If operands[1] is a constant address invalid for pic, then we need to - handle it just like LEGITIMIZE_ADDRESS does. */ - if (flag_pic && pic_address_needs_scratch (operands[1])) - { - rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0)); - rtx temp2 = XEXP (XEXP (operands[1], 0), 1); - - if (! SMALL_INT (temp2)) - temp2 = force_reg (SImode, temp2); - - emit_move_insn (operands[0], gen_rtx_PLUS (SImode, temp, temp2)); - DONE; - } - - /* On the mips16, we can handle a GP relative reference by adding in - $gp. We need to check the name to see whether this is a string - constant. */ - if (TARGET_MIPS16 - && register_operand (operands[0], SImode) - && GET_CODE (operands[1]) == SYMBOL_REF - && SYMBOL_REF_FLAG (operands[1])) - { - const char *name = XSTR (operands[1], 0); - - if (name[0] != '*' - || strncmp (name + 1, LOCAL_LABEL_PREFIX, - sizeof LOCAL_LABEL_PREFIX - 1) != 0) - { - rtx base_reg; - - if (reload_in_progress || reload_completed) - { - /* We need to reload this address. In this case we - aren't going to have a chance to combine loading the - address with the load or store. That means that we - can either generate a 2 byte move followed by a 4 - byte addition, or a 2 byte load with a 4 byte entry - in the constant table. Since the entry in the - constant table might be shared, we're better off, on - average, loading the address from the constant table. */ - emit_move_insn (operands[0], - force_const_mem (SImode, operands[1])); - DONE; - } - - base_reg = gen_reg_rtx (Pmode); - emit_move_insn (base_reg, mips16_gp_pseudo_reg ()); - - emit_move_insn (operands[0], - gen_rtx (PLUS, Pmode, base_reg, - mips16_gp_offset (operands[1]))); - DONE; - } - } - - if ((reload_in_progress | reload_completed) == 0 - && !register_operand (operands[0], SImode) - && !register_operand (operands[1], SImode) - && (TARGET_MIPS16 - || GET_CODE (operands[1]) != CONST_INT - || INTVAL (operands[1]) != 0)) - { - rtx temp = force_reg (SImode, operands[1]); - emit_move_insn (operands[0], temp); - DONE; - } }") ;; We can only store $ra directly into a small sp offset. Should the @@ -5746,40 +5472,25 @@ move\\t%0,%z4\\n\\ ;; in FP registers (off by default, use -mdebugh to enable). (define_insn "movsi_internal" - [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,R,m,*f,*f,*f,?*f,*d,*R,*m,*d,*z,*x,*d,*x,*d,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R") - (match_operand:SI 1 "move_operand" "d,IKL,Mnis,R,m,dJ,dJ,*f,*d*J,*R,*m,*f,*f,*f,*z,*d,J,*x,*d,*a,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,e,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*d,*x,*d,*B*C*D,*B*C*D,*d,*m") + (match_operand:SI 1 "move_operand" "d,U,T,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,J,*x,*d,*a,*d,*m,*B*C*D,*B*C*D"))] "!TARGET_MIPS16 && (register_operand (operands[0], SImode) || register_operand (operands[1], SImode) || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))" "* return mips_move_1word (operands, insn, FALSE);" - [(set_attr "type" "move,arith,arith,load,load,store,store,move,xfer,load,load,xfer,store,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store") + [(set_attr "type" "move,const,const,load,store,move,xfer,load,xfer,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,xfer,store") (set_attr "mode" "SI") - (set_attr "length" "4,4,8,4,8,4,8,4,4,4,8,4,4,8,4,4,4,4,4,4,4,4,8,4,4,8")]) - -;; This is the mips16 movsi instruction. We accept a small integer as -;; the source if the destination is a GP memory reference. This is -;; because we want the combine pass to turn adding a GP reference to a -;; register into a direct GP reference, but the combine pass will pass -;; in the source as a constant if it finds an equivalent one. If the -;; instruction is recognized, reload will force the constant back out -;; into a register. + (set_attr "length" "4,*,*,*,*,4,4,*,4,*,4,4,4,4,4,4,4,*,4,*")]) (define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d,*d") - (match_operand:SI 1 "move_operand" "d,d,y,K,N,s,R,m,d,d,*x,*a"))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d,*d") + (match_operand:SI 1 "move_operand" "d,d,y,K,N,U,m,d,*x,*a"))] "TARGET_MIPS16 && (register_operand (operands[0], SImode) - || register_operand (operands[1], SImode) - || (GET_CODE (operands[0]) == MEM - && GET_CODE (XEXP (operands[0], 0)) == PLUS - && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST - && mips16_gp_offset_p (XEXP (XEXP (operands[0], 0), 1)) - && GET_CODE (operands[1]) == CONST_INT - && (SMALL_INT (operands[1]) - || SMALL_INT_UNSIGNED (operands[1]))))" + || register_operand (operands[1], SImode))" "* return mips_move_1word (operands, insn, FALSE);" - [(set_attr "type" "move,move,move,arith,arith,arith,load,load,store,store,hilo,hilo") + [(set_attr "type" "move,move,move,arith,arith,const,load,store,hilo,hilo") (set_attr "mode" "SI") (set_attr_alternative "length" [(const_int 4) @@ -5791,13 +5502,9 @@ move\\t%0,%z4\\n\\ (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "") (const_int 8) (const_int 12)) - (if_then_else (match_operand:VOID 1 "m16_usym8_4" "") - (const_int 4) - (const_int 8)) - (const_int 4) - (const_int 8) - (const_int 4) - (const_int 8) + (const_string "*") + (const_string "*") + (const_string "*") (const_int 4) (const_int 4)])]) @@ -6043,13 +5750,13 @@ move\\t%0,%z4\\n\\ ;; between the general registers and the floating point registers. (define_insn "movcc" - [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m") - (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))] + [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m") + (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))] "ISA_HAS_8CC && TARGET_HARD_FLOAT" "* return mips_move_1word (operands, insn, FALSE);" - [(set_attr "type" "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store") + [(set_attr "type" "move,move,load,store,xfer,xfer,move,load,store") (set_attr "mode" "SI") - (set_attr "length" "8,4,4,8,4,8,4,4,4,4,8,4,8")]) + (set_attr "length" "8,4,*,*,4,4,4,*,*")]) ;; Reload condition code registers. reload_incc and reload_outcc ;; both handle moves from arbitrary operands into condition code @@ -6107,16 +5814,18 @@ move\\t%0,%z4\\n\\ "ISA_HAS_FP4 && TARGET_HARD_FLOAT" "lwxc1\\t%0,%1(%2)" [(set_attr "type" "load") - (set_attr "mode" "SF")]) + (set_attr "mode" "SF") + (set_attr "length" "4")]) (define_insn "" [(set (match_operand:SF 0 "register_operand" "=f") - (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d"))))] + (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d"))))] "ISA_HAS_FP4 && TARGET_HARD_FLOAT" "lwxc1\\t%0,%1(%2)" [(set_attr "type" "load") - (set_attr "mode" "SF")]) + (set_attr "mode" "SF") + (set_attr "length" "4")]) (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") @@ -6125,16 +5834,18 @@ move\\t%0,%z4\\n\\ "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" "ldxc1\\t%0,%1(%2)" [(set_attr "type" "load") - (set_attr "mode" "DF")]) + (set_attr "mode" "DF") + (set_attr "length" "4")]) (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") - (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d"))))] + (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d"))))] "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" "ldxc1\\t%0,%1(%2)" [(set_attr "type" "load") - (set_attr "mode" "DF")]) + (set_attr "mode" "DF") + (set_attr "length" "4")]) (define_insn "" [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d") @@ -6143,16 +5854,18 @@ move\\t%0,%z4\\n\\ "ISA_HAS_FP4 && TARGET_HARD_FLOAT" "swxc1\\t%0,%1(%2)" [(set_attr "type" "store") - (set_attr "mode" "SF")]) + (set_attr "mode" "SF") + (set_attr "length" "4")]) (define_insn "" - [(set (mem:SF (plus:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d"))) + [(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d"))) (match_operand:SF 0 "register_operand" "f"))] "ISA_HAS_FP4 && TARGET_HARD_FLOAT" "swxc1\\t%0,%1(%2)" [(set_attr "type" "store") - (set_attr "mode" "SF")]) + (set_attr "mode" "SF") + (set_attr "length" "4")]) (define_insn "" [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d") @@ -6161,16 +5874,18 @@ move\\t%0,%z4\\n\\ "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" "sdxc1\\t%0,%1(%2)" [(set_attr "type" "store") - (set_attr "mode" "DF")]) + (set_attr "mode" "DF") + (set_attr "length" "4")]) (define_insn "" - [(set (mem:DF (plus:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d"))) + [(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d"))) (match_operand:DF 0 "register_operand" "f"))] "ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" "sdxc1\\t%0,%1(%2)" [(set_attr "type" "store") - (set_attr "mode" "DF")]) + (set_attr "mode" "DF") + (set_attr "length" "4")]) ;; 16-bit Integer moves @@ -6202,25 +5917,25 @@ move\\t%0,%z4\\n\\ ;; in FP registers (off by default, use -mdebugh to enable). (define_insn "movhi_internal" - [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d") - (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f*z,*f,*x,*d") + (match_operand:HI 1 "general_operand" "d,IK,m,dJ,*f*z,*d,*f,*d,*x"))] "!TARGET_MIPS16 && (register_operand (operands[0], HImode) || register_operand (operands[1], HImode) || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))" "* return mips_move_1word (operands, insn, TRUE);" - [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo") + [(set_attr "type" "move,arith,load,store,xfer,xfer,move,hilo,hilo") (set_attr "mode" "HI") - (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")]) + (set_attr "length" "4,4,*,*,4,4,4,4,4")]) (define_insn "" - [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d") - (match_operand:HI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d") + (match_operand:HI 1 "general_operand" "d,d,y,K,N,m,d,*x"))] "TARGET_MIPS16 && (register_operand (operands[0], HImode) || register_operand (operands[1], HImode))" "* return mips_move_1word (operands, insn, TRUE);" - [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo") + [(set_attr "type" "move,move,move,arith,arith,load,store,hilo") (set_attr "mode" "HI") (set_attr_alternative "length" [(const_int 4) @@ -6232,10 +5947,8 @@ move\\t%0,%z4\\n\\ (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "") (const_int 8) (const_int 12)) - (const_int 4) - (const_int 8) - (const_int 4) - (const_int 8) + (const_string "*") + (const_string "*") (const_int 4)])]) @@ -6312,25 +6025,25 @@ move\\t%0,%z4\\n\\ ;; in FP registers (off by default, use -mdebugh to enable). (define_insn "movqi_internal" - [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d") - (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))] + [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f*z,*f,*x,*d") + (match_operand:QI 1 "general_operand" "d,IK,m,dJ,*f*z,*d,*f,*d,*x"))] "!TARGET_MIPS16 && (register_operand (operands[0], QImode) || register_operand (operands[1], QImode) || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))" "* return mips_move_1word (operands, insn, TRUE);" - [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo") + [(set_attr "type" "move,arith,load,store,xfer,xfer,move,hilo,hilo") (set_attr "mode" "QI") - (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")]) + (set_attr "length" "4,4,*,*,4,4,4,4,4")]) (define_insn "" - [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d") - (match_operand:QI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))] + [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d") + (match_operand:QI 1 "general_operand" "d,d,y,K,N,m,d,*x"))] "TARGET_MIPS16 && (register_operand (operands[0], QImode) || register_operand (operands[1], QImode))" "* return mips_move_1word (operands, insn, TRUE);" - [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo") + [(set_attr "type" "move,move,move,arith,arith,load,store,hilo") (set_attr "mode" "QI") (set_attr_alternative "length" [(const_int 4) @@ -6342,10 +6055,8 @@ move\\t%0,%z4\\n\\ (if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "") (const_int 8) (const_int 12)) - (const_int 4) - (const_int 8) - (const_int 4) - (const_int 8) + (const_string "*") + (const_string "*") (const_int 4)])]) @@ -6395,37 +6106,37 @@ move\\t%0,%z4\\n\\ }") (define_insn "movsf_internal1" - [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m") - (match_operand:SF 1 "general_operand" "f,G,R,m,fG,fG,*d,*f,*G*d,*R,*m,*d,*d"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m") + (match_operand:SF 1 "general_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))] "TARGET_HARD_FLOAT && (register_operand (operands[0], SFmode) || nonmemory_operand (operands[1], SFmode))" "* return mips_move_1word (operands, insn, FALSE);" - [(set_attr "type" "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store") + [(set_attr "type" "move,xfer,load,store,xfer,xfer,move,load,store") (set_attr "mode" "SF") - (set_attr "length" "4,4,4,8,4,8,4,4,4,4,8,4,8")]) + (set_attr "length" "4,4,*,*,4,4,4,*,*")]) (define_insn "movsf_internal2" - [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m") - (match_operand:SF 1 "general_operand" " Gd,R,m,d,d"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m") + (match_operand:SF 1 "general_operand" " Gd,m,d"))] "TARGET_SOFT_FLOAT && !TARGET_MIPS16 && (register_operand (operands[0], SFmode) || nonmemory_operand (operands[1], SFmode))" "* return mips_move_1word (operands, insn, FALSE);" - [(set_attr "type" "move,load,load,store,store") + [(set_attr "type" "move,load,store") (set_attr "mode" "SF") - (set_attr "length" "4,4,8,4,8")]) + (set_attr "length" "4,*,*")]) (define_insn "" - [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,d,R,m") - (match_operand:SF 1 "nonimmediate_operand" "d,d,y,R,m,d,d"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m") + (match_operand:SF 1 "nonimmediate_operand" "d,d,y,m,d"))] "TARGET_MIPS16 && (register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode))" "* return mips_move_1word (operands, insn, FALSE);" - [(set_attr "type" "move,move,move,load,load,store,store") + [(set_attr "type" "move,move,move,load,store") (set_attr "mode" "SF") - (set_attr "length" "4,4,4,4,8,4,8")]) + (set_attr "length" "4,4,4,*,*")]) ;; 64-bit floating point moves @@ -6442,51 +6153,49 @@ move\\t%0,%z4\\n\\ operands[1] = force_reg (DFmode, operands[1]); }") -(define_insn "movdf_internal1" - [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,f,R,To,*f,*d,*d,*d,*d,*R,*T") - (match_operand:DF 1 "general_operand" "f,G,R,To,fG,fG,*d,*f,*d*G,*R,*T,*d,*d"))] - "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT) - && TARGET_DOUBLE_FLOAT +(define_insn "movdf_internal1a" + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m") + (match_operand:DF 1 "general_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))] + "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT && (register_operand (operands[0], DFmode) || nonmemory_operand (operands[1], DFmode))" "* return mips_move_2words (operands, insn); " - [(set_attr "type" "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store") - (set_attr "mode" "DF") - (set_attr "length" "4,8,8,16,8,16,8,8,8,8,16,8,16")]) + [(set_attr "type" "move,move,load,store,xfer,xfer,move,load,store") + (set_attr "mode" "DF") + (set_attr "length" "4,8,*,*,4,4,4,*,*")]) -(define_insn "movdf_internal1a" - [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,To,To,*d,*d,*To,*R,*d") - (match_operand:DF 1 "general_operand" " f,To,f,G,f,G,*To,*R,*d,*d,*d"))] - "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT) - && TARGET_DOUBLE_FLOAT +(define_insn "movdf_internal1b" + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m") + (match_operand:DF 1 "general_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))] + "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT && (register_operand (operands[0], DFmode) || nonmemory_operand (operands[1], DFmode))" "* return mips_move_2words (operands, insn); " - [(set_attr "type" "move,load,store,store,store,store,load,load,store,store,move") + [(set_attr "type" "move,move,load,store,xfer,xfer,move,load,store") (set_attr "mode" "DF") - (set_attr "length" "4,8,4,4,8,8,8,4,8,4,4")]) + (set_attr "length" "4,8,*,*,8,8,8,*,*")]) (define_insn "movdf_internal2" - [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,To,d,f,f") - (match_operand:DF 1 "general_operand" "dG,R,To,d,d,f,d,f"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f") + (match_operand:DF 1 "general_operand" "dG,m,d,f,d,f"))] "(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16 && (register_operand (operands[0], DFmode) || nonmemory_operand (operands[1], DFmode))" "* return mips_move_2words (operands, insn); " - [(set_attr "type" "move,load,load,store,store,xfer,load,move") + [(set_attr "type" "move,load,store,xfer,xfer,move") (set_attr "mode" "DF") - (set_attr "length" "8,8,16,8,16,8,8,4")]) + (set_attr "length" "8,*,*,8,8,4")]) (define_insn "" - [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,d,R,To") - (match_operand:DF 1 "nonimmediate_operand" "d,d,y,R,To,d,d"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m") + (match_operand:DF 1 "nonimmediate_operand" "d,d,y,m,d"))] "TARGET_MIPS16 && (register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode))" "* return mips_move_2words (operands, insn);" - [(set_attr "type" "move,move,move,load,load,store,store") + [(set_attr "type" "move,move,move,load,store") (set_attr "mode" "DF") - (set_attr "length" "8,8,8,8,16,8,16")]) + (set_attr "length" "8,8,8,*,*")]) (define_split [(set (match_operand:DF 0 "register_operand" "") @@ -6505,12 +6214,12 @@ move\\t%0,%z4\\n\\ (define_insn "loadgp" [(set (reg:DI 28) - (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "") + (unspec_volatile:DI [(match_operand 0 "immediate_operand" "") (match_operand:DI 1 "register_operand" "")] UNSPEC_LOADGP)) (clobber (reg:DI 1))] "" - "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%a0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%a0)))\\n\\tdaddu\\t$gp,$1,%1%]" + "%[lui\\t$1,%%hi(%%neg(%%gp_rel(%0)))\\n\\taddiu\\t$1,$1,%%lo(%%neg(%%gp_rel(%0)))\\n\\tdaddu\\t$gp,$1,%1%]" [(set_attr "type" "move") (set_attr "mode" "DI") (set_attr "length" "12")]) @@ -6656,8 +6365,8 @@ move\\t%0,%z4\\n\\ (set_attr "length" "80")]) (define_insn "movstrsi_internal3" - [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination - (match_operand:BLK 1 "memory_operand" "Ro")) ;; source + [(set (match_operand:BLK 0 "memory_operand" "=m") ;; destination + (match_operand:BLK 1 "memory_operand" "m")) ;; source (clobber (match_scratch:SI 4 "=&d")) ;; temp 1 (clobber (match_scratch:SI 5 "=&d")) ;; temp 2 (clobber (match_scratch:SI 6 "=&d")) ;; temp 3 @@ -6726,6 +6435,22 @@ move\\t%0,%z4\\n\\ [(set_attr "type" "arith") (set_attr "mode" "SI")]) +(define_insn "ashlsi3_internal1_extend" + [(set (match_operand:DI 0 "register_operand" "=d") + (sign_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "d") + (match_operand:SI 2 "arith_operand" "dI"))))] + "TARGET_64BIT && !TARGET_MIPS16" + "* +{ + if (GET_CODE (operands[2]) == CONST_INT) + operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); + + return \"sll\\t%0,%1,%2\"; +}" + [(set_attr "type" "arith") + (set_attr "mode" "DI")]) + + (define_insn "ashlsi3_internal2" [(set (match_operand:SI 0 "register_operand" "=d,d") (ashift:SI (match_operand:SI 1 "register_operand" "0,d") @@ -6768,7 +6493,7 @@ move\\t%0,%z4\\n\\ (define_expand "ashldi3" [(parallel [(set (match_operand:DI 0 "register_operand" "") - (ashift:DI (match_operand:DI 1 "se_register_operand" "") + (ashift:DI (match_operand:DI 1 "register_operand" "") (match_operand:SI 2 "arith_operand" ""))) (clobber (match_dup 3))])] "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)" @@ -6989,7 +6714,7 @@ move\\t%0,%z4\\n\\ (define_insn "ashldi3_internal4" [(set (match_operand:DI 0 "register_operand" "=d") - (ashift:DI (match_operand:DI 1 "se_register_operand" "d") + (ashift:DI (match_operand:DI 1 "register_operand" "d") (match_operand:SI 2 "arith_operand" "dI")))] "TARGET_64BIT && !TARGET_MIPS16" "* @@ -7004,7 +6729,7 @@ move\\t%0,%z4\\n\\ (define_insn "" [(set (match_operand:DI 0 "register_operand" "=d,d") - (ashift:DI (match_operand:DI 1 "se_register_operand" "0,d") + (ashift:DI (match_operand:DI 1 "register_operand" "0,d") (match_operand:SI 2 "arith_operand" "d,I")))] "TARGET_64BIT && TARGET_MIPS16" "* @@ -7129,7 +6854,7 @@ move\\t%0,%z4\\n\\ (define_expand "ashrdi3" [(parallel [(set (match_operand:DI 0 "register_operand" "") - (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "") + (ashiftrt:DI (match_operand:DI 1 "register_operand" "") (match_operand:SI 2 "arith_operand" ""))) (clobber (match_dup 3))])] "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)" @@ -7343,7 +7068,7 @@ move\\t%0,%z4\\n\\ (define_insn "ashrdi3_internal4" [(set (match_operand:DI 0 "register_operand" "=d") - (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "d") + (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") (match_operand:SI 2 "arith_operand" "dI")))] "TARGET_64BIT && !TARGET_MIPS16" "* @@ -7358,7 +7083,7 @@ move\\t%0,%z4\\n\\ (define_insn "" [(set (match_operand:DI 0 "register_operand" "=d,d") - (ashiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0") + (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0") (match_operand:SI 2 "arith_operand" "d,I")))] "TARGET_64BIT && TARGET_MIPS16" "* @@ -7484,19 +7209,17 @@ move\\t%0,%z4\\n\\ ;; not have and immediate). We recognize a shift of a load in order ;; to make it simple enough for combine to understand. +;; ??? FIXME: turn into a define_insn_and_split (define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d,d") - (lshiftrt:SI (match_operand:SI 1 "memory_operand" "R,m") - (match_operand:SI 2 "immediate_operand" "I,I")))] - "TARGET_MIPS16" + [(set (match_operand:SI 0 "register_operand" "=d") + (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m") + (match_operand:SI 2 "immediate_operand" "I")))] + "0 && TARGET_MIPS16" "lw\\t%0,%1\;srl\\t%0,%2" [(set_attr "type" "load") (set_attr "mode" "SI") (set_attr_alternative "length" [(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "") - (const_int 8) - (const_int 12)) - (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "") (const_int 12) (const_int 16))])]) @@ -7511,7 +7234,7 @@ move\\t%0,%z4\\n\\ (define_expand "lshrdi3" [(parallel [(set (match_operand:DI 0 "register_operand" "") - (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "") + (lshiftrt:DI (match_operand:DI 1 "register_operand" "") (match_operand:SI 2 "arith_operand" ""))) (clobber (match_dup 3))])] "TARGET_64BIT || (!TARGET_DEBUG_G_MODE && !TARGET_MIPS16)" @@ -7727,7 +7450,7 @@ move\\t%0,%z4\\n\\ (define_insn "lshrdi3_internal4" [(set (match_operand:DI 0 "register_operand" "=d") - (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "d") + (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") (match_operand:SI 2 "arith_operand" "dI")))] "TARGET_64BIT && !TARGET_MIPS16" "* @@ -7742,7 +7465,7 @@ move\\t%0,%z4\\n\\ (define_insn "" [(set (match_operand:DI 0 "register_operand" "=d,d") - (lshiftrt:DI (match_operand:DI 1 "se_register_operand" "0,0") + (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0") (match_operand:SI 2 "arith_operand" "d,I")))] "TARGET_64BIT && TARGET_MIPS16" "* @@ -7879,8 +7602,8 @@ move\\t%0,%z4\\n\\ (define_expand "cmpdi" [(set (cc0) - (compare:CC (match_operand:DI 0 "se_register_operand" "") - (match_operand:DI 1 "se_arith_operand" "")))] + (compare:CC (match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "arith_operand" "")))] "TARGET_64BIT" " { @@ -7895,7 +7618,7 @@ move\\t%0,%z4\\n\\ (define_expand "tstdi" [(set (cc0) - (match_operand:DI 0 "se_register_operand" ""))] + (match_operand:DI 0 "register_operand" ""))] "TARGET_64BIT" " { @@ -8040,7 +7763,7 @@ move\\t%0,%z4\\n\\ [(set (pc) (if_then_else (match_operator:DI 0 "cmp_op" - [(match_operand:DI 2 "se_register_operand" "d") + [(match_operand:DI 2 "register_operand" "d") (const_int 0)]) (label_ref (match_operand 1 "" "")) (pc)))] @@ -8061,7 +7784,7 @@ move\\t%0,%z4\\n\\ [(set (pc) (if_then_else (match_operator:DI 0 "cmp_op" - [(match_operand:DI 2 "se_register_operand" "d") + [(match_operand:DI 2 "register_operand" "d") (const_int 0)]) (pc) (label_ref (match_operand 1 "" ""))))] @@ -8105,8 +7828,8 @@ move\\t%0,%z4\\n\\ [(set (pc) (if_then_else (match_operator:DI 0 "equality_op" - [(match_operand:DI 2 "se_register_operand" "d") - (match_operand:DI 3 "se_register_operand" "d")]) + [(match_operand:DI 2 "register_operand" "d") + (match_operand:DI 3 "register_operand" "d")]) (label_ref (match_operand 1 "" "")) (pc)))] "!TARGET_MIPS16" @@ -8147,8 +7870,8 @@ move\\t%0,%z4\\n\\ [(set (pc) (if_then_else (match_operator:DI 0 "equality_op" - [(match_operand:DI 2 "se_register_operand" "d") - (match_operand:DI 3 "se_register_operand" "d")]) + [(match_operand:DI 2 "register_operand" "d") + (match_operand:DI 3 "register_operand" "d")]) (pc) (label_ref (match_operand 1 "" ""))))] "!TARGET_MIPS16" @@ -8198,7 +7921,7 @@ move\\t%0,%z4\\n\\ (define_insn "" [(set (pc) (if_then_else (match_operator:DI 0 "equality_op" - [(match_operand:DI 1 "se_register_operand" "d,t") + [(match_operand:DI 1 "register_operand" "d,t") (const_int 0)]) (match_operand 2 "pc_or_label_operand" "") (match_operand 3 "pc_or_label_operand" "")))] @@ -8559,7 +8282,7 @@ move\\t%0,%z4\\n\\ (define_insn "seq_di_zero" [(set (match_operand:DI 0 "register_operand" "=d") - (eq:DI (match_operand:DI 1 "se_register_operand" "d") + (eq:DI (match_operand:DI 1 "register_operand" "d") (const_int 0)))] "TARGET_64BIT && !TARGET_MIPS16" "sltu\\t%0,%1,1" @@ -8568,7 +8291,7 @@ move\\t%0,%z4\\n\\ (define_insn "" [(set (match_operand:DI 0 "register_operand" "=t") - (eq:DI (match_operand:DI 1 "se_register_operand" "d") + (eq:DI (match_operand:DI 1 "register_operand" "d") (const_int 0)))] "TARGET_64BIT && TARGET_MIPS16" "sltu\\t%1,1" @@ -8603,8 +8326,8 @@ move\\t%0,%z4\\n\\ (define_insn "seq_di" [(set (match_operand:DI 0 "register_operand" "=d,d") - (eq:DI (match_operand:DI 1 "se_register_operand" "%d,d") - (match_operand:DI 2 "se_uns_arith_operand" "d,K")))] + (eq:DI (match_operand:DI 1 "register_operand" "%d,d") + (match_operand:DI 2 "uns_arith_operand" "d,K")))] "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16" "@ xor\\t%0,%1,%2\;sltu\\t%0,%0,1 @@ -8615,8 +8338,8 @@ move\\t%0,%z4\\n\\ (define_split [(set (match_operand:DI 0 "register_operand" "") - (eq:DI (match_operand:DI 1 "se_register_operand" "") - (match_operand:DI 2 "se_uns_arith_operand" "")))] + (eq:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "uns_arith_operand" "")))] "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)" @@ -8667,7 +8390,7 @@ move\\t%0,%z4\\n\\ (define_insn "sne_di_zero" [(set (match_operand:DI 0 "register_operand" "=d") - (ne:DI (match_operand:DI 1 "se_register_operand" "d") + (ne:DI (match_operand:DI 1 "register_operand" "d") (const_int 0)))] "TARGET_64BIT && !TARGET_MIPS16" "sltu\\t%0,%.,%1" @@ -8702,8 +8425,8 @@ move\\t%0,%z4\\n\\ (define_insn "sne_di" [(set (match_operand:DI 0 "register_operand" "=d,d") - (ne:DI (match_operand:DI 1 "se_register_operand" "%d,d") - (match_operand:DI 2 "se_uns_arith_operand" "d,K")))] + (ne:DI (match_operand:DI 1 "register_operand" "%d,d") + (match_operand:DI 2 "uns_arith_operand" "d,K")))] "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16" "@ xor\\t%0,%1,%2\;sltu\\t%0,%.,%0 @@ -8714,8 +8437,8 @@ move\\t%0,%z4\\n\\ (define_split [(set (match_operand:DI 0 "register_operand" "") - (ne:DI (match_operand:DI 1 "se_register_operand" "") - (match_operand:DI 2 "se_uns_arith_operand" "")))] + (ne:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "uns_arith_operand" "")))] "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16 && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)" @@ -8773,8 +8496,8 @@ move\\t%0,%z4\\n\\ (define_insn "sgt_di" [(set (match_operand:DI 0 "register_operand" "=d") - (gt:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))] + (gt:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "reg_or_0_operand" "dJ")))] "TARGET_64BIT && !TARGET_MIPS16" "slt\\t%0,%z2,%1" [(set_attr "type" "arith") @@ -8782,8 +8505,8 @@ move\\t%0,%z4\\n\\ (define_insn "" [(set (match_operand:DI 0 "register_operand" "=d") - (gt:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d")))] + (gt:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d")))] "TARGET_64BIT && TARGET_MIPS16" "slt\\t%2,%1" [(set_attr "type" "arith") @@ -8837,8 +8560,8 @@ move\\t%0,%z4\\n\\ (define_insn "sge_di" [(set (match_operand:DI 0 "register_operand" "=d") - (ge:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_arith_operand" "dI")))] + (ge:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "arith_operand" "dI")))] "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16" "slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001" [(set_attr "type" "arith") @@ -8847,8 +8570,8 @@ move\\t%0,%z4\\n\\ (define_split [(set (match_operand:DI 0 "register_operand" "") - (ge:DI (match_operand:DI 1 "se_register_operand" "") - (match_operand:DI 2 "se_arith_operand" "")))] + (ge:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "arith_operand" "")))] "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16" [(set (match_dup 0) @@ -8907,8 +8630,8 @@ move\\t%0,%z4\\n\\ (define_insn "slt_di" [(set (match_operand:DI 0 "register_operand" "=d") - (lt:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_arith_operand" "dI")))] + (lt:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "arith_operand" "dI")))] "TARGET_64BIT && !TARGET_MIPS16" "slt\\t%0,%1,%2" [(set_attr "type" "arith") @@ -8916,8 +8639,8 @@ move\\t%0,%z4\\n\\ (define_insn "" [(set (match_operand:DI 0 "register_operand" "=t,t") - (lt:DI (match_operand:DI 1 "se_register_operand" "d,d") - (match_operand:DI 2 "se_arith_operand" "d,I")))] + (lt:DI (match_operand:DI 1 "register_operand" "d,d") + (match_operand:DI 2 "arith_operand" "d,I")))] "TARGET_64BIT && TARGET_MIPS16" "slt\\t%1,%2" [(set_attr "type" "arith") @@ -8985,7 +8708,7 @@ move\\t%0,%z4\\n\\ (define_insn "sle_di_const" [(set (match_operand:DI 0 "register_operand" "=d") - (le:DI (match_operand:DI 1 "se_register_operand" "d") + (le:DI (match_operand:DI 1 "register_operand" "d") (match_operand:DI 2 "small_int" "I")))] "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767" "* @@ -8998,7 +8721,7 @@ move\\t%0,%z4\\n\\ (define_insn "" [(set (match_operand:DI 0 "register_operand" "=t") - (le:DI (match_operand:DI 1 "se_register_operand" "d") + (le:DI (match_operand:DI 1 "register_operand" "d") (match_operand:DI 2 "small_int" "I")))] "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767" "* @@ -9037,8 +8760,8 @@ move\\t%0,%z4\\n\\ (define_insn "sle_di_reg" [(set (match_operand:DI 0 "register_operand" "=d") - (le:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d")))] + (le:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d")))] "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16" "slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001" [(set_attr "type" "arith") @@ -9047,8 +8770,8 @@ move\\t%0,%z4\\n\\ (define_split [(set (match_operand:DI 0 "register_operand" "") - (le:DI (match_operand:DI 1 "se_register_operand" "") - (match_operand:DI 2 "se_register_operand" "")))] + (le:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "register_operand" "")))] "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16" [(set (match_dup 0) @@ -9105,8 +8828,8 @@ move\\t%0,%z4\\n\\ (define_insn "sgtu_di" [(set (match_operand:DI 0 "register_operand" "=d") - (gtu:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_reg_or_0_operand" "dJ")))] + (gtu:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "reg_or_0_operand" "dJ")))] "TARGET_64BIT && !TARGET_MIPS16" "sltu\\t%0,%z2,%1" [(set_attr "type" "arith") @@ -9114,8 +8837,8 @@ move\\t%0,%z4\\n\\ (define_insn "" [(set (match_operand:DI 0 "register_operand" "=t") - (gtu:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d")))] + (gtu:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d")))] "TARGET_64BIT && TARGET_MIPS16" "sltu\\t%2,%1" [(set_attr "type" "arith") @@ -9169,8 +8892,8 @@ move\\t%0,%z4\\n\\ (define_insn "sgeu_di" [(set (match_operand:DI 0 "register_operand" "=d") - (geu:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_arith_operand" "dI")))] + (geu:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "arith_operand" "dI")))] "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16" "sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001" [(set_attr "type" "arith") @@ -9179,8 +8902,8 @@ move\\t%0,%z4\\n\\ (define_split [(set (match_operand:DI 0 "register_operand" "") - (geu:DI (match_operand:DI 1 "se_register_operand" "") - (match_operand:DI 2 "se_arith_operand" "")))] + (geu:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "arith_operand" "")))] "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16" [(set (match_dup 0) @@ -9239,8 +8962,8 @@ move\\t%0,%z4\\n\\ (define_insn "sltu_di" [(set (match_operand:DI 0 "register_operand" "=d") - (ltu:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_arith_operand" "dI")))] + (ltu:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "arith_operand" "dI")))] "TARGET_64BIT && !TARGET_MIPS16" "sltu\\t%0,%1,%2" [(set_attr "type" "arith") @@ -9248,8 +8971,8 @@ move\\t%0,%z4\\n\\ (define_insn "" [(set (match_operand:DI 0 "register_operand" "=t,t") - (ltu:DI (match_operand:DI 1 "se_register_operand" "d,d") - (match_operand:DI 2 "se_arith_operand" "d,I")))] + (ltu:DI (match_operand:DI 1 "register_operand" "d,d") + (match_operand:DI 2 "arith_operand" "d,I")))] "TARGET_64BIT && TARGET_MIPS16" "sltu\\t%1,%2" [(set_attr "type" "arith") @@ -9317,7 +9040,7 @@ move\\t%0,%z4\\n\\ (define_insn "sleu_di_const" [(set (match_operand:DI 0 "register_operand" "=d") - (leu:DI (match_operand:DI 1 "se_register_operand" "d") + (leu:DI (match_operand:DI 1 "register_operand" "d") (match_operand:DI 2 "small_int" "I")))] "TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767" "* @@ -9330,7 +9053,7 @@ move\\t%0,%z4\\n\\ (define_insn "" [(set (match_operand:DI 0 "register_operand" "=t") - (leu:DI (match_operand:DI 1 "se_register_operand" "d") + (leu:DI (match_operand:DI 1 "register_operand" "d") (match_operand:DI 2 "small_int" "I")))] "TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767" "* @@ -9369,8 +9092,8 @@ move\\t%0,%z4\\n\\ (define_insn "sleu_di_reg" [(set (match_operand:DI 0 "register_operand" "=d") - (leu:DI (match_operand:DI 1 "se_register_operand" "d") - (match_operand:DI 2 "se_register_operand" "d")))] + (leu:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d")))] "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_MIPS16" "sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001" [(set_attr "type" "arith") @@ -9379,8 +9102,8 @@ move\\t%0,%z4\\n\\ (define_split [(set (match_operand:DI 0 "register_operand" "") - (leu:DI (match_operand:DI 1 "se_register_operand" "") - (match_operand:DI 2 "se_register_operand" "")))] + (leu:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "register_operand" "")))] "TARGET_64BIT && TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE && !TARGET_MIPS16" [(set (match_dup 0) @@ -9649,7 +9372,7 @@ move\\t%0,%z4\\n\\ ;; we can't use `j' when emitting non-embedded PIC, so we emit ;; branch, if it's in range, or load the address of the branch ;; target into $at in a PIC-compatible way and then jump to it. - (if_then_else + (if_then_else (ior (eq (symbol_ref "flag_pic && ! TARGET_EMBEDDED_PIC") (const_int 0)) (lt (abs (minus (match_dup 0) @@ -9699,7 +9422,7 @@ move\\t%0,%z4\\n\\ (set_attr "mode" "none")]) (define_insn "indirect_jump_internal2" - [(set (pc) (match_operand:DI 0 "se_register_operand" "d"))] + [(set (pc) (match_operand:DI 0 "register_operand" "d"))] "Pmode == DImode" "%*j\\t%0" [(set_attr "type" "jump") @@ -9725,24 +9448,17 @@ move\\t%0,%z4\\n\\ DONE; } - if (GET_MODE (operands[0]) != Pmode) + if (GET_MODE (operands[0]) != ptr_mode) abort (); - if (! flag_pic) - { - if (!(Pmode == DImode)) - emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1])); - else - emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1])); - } - else - { - if (!(Pmode == DImode)) - emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1])); - else - emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1])); - } + if (TARGET_GPWORD) + operands[0] = expand_binop (ptr_mode, add_optab, operands[0], + pic_offset_table_rtx, 0, 0, OPTAB_WIDEN); + if (Pmode == SImode) + emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1])); + else + emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1])); DONE; } }") @@ -9751,28 +9467,20 @@ move\\t%0,%z4\\n\\ [(set (pc) (match_operand:SI 0 "register_operand" "d")) (use (label_ref (match_operand 1 "" "")))] - "!(Pmode == DImode)" + "" "%*j\\t%0" [(set_attr "type" "jump") (set_attr "mode" "none")]) (define_insn "tablejump_internal2" [(set (pc) - (match_operand:DI 0 "se_register_operand" "d")) + (match_operand:DI 0 "register_operand" "d")) (use (label_ref (match_operand 1 "" "")))] - "Pmode == DImode" + "TARGET_64BIT" "%*j\\t%0" [(set_attr "type" "jump") (set_attr "mode" "none")]) -(define_expand "tablejump_internal3" - [(parallel [(set (pc) - (plus:SI (match_operand:SI 0 "register_operand" "d") - (label_ref:SI (match_operand 1 "" "")))) - (use (label_ref:SI (match_dup 1)))])] - "" - "") - (define_expand "tablejump_mips161" [(set (pc) (plus:SI (sign_extend:SI (match_operand:HI 0 "register_operand" "d")) @@ -9817,64 +9525,6 @@ move\\t%0,%z4\\n\\ } }") -;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise -;;; it is not valid. ??? With the USE, the condition tests may not be required -;;; any longer. - -;;; ??? The length depends on the ABI. It is two for o32, and one for n32. -;;; We just use the conservative number here. - -(define_insn "" - [(set (pc) - (plus:SI (match_operand:SI 0 "register_operand" "d") - (label_ref:SI (match_operand 1 "" "")))) - (use (label_ref:SI (match_dup 1)))] - "!(Pmode == DImode) && next_active_insn (insn) != 0 - && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC - && PREV_INSN (next_active_insn (insn)) == operands[1]" - "* -{ - /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic. */ - if (mips_abi == ABI_32 || mips_abi == ABI_O64 - || (mips_abi == ABI_N32 && TARGET_GAS)) - output_asm_insn (\".cpadd\\t%0\", operands); - return \"%*j\\t%0\"; -}" - [(set_attr "type" "jump") - (set_attr "mode" "none") - (set_attr "length" "8")]) - -(define_expand "tablejump_internal4" - [(parallel [(set (pc) - (plus:DI (match_operand:DI 0 "se_register_operand" "d") - (label_ref:DI (match_operand 1 "" "")))) - (use (label_ref:DI (match_dup 1)))])] - "" - "") - -;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise -;;; it is not valid. ??? With the USE, the condition tests may not be required -;;; any longer. - -(define_insn "" - [(set (pc) - (plus:DI (match_operand:DI 0 "se_register_operand" "d") - (label_ref:DI (match_operand 1 "" "")))) - (use (label_ref:DI (match_dup 1)))] - "Pmode == DImode && next_active_insn (insn) != 0 - && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC - && PREV_INSN (next_active_insn (insn)) == operands[1]" - "* -{ - /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic. */ - if (TARGET_GAS && mips_abi == ABI_64) - output_asm_insn (\".cpadd\\t%0\", operands); - return \"%*j\\t%0\"; -}" - [(set_attr "type" "jump") - (set_attr "mode" "none") - (set_attr "length" "8")]) - ;; Implement a switch statement when generating embedded PIC code. ;; Switches are implemented by `tablejump' when not using -membedded-pic. @@ -10060,14 +9710,18 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2" (define_expand "epilogue" [(const_int 2)] "" - " { - if (mips_isa >= 0) /* avoid unused code warnings */ - { - mips_expand_epilogue (); - DONE; - } -}") + mips_expand_epilogue (false); + DONE; +}) + +(define_expand "sibcall_epilogue" + [(const_int 2)] + "" +{ + mips_expand_epilogue (true); + DONE; +}) ;; Trivial return. Make it look like a normal return insn as that ;; allows jump optimizations to work better . @@ -10165,470 +9819,181 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2" ;; ;; .................... -;; calls.c now passes a third argument, make saber happy +;; Sibling calls. All these patterns use direct jumps. -(define_expand "call" - [(parallel [(call (match_operand 0 "memory_operand" "m") - (match_operand 1 "" "i")) - (clobber (reg:SI 31)) - (use (match_operand 2 "" "")) ;; next_arg_reg - (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx - "" - " -{ - rtx addr; +;; call_insn_operand will only accepts constant addresses if a direct +;; jump is acceptable. Since the 'S' constraint is defined in terms of +;; call_insn_operand, the same is true of the contraints. - if (operands[0]) /* eliminate unused code warnings */ - { - addr = XEXP (operands[0], 0); - if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS)) - || ! call_insn_operand (addr, VOIDmode)) - XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr); - - /* In order to pass small structures by value in registers - compatibly with the MIPS compiler, we need to shift the value - into the high part of the register. Function_arg has encoded - a PARALLEL rtx, holding a vector of adjustments to be made - as the next_arg_reg variable, so we split up the insns, - and emit them separately. */ - - if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL) - { - rtvec adjust = XVEC (operands[2], 0); - int num = GET_NUM_ELEM (adjust); - int i; - - for (i = 0; i < num; i++) - emit_insn (RTVEC_ELT (adjust, i)); - } +;; When we use an indirect jump, we need a register that will be +;; preserved by the epilogue. Since TARGET_ABICALLS forces us to +;; use $25 for this purpose -- and $25 is never clobbered by the +;; epilogue -- we might as well use it for !TARGET_ABICALLS as well. - if (TARGET_MIPS16 - && mips16_hard_float - && operands[2] != 0 - && (int) GET_MODE (operands[2]) != 0) - { - if (build_mips16_call_stub (NULL_RTX, operands[0], operands[1], - (int) GET_MODE (operands[2]))) - DONE; - } - - emit_call_insn (gen_call_internal0 (operands[0], operands[1], - gen_rtx_REG (SImode, - GP_REG_FIRST + 31))); - DONE; - } -}") - -(define_expand "call_internal0" +(define_expand "sibcall" [(parallel [(call (match_operand 0 "" "") (match_operand 1 "" "")) - (clobber (match_operand:SI 2 "" ""))])] - "" - "") - -;; We need to recognize reg:SI 31 specially for the mips16, because we -;; don't have a constraint letter for it. - -(define_insn "" - [(call (mem (match_operand 0 "call_insn_operand" "ei")) - (match_operand 1 "" "i")) - (clobber (match_operand:SI 2 "register_operand" "=y"))] - "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS - && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31" - "%*jal\\t%0" - [(set_attr "type" "call") - (set_attr "mode" "none") - (set_attr "length" "8")]) - -(define_insn "call_internal1" - [(call (mem (match_operand 0 "call_insn_operand" "ri")) - (match_operand 1 "" "i")) - (clobber (match_operand:SI 2 "register_operand" "=d"))] - "!TARGET_ABICALLS && !TARGET_LONG_CALLS" - "* -{ - register rtx target = operands[0]; - - if (GET_CODE (target) == CONST_INT) - return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\"; - else if (CONSTANT_ADDRESS_P (target)) - return \"%*jal\\t%0\"; - else - return \"%*jal\\t%2,%0\"; -}" - [(set_attr "type" "call") - (set_attr "mode" "none")]) - -(define_insn "call_internal2" - [(call (mem (match_operand 0 "call_insn_operand" "ri")) - (match_operand 1 "" "i")) - (clobber (match_operand:SI 2 "register_operand" "=d"))] - "TARGET_ABICALLS && !TARGET_LONG_CALLS" - "* -{ - register rtx target = operands[0]; - - if (GET_CODE (target) == CONST_INT) - return \"li\\t%^,%0\\n\\tjal\\t%2,%^\"; - else if (CONSTANT_ADDRESS_P (target)) - { - if (GET_MODE (target) == SImode) - return \"la\\t%^,%0\\n\\tjal\\t%2,%^\"; - else - return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\"; - } - else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM) - return \"move\\t%^,%0\\n\\tjal\\t%2,%^\"; - else - return \"jal\\t%2,%0\"; -}" - [(set_attr "type" "call") - (set_attr "mode" "none") - (set_attr "length" "8")]) - -(define_insn "call_internal3a" - [(call (mem:SI (match_operand:SI 0 "register_operand" "r")) - (match_operand 1 "" "i")) - (clobber (match_operand:SI 2 "register_operand" "=d"))] - "!TARGET_MIPS16 - && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS" - "%*jal\\t%2,%0" - [(set_attr "type" "call") - (set_attr "mode" "none")]) - -(define_insn "call_internal3b" - [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r")) - (match_operand 1 "" "i")) - (clobber (match_operand:SI 2 "register_operand" "=d"))] - "!TARGET_MIPS16 - && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS" - "%*jal\\t%2,%0" - [(set_attr "type" "call") - (set_attr "mode" "none") - (set_attr "length" "1")]) - -(define_insn "call_internal3c" - [(call (mem:SI (match_operand:SI 0 "register_operand" "e")) - (match_operand 1 "" "i")) - (clobber (match_operand:SI 2 "register_operand" "=y"))] - "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS - && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31" - "%*jal\\t%2,%0" - [(set_attr "type" "call") - (set_attr "mode" "none")]) - -(define_insn "call_internal4a" - [(call (mem:SI (match_operand:SI 0 "register_operand" "r")) - (match_operand 1 "" "i")) - (clobber (match_operand:SI 2 "register_operand" "=d"))] - "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS" - "* -{ - if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM) - return \"move\\t%^,%0\\n\\tjal\\t%2,%^\"; - else - return \"jal\\t%2,%0\"; -}" - [(set_attr "type" "call") - (set_attr "mode" "none") - (set_attr "length" "8")]) - -(define_insn "call_internal4b" - [(call (mem:DI (match_operand:DI 0 "se_register_operand" "r")) - (match_operand 1 "" "i")) - (clobber (match_operand:SI 2 "register_operand" "=d"))] - "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS" - "* -{ - if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM) - return \"move\\t%^,%0\\n\\tjal\\t%2,%^\"; - else - return \"jal\\t%2,%0\"; -}" - [(set_attr "type" "call") - (set_attr "mode" "none") - (set_attr "length" "8")]) - -;; calls.c now passes a fourth argument, make saber happy - -(define_expand "call_value" - [(parallel [(set (match_operand 0 "register_operand" "=df") - (call (match_operand 1 "memory_operand" "m") - (match_operand 2 "" "i"))) - (clobber (reg:SI 31)) - (use (match_operand 3 "" ""))])] ;; next_arg_reg - "" - " + (use (match_operand 2 "" "")) ;; next_arg_reg + (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx + "TARGET_SIBCALLS" { - rtx addr; - - if (operands[0]) /* eliminate unused code warning */ - { - addr = XEXP (operands[1], 0); - if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS)) - || ! call_insn_operand (addr, VOIDmode)) - XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr); - - /* In order to pass small structures by value in registers - compatibly with the MIPS compiler, we need to shift the value - into the high part of the register. Function_arg has encoded - a PARALLEL rtx, holding a vector of adjustments to be made - as the next_arg_reg variable, so we split up the insns, - and emit them separately. */ - - if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL) - { - rtvec adjust = XVEC (operands[3], 0); - int num = GET_NUM_ELEM (adjust); - int i; - - for (i = 0; i < num; i++) - emit_insn (RTVEC_ELT (adjust, i)); - } - - if (TARGET_MIPS16 - && mips16_hard_float - && ((operands[3] != 0 - && (int) GET_MODE (operands[3]) != 0) - || GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT)) - { - if (build_mips16_call_stub (operands[0], operands[1], operands[2], - (operands[3] == 0 ? 0 - : (int) GET_MODE (operands[3])))) - DONE; - } - - /* Handle Irix6 function calls that have multiple non-contiguous - results. */ - if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1) - { - emit_call_insn (gen_call_value_multiple_internal0 - (XEXP (XVECEXP (operands[0], 0, 0), 0), - operands[1], operands[2], - XEXP (XVECEXP (operands[0], 0, 1), 0), - gen_rtx_REG (SImode, GP_REG_FIRST + 31))); - DONE; - } - - /* We have a call returning a DImode structure in an FP reg. - Strip off the now unnecessary PARALLEL. */ - if (GET_CODE (operands[0]) == PARALLEL) - operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0); - - emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2], - gen_rtx_REG (SImode, - GP_REG_FIRST + 31))); + mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], true); + DONE; +}) - DONE; - } -}") +(define_insn "sibcall_internal" + [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S")) + (match_operand 1 "" ""))] + "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" + "@ + %*jr\\t%0 + %*j\\t%0" + [(set_attr "type" "call")]) -(define_expand "call_value_internal0" +(define_expand "sibcall_value" [(parallel [(set (match_operand 0 "" "") (call (match_operand 1 "" "") (match_operand 2 "" ""))) - (clobber (match_operand:SI 3 "" ""))])] - "" - "") - -;; Recognize $31 specially on the mips16, because we don't have a -;; constraint letter for it. - -(define_insn "" - [(set (match_operand 0 "register_operand" "=d") - (call (mem (match_operand 1 "call_insn_operand" "ei")) - (match_operand 2 "" "i"))) - (clobber (match_operand:SI 3 "register_operand" "=y"))] - "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS - && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31" - "%*jal\\t%1" - [(set_attr "type" "call") - (set_attr "mode" "none") - (set_attr "length" "8")]) - -(define_insn "call_value_internal1" - [(set (match_operand 0 "register_operand" "=df") - (call (mem (match_operand 1 "call_insn_operand" "ri")) - (match_operand 2 "" "i"))) - (clobber (match_operand:SI 3 "register_operand" "=d"))] - "!TARGET_ABICALLS && !TARGET_LONG_CALLS" - "* -{ - register rtx target = operands[1]; - - if (GET_CODE (target) == CONST_INT) - return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\"; - else if (CONSTANT_ADDRESS_P (target)) - return \"%*jal\\t%1\"; - else - return \"%*jal\\t%3,%1\"; -}" - [(set_attr "type" "call") - (set_attr "mode" "none")]) - -(define_insn "call_value_internal2" - [(set (match_operand 0 "register_operand" "=df") - (call (mem (match_operand 1 "call_insn_operand" "ri")) - (match_operand 2 "" "i"))) - (clobber (match_operand:SI 3 "register_operand" "=d"))] - "TARGET_ABICALLS && !TARGET_LONG_CALLS" - "* + (use (match_operand 3 "" ""))])] ;; next_arg_reg + "TARGET_SIBCALLS" { - register rtx target = operands[1]; - - if (GET_CODE (target) == CONST_INT) - return \"li\\t%^,%1\\n\\tjal\\t%3,%^\"; - else if (CONSTANT_ADDRESS_P (target)) - { - if (GET_MODE (target) == SImode) - return \"la\\t%^,%1\\n\\tjal\\t%3,%^\"; - else - return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\"; - } - else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM) - return \"move\\t%^,%1\\n\\tjal\\t%3,%^\"; - else - return \"jal\\t%3,%1\"; -}" - [(set_attr "type" "call") - (set_attr "mode" "none") - (set_attr "length" "8")]) - -(define_insn "call_value_internal3a" - [(set (match_operand 0 "register_operand" "=df") - (call (mem:SI (match_operand:SI 1 "register_operand" "r")) - (match_operand 2 "" "i"))) - (clobber (match_operand:SI 3 "register_operand" "=d"))] - "!TARGET_MIPS16 - && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS" - "%*jal\\t%3,%1" - [(set_attr "type" "call") - (set_attr "mode" "none")]) - -(define_insn "call_value_internal3b" - [(set (match_operand 0 "register_operand" "=df") - (call (mem:DI (match_operand:DI 1 "se_register_operand" "r")) - (match_operand 2 "" "i"))) - (clobber (match_operand:SI 3 "register_operand" "=d"))] - "!TARGET_MIPS16 - && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS" - "%*jal\\t%3,%1" - [(set_attr "type" "call") - (set_attr "mode" "none")]) + mips_expand_call (operands[0], XEXP (operands[1], 0), + operands[2], operands[3], true); + DONE; +}) -(define_insn "call_value_internal3c" - [(set (match_operand 0 "register_operand" "=df") - (call (mem:SI (match_operand:SI 1 "register_operand" "e")) - (match_operand 2 "" "i"))) - (clobber (match_operand:SI 3 "register_operand" "=y"))] - "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS - && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31" - "%*jal\\t%3,%1" - [(set_attr "type" "call") - (set_attr "mode" "none")]) +(define_insn "sibcall_value_internal" + [(set (match_operand 0 "register_operand" "=df,df") + (call (mem:SI (match_operand 1 "call_insn_operand" "j,S")) + (match_operand 2 "" "")))] + "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" + "@ + %*jr\\t%1 + %*j\\t%1" + [(set_attr "type" "call")]) + +(define_insn "sibcall_value_multiple_internal" + [(set (match_operand 0 "register_operand" "=df,df") + (call (mem:SI (match_operand 1 "call_insn_operand" "j,S")) + (match_operand 2 "" ""))) + (set (match_operand 3 "register_operand" "=df,df") + (call (mem:SI (match_dup 1)) + (match_dup 2)))] + "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" + "@ + %*jr\\t%1 + %*j\\t%1" + [(set_attr "type" "call")]) -(define_insn "call_value_internal4a" - [(set (match_operand 0 "register_operand" "=df") - (call (mem:SI (match_operand:SI 1 "register_operand" "r")) - (match_operand 2 "" "i"))) - (clobber (match_operand:SI 3 "register_operand" "=d"))] - "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS" - "* +(define_expand "call" + [(parallel [(call (match_operand 0 "" "") + (match_operand 1 "" "")) + (use (match_operand 2 "" "")) ;; next_arg_reg + (use (match_operand 3 "" ""))])] ;; struct_value_size_rtx + "" { - if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM) - return \"move\\t%^,%1\\n\\tjal\\t%3,%^\"; - else - return \"jal\\t%3,%1\"; -}" - [(set_attr "type" "call") - (set_attr "mode" "none") - (set_attr "length" "8")]) + mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2], false); + DONE; +}) -(define_insn "call_value_internal4b" - [(set (match_operand 0 "register_operand" "=df") - (call (mem:DI (match_operand:DI 1 "se_register_operand" "r")) - (match_operand 2 "" "i"))) - (clobber (match_operand:SI 3 "register_operand" "=d"))] - "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS" - "* -{ - if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM) - return \"move\\t%^,%1\\n\\tjal\\t%3,%^\"; - else - return \"jal\\t%3,%1\"; -}" - [(set_attr "type" "call") - (set_attr "mode" "none") - (set_attr "length" "8")]) +(define_insn_and_split "call_internal" + [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S")) + (match_operand 1 "" "")) + (clobber (reg:SI 31))] + "" + "%*jal\\t%0" + "reload_completed && TARGET_SPLIT_CALLS" + [(const_int 0)] + { + emit_call_insn (gen_call_split (operands[0], operands[1])); + emit_insn (gen_exception_receiver ()); + DONE; + } + [(set_attr "jal" "indirect,direct") + (set_attr "extended_mips16" "no,yes")]) + +(define_insn "call_split" + [(call (mem:SI (match_operand 0 "call_insn_operand" "c")) + (match_operand 1 "" "")) + (clobber (reg:SI 31)) + (const_int 1)] + "TARGET_SPLIT_CALLS" + "%*jalr\\t%0" + [(set_attr "type" "call")]) -(define_expand "call_value_multiple_internal0" +(define_expand "call_value" [(parallel [(set (match_operand 0 "" "") (call (match_operand 1 "" "") (match_operand 2 "" ""))) - (set (match_operand 3 "" "") - (call (match_dup 1) - (match_dup 2))) - (clobber (match_operand:SI 4 "" ""))])] + (use (match_operand 3 "" ""))])] ;; next_arg_reg "" - "") - -;; ??? May eventually need all 6 versions of the call patterns with multiple -;; return values. - -(define_insn "call_value_multiple_internal1" - [(set (match_operand 0 "register_operand" "=df") - (call (mem (match_operand 1 "call_insn_operand" "ri")) - (match_operand 2 "" "i"))) - (set (match_operand 3 "register_operand" "=df") - (call (mem (match_dup 1)) - (match_dup 2))) - (clobber (match_operand:SI 4 "register_operand" "=d"))] - "!TARGET_ABICALLS && !TARGET_LONG_CALLS" - "* { - register rtx target = operands[1]; - - if (GET_CODE (target) == CONST_INT) - return \"%[li\\t%@,%1\\n\\t%*jal\\t%4,%@%]\"; - else if (CONSTANT_ADDRESS_P (target)) - return \"%*jal\\t%1\"; - else - return \"%*jal\\t%4,%1\"; -}" - [(set_attr "type" "call") - (set_attr "mode" "none")]) + mips_expand_call (operands[0], XEXP (operands[1], 0), + operands[2], operands[3], false); + DONE; +}) -(define_insn "call_value_multiple_internal2" +(define_insn_and_split "call_value_internal" + [(set (match_operand 0 "register_operand" "=df,df") + (call (mem:SI (match_operand 1 "call_insn_operand" "c,S")) + (match_operand 2 "" ""))) + (clobber (reg:SI 31))] + "" + "%*jal\\t%1" + "reload_completed && TARGET_SPLIT_CALLS" + [(const_int 0)] + { + emit_call_insn (gen_call_value_split (operands[0], operands[1], + operands[2])); + emit_insn (gen_exception_receiver ()); + DONE; + } + [(set_attr "jal" "indirect,direct") + (set_attr "extended_mips16" "no,yes")]) + +(define_insn "call_value_split" + [(set (match_operand 0 "register_operand" "=df") + (call (mem:SI (match_operand 1 "call_insn_operand" "c")) + (match_operand 2 "" ""))) + (clobber (reg:SI 31)) + (const_int 1)] + "TARGET_SPLIT_CALLS" + "%*jalr\\t%1" + [(set_attr "type" "call")]) + +(define_insn_and_split "call_value_multiple_internal" + [(set (match_operand 0 "register_operand" "=df,df") + (call (mem:SI (match_operand 1 "call_insn_operand" "c,S")) + (match_operand 2 "" ""))) + (set (match_operand 3 "register_operand" "=df,df") + (call (mem:SI (match_dup 1)) + (match_dup 2))) + (clobber (reg:SI 31))] + "" + "%*jal\\t%1" + "reload_completed && TARGET_SPLIT_CALLS" + [(const_int 0)] + { + emit_call_insn (gen_call_value_multiple_split (operands[0], operands[1], + operands[2], operands[3])); + emit_insn (gen_exception_receiver ()); + DONE; + } + [(set_attr "jal" "indirect,direct") + (set_attr "extended_mips16" "no,yes")]) + +(define_insn "call_value_multiple_split" [(set (match_operand 0 "register_operand" "=df") - (call (mem (match_operand 1 "call_insn_operand" "ri")) - (match_operand 2 "" "i"))) + (call (mem:SI (match_operand 1 "call_insn_operand" "c")) + (match_operand 2 "" ""))) (set (match_operand 3 "register_operand" "=df") - (call (mem (match_dup 1)) - (match_dup 2))) - (clobber (match_operand:SI 4 "register_operand" "=d"))] - "TARGET_ABICALLS && !TARGET_LONG_CALLS" - "* -{ - register rtx target = operands[1]; - - if (GET_CODE (target) == CONST_INT) - return \"li\\t%^,%1\\n\\tjal\\t%4,%^\"; - else if (CONSTANT_ADDRESS_P (target)) - { - if (GET_MODE (target) == SImode) - return \"la\\t%^,%1\\n\\tjal\\t%4,%^\"; - else - return \"dla\\t%^,%1\\n\\tjal\\t%4,%^\"; - } - else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM) - return \"move\\t%^,%1\\n\\tjal\\t%4,%^\"; - else - return \"jal\\t%4,%1\"; -}" - [(set_attr "type" "call") - (set_attr "mode" "none") - (set_attr "length" "8")]) - + (call (mem:SI (match_dup 1)) + (match_dup 2))) + (clobber (reg:SI 31)) + (const_int 1)] + "TARGET_SPLIT_CALLS" + "%*jalr\\t%1" + [(set_attr "type" "call")]) ;; Call subroutine returning any type. @@ -10640,21 +10005,18 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2" "" " { - if (operands[0]) /* silence statement not reached warnings */ - { - int i; + int i; - emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx)); + emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx)); - for (i = 0; i < XVECLEN (operands[2], 0); i++) - { - rtx set = XVECEXP (operands[2], 0, i); - emit_move_insn (SET_DEST (set), SET_SRC (set)); - } - - emit_insn (gen_blockage ()); - DONE; + for (i = 0; i < XVECLEN (operands[2], 0); i++) + { + rtx set = XVECEXP (operands[2], 0, i); + emit_move_insn (SET_DEST (set), SET_SRC (set)); } + + emit_insn (gen_blockage ()); + DONE; }") ;; @@ -10671,10 +10033,10 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2" (match_operand 1 "const_int_operand" "") (match_operand 2 "const_int_operand" ""))] "ISA_HAS_PREFETCH" -"{ - if (symbolic_operand (operands[0], GET_MODE (operands[0]))) - operands[0] = force_reg (GET_MODE (operands[0]), operands[0]); -}") +{ + if (symbolic_operand (operands[0], GET_MODE (operands[0]))) + operands[0] = force_reg (GET_MODE (operands[0]), operands[0]); +}) (define_insn "prefetch_si_address" [(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r") @@ -10683,7 +10045,7 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2" (match_operand:SI 2 "const_int_operand" "n"))] "ISA_HAS_PREFETCH && Pmode == SImode" "* return mips_emit_prefetch (operands);" - [(set_attr "type" "load")]) + [(set_attr "type" "prefetch")]) (define_insn "prefetch_si" [(prefetch (match_operand:SI 0 "register_operand" "r") @@ -10691,24 +10053,24 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2" (match_operand:SI 2 "const_int_operand" "n"))] "ISA_HAS_PREFETCH && Pmode == SImode" "* return mips_emit_prefetch (operands);" - [(set_attr "type" "load")]) + [(set_attr "type" "prefetch")]) (define_insn "prefetch_di_address" - [(prefetch (plus:DI (match_operand:DI 0 "se_register_operand" "r") + [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r") (match_operand:DI 3 "const_int_operand" "i")) (match_operand:DI 1 "const_int_operand" "n") (match_operand:DI 2 "const_int_operand" "n"))] "ISA_HAS_PREFETCH && Pmode == DImode" "* return mips_emit_prefetch (operands);" - [(set_attr "type" "load")]) + [(set_attr "type" "prefetch")]) (define_insn "prefetch_di" - [(prefetch (match_operand:DI 0 "se_register_operand" "r") + [(prefetch (match_operand:DI 0 "register_operand" "r") (match_operand:DI 1 "const_int_operand" "n") (match_operand:DI 2 "const_int_operand" "n"))] "ISA_HAS_PREFETCH && Pmode == DImode" "* return mips_emit_prefetch (operands);" - [(set_attr "type" "load")]) + [(set_attr "type" "prefetch")]) (define_insn "nop" [(const_int 0)] @@ -10755,7 +10117,7 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2" [(set (match_operand:SI 0 "register_operand" "=d,d") (if_then_else:SI (match_operator 4 "equality_op" - [(match_operand:DI 1 "se_register_operand" "d,d") + [(match_operand:DI 1 "register_operand" "d,d") (const_int 0)]) (match_operand:SI 2 "reg_or_0_operand" "dJ,0") (match_operand:SI 3 "reg_or_0_operand" "0,dJ")))] @@ -10788,8 +10150,8 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2" (match_operator 4 "equality_op" [(match_operand:SI 1 "register_operand" "d,d") (const_int 0)]) - (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0") - (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))] + (match_operand:DI 2 "reg_or_0_operand" "dJ,0") + (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))] "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT" "@ mov%B4\\t%0,%z2,%1 @@ -10801,10 +10163,10 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2" [(set (match_operand:DI 0 "register_operand" "=d,d") (if_then_else:DI (match_operator 4 "equality_op" - [(match_operand:DI 1 "se_register_operand" "d,d") + [(match_operand:DI 1 "register_operand" "d,d") (const_int 0)]) - (match_operand:DI 2 "se_reg_or_0_operand" "dJ,0") - (match_operand:DI 3 "se_reg_or_0_operand" "0,dJ")))] + (match_operand:DI 2 "reg_or_0_operand" "dJ,0") + (match_operand:DI 3 "reg_or_0_operand" "0,dJ")))] "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT" "@ mov%B4\\t%0,%z2,%1 @@ -10819,8 +10181,8 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2" "register_operand" "z,z") (const_int 0)]) - (match_operand:DI 1 "se_reg_or_0_operand" "dJ,0") - (match_operand:DI 2 "se_reg_or_0_operand" "0,dJ")))] + (match_operand:DI 1 "reg_or_0_operand" "dJ,0") + (match_operand:DI 2 "reg_or_0_operand" "0,dJ")))] "ISA_HAS_CONDMOVE && TARGET_HARD_FLOAT && TARGET_64BIT" "@ mov%T3\\t%0,%z1,%4 @@ -10847,7 +10209,7 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2" [(set (match_operand:SF 0 "register_operand" "=f,f") (if_then_else:SF (match_operator 4 "equality_op" - [(match_operand:DI 1 "se_register_operand" "d,d") + [(match_operand:DI 1 "register_operand" "d,d") (const_int 0)]) (match_operand:SF 2 "register_operand" "f,0") (match_operand:SF 3 "register_operand" "0,f")))] @@ -10893,7 +10255,7 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2" [(set (match_operand:DF 0 "register_operand" "=f,f") (if_then_else:DF (match_operator 4 "equality_op" - [(match_operand:DI 1 "se_register_operand" "d,d") + [(match_operand:DI 1 "register_operand" "d,d") (const_int 0)]) (match_operand:DF 2 "register_operand" "f,0") (match_operand:DF 3 "register_operand" "0,f")))] @@ -10939,8 +10301,8 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2" [(set (match_dup 4) (match_operand 1 "comparison_operator" "")) (set (match_operand:DI 0 "register_operand" "") (if_then_else:DI (match_dup 5) - (match_operand:DI 2 "se_reg_or_0_operand" "") - (match_operand:DI 3 "se_reg_or_0_operand" "")))] + (match_operand:DI 2 "reg_or_0_operand" "") + (match_operand:DI 3 "reg_or_0_operand" "")))] "(ISA_HAS_CONDMOVE || ISA_HAS_INT_CONDMOVE) && TARGET_64BIT" " { @@ -11212,27 +10574,3 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2" [(set_attr "type" "branch") (set_attr "mode" "none") (set_attr "length" "8")]) - -;; For the rare case where we need to load an address into a register -;; that can not be recognized by the normal movsi/addsi instructions. -;; I have no idea how many insns this can actually generate. It should -;; be rare, so over-estimating as 10 instructions should not have any -;; real performance impact. -(define_insn "leasi" - [(set (match_operand:SI 0 "register_operand" "=d") - (match_operand:SI 1 "address_operand" "p"))] - "Pmode == SImode" - "la %0,%a1" - [(set_attr "type" "arith") - (set_attr "mode" "SI") - (set_attr "length" "40")]) - -;; Similarly for targets where we have 64bit pointers. -(define_insn "leadi" - [(set (match_operand:DI 0 "register_operand" "=d") - (match_operand:DI 1 "address_operand" "p"))] - "Pmode == DImode" - "dla %0,%a1" - [(set_attr "type" "arith") - (set_attr "mode" "DI") - (set_attr "length" "40")]) |