From 9f61f8addd5b084ab3cb6e56812d6f4c54a8b026 Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Tue, 13 Oct 1992 19:08:44 -0400 Subject: [PATCH] Use GEN_INT when appropriate. (define_attr type): New types for SQRT. (call patterns): Use SCRATCH for LR0. Use new predicate call_operand so that some integers can be used as addresses; fix CALLI so it doesn't accept constant. (EXBYTE, EXTHW, INBYTE, INHW): Use ZERO_EXTEND instead of AND when combine will make it. Use PSImode for BP value and don't reference BP explicitly. Clean up define_expands for these operations. (rotlsi3): Use PSImode pseudo for FC. (sign_extend): Sign extension insns clobber BP. ({load,store}_multiple): Use PSImode pseudo for CR. (MTSR): Add pattern for TRUNCATE from SImode to PSImode. (sqrtsf2, sqrtdf2, movpsi): New patterns. (load/store bytes/halfword): Clean up to accept temporaries as input and use PSImode when required. (movhi, movqi): Allocate temporaries here. (reload_inqi, reload_outqi, reload_inhi, reload_outhi): New patterns. (movdf, movdi, movti): Use SCRATCH for BP register. (reload_{in,out}{df,di,ti}): New patterns. From-SVN: r2445 --- gcc/config/a29k/a29k.md | 897 +++++++++++++++++++++++----------------- 1 file changed, 527 insertions(+), 370 deletions(-) diff --git a/gcc/config/a29k/a29k.md b/gcc/config/a29k/a29k.md index 06fe6f177eb..c99fa01dce1 100644 --- a/gcc/config/a29k/a29k.md +++ b/gcc/config/a29k/a29k.md @@ -1,5 +1,5 @@ ;;- Machine description for AMD Am29000 for GNU C compiler -;; Copyright (C) 1991 Free Software Foundation, Inc. +;; Copyright (C) 1991, 1992 Free Software Foundation, Inc. ;; Contributed by Richard Kenner (kenner@nyu.edu) ;; This file is part of GNU CC. @@ -31,7 +31,7 @@ ;; Everything else is miscellaneous. (define_attr "type" - "call,branch,load,store,fadd,fmul,fam,fdiv,dmul,dam,ddiv,multi,misc" + "call,branch,load,store,fadd,fmul,fam,fdiv,fsqrt,dmul,dam,ddiv,dsqrt,multi,misc" (const_string "misc")) ;; ASM insns cannot go into a delay slot, so call them "multi". @@ -69,7 +69,9 @@ (define_function_unit "adder" 1 0 (eq_attr "type" "fadd,fam,dam") 3 0) (define_function_unit "divider" 1 0 (eq_attr "type" "fdiv") 11 10) +(define_function_unit "divider" 1 0 (eq_attr "type" "fsqrt") 28 27) (define_function_unit "divider" 1 0 (eq_attr "type" "ddiv") 18 17) +(define_function_unit "divider" 1 0 (eq_attr "type" "dsqrt") 57 56) ;; ADD (define_insn "addsi3" @@ -134,10 +136,13 @@ DONE; }") +;; We indicate that LR0 is clobbered in the CALL_INSN itself. Otherwise, +;; reorg will think it is just clobbered by the called function. + (define_expand "call" [(parallel [(call (match_operand:SI 0 "" "") (match_operand 1 "" "")) - (clobber (reg:SI 32))]) + (clobber (scratch:SI))]) (match_operand 2 "" "")] "" " @@ -145,27 +150,18 @@ if (GET_CODE (operands[0]) != MEM) abort (); - if (! TARGET_SMALL_MEMORY - && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) - operands[0] = gen_rtx (MEM, GET_MODE (operands[0]), + if (! call_operand (XEXP (operands[0], 0), SImode)) + operands[0] = gen_rtx (MEM, SImode, force_reg (Pmode, XEXP (operands[0], 0))); operands[2] = gen_clobbers_to (operands[2]); }") -(define_insn "" - [(call (match_operand:SI 0 "memory_operand" "m") - (match_operand 1 "" "")) - (clobber (reg:SI 32))] - "" - "calli lr0,%0%#" - [(set_attr "type" "call")]) - (define_expand "call_value" [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") (call (match_operand:SI 1 "" "") (match_operand 2 "" ""))) - (clobber (reg:SI 32))]) + (clobber (scratch:SI))]) (match_operand 3 "" "")] "" " @@ -173,41 +169,44 @@ if (GET_CODE (operands[1]) != MEM) abort (); - if (! TARGET_SMALL_MEMORY - && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) - operands[1] = gen_rtx (MEM, GET_MODE (operands[1]), + if (! call_operand (XEXP (operands[1], 0), SImode)) + operands[1] = gen_rtx (MEM, SImode, force_reg (Pmode, XEXP (operands[1], 0))); operands[3] = gen_clobbers_to (operands[3]); }") (define_insn "" - [(set (match_operand 0 "gpc_reg_operand" "=r") - (call (match_operand:SI 1 "memory_operand" "m") - (match_operand 2 "" ""))) - (clobber (reg:SI 32))] - "" - "calli lr0,%1%#" + [(call (match_operand:SI 0 "memory_operand" "m") + (match_operand 1 "" "")) + (clobber (match_scratch:SI 2 "=l"))] + "GET_CODE (XEXP (operands[0], 0)) != CONST_INT" + "calli lr0,%0%#" [(set_attr "type" "call")]) (define_insn "" - [(call (mem:SI (match_operand:SI 0 "immediate_operand" "i")) + [(call (mem:SI (match_operand:SI 0 "call_operand" "i")) (match_operand:SI 1 "general_operand" "g")) - (clobber (reg:SI 32))] - "GET_CODE (operands[0]) == SYMBOL_REF - && (TARGET_SMALL_MEMORY - || ! strcmp (XSTR (operands[0], 0), current_function_name))" + (clobber (match_scratch:SI 2 "=l"))] + "" "call lr0,%F0" [(set_attr "type" "call")]) (define_insn "" [(set (match_operand 0 "gpc_reg_operand" "=r") - (call (mem:SI (match_operand:SI 1 "immediate_operand" "i")) + (call (match_operand:SI 1 "memory_operand" "m") + (match_operand 2 "" ""))) + (clobber (match_scratch:SI 3 "=l"))] + "GET_CODE (XEXP (operands[1], 0)) != CONST_INT" + "calli lr0,%1%#" + [(set_attr "type" "call")]) + +(define_insn "" + [(set (match_operand 0 "gpc_reg_operand" "=r") + (call (mem:SI (match_operand:SI 1 "call_operand" "i")) (match_operand:SI 2 "general_operand" "g"))) - (clobber (reg:SI 32))] - "GET_CODE (operands[1]) == SYMBOL_REF - && (TARGET_SMALL_MEMORY - || ! strcmp (XSTR (operands[1], 0), current_function_name))" + (clobber (match_scratch:SI 3 "=l"))] + "" "call lr0,%F1" [(set_attr "type" "call")]) @@ -248,31 +247,25 @@ (define_insn "" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") (const_int 16) - (match_operand:SI 1 "const_0_operand" "")) + (match_operand:SI 1 "const_0_operand" "I")) (match_operand:SI 2 "cint_16_operand" "J"))] "" - "* -{ operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) << 16); - return \"consth %0,%2\"; -}") + "consth %0,%m2") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0") - (const_int 65535)) + (ior:SI (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "0")) (match_operand:SI 2 "const_int_operand" "n")))] - "(INTVAL (operands[1]) & 0xffff) == 0" + "(INTVAL (operands[2]) & 0xffff) == 0" "consth %0,%2") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0") - (const_int 65535)) + (ior:SI (zero_extend:SI (match_operand:HI 1 "gpc_reg_operand" "0")) (and:SI (match_operand:SI 2 "immediate_operand" "i") (const_int -65536))))] "" "consth %0,%2") - ;; CONVERT (define_insn "fix_truncsfsi2" @@ -591,8 +584,9 @@ (const_int -256)) (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r") (const_int 8) - (ashift:SI (match_operand:SI 3 "register_operand" "b") - (const_int 3)))))] + (ashift:PSI + (match_operand:PSI 3 "register_operand" "b") + (const_int 3)))))] "" "exbyte %0,%2,%1") @@ -600,19 +594,21 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r") (const_int 8) - (ashift:SI (match_operand:SI 2 "register_operand" "b") - (const_int 3))))] + (ashift:PSI + (match_operand:PSI 2 "register_operand" "b") + (const_int 3))))] "" "exbyte %0,%1,0") (define_insn "" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") (const_int 8) - (match_operand:SI 1 "const_24_operand" "")) + (match_operand:PSI 1 "const_24_operand" "")) (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r") (const_int 8) - (ashift:SI (match_operand:SI 3 "register_operand" "b") - (const_int 3))))] + (ashift:PSI + (match_operand:PSI 3 "register_operand" "b") + (const_int 3))))] "" "exbyte %0,%2,%0") @@ -632,37 +628,19 @@ size = INTVAL (operands[2]); pos = INTVAL (operands[3]); - if ((size != 8 && size != 16) || pos % size != 0) - FAIL; - operands[3] = gen_rtx (ASHIFT, SImode, - force_reg (SImode, - gen_rtx (CONST_INT, VOIDmode, pos / 8)), - gen_rtx (CONST_INT, VOIDmode, 3)); -}") - -(define_expand "extv" - [(set (match_operand:SI 0 "gpc_reg_operand" "") - (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "") - (match_operand:SI 2 "general_operand" "") - (match_operand:SI 3 "general_operand" "")))] - "" - " -{ - int pos; + /* Can't do this unless a byte extraction. If extracting the high + or low byte, don't do this because a shift or AND is shorter. + Don't do 16-bit extracts, since the only two are the high and low + ends, and it is faster to do them with CONSTH and SRL. */ - if (GET_CODE (operands[2]) != CONST_INT - || GET_CODE (operands[3]) != CONST_INT) + if (size != 8 || (pos != 8 && pos != 16)) FAIL; - pos = INTVAL (operands[3]); - if (INTVAL (operands[2]) != 16 || pos % 16 != 0) - FAIL; + operands[3] = gen_rtx (ASHIFT, PSImode, + force_reg (PSImode, GEN_INT (pos / 8)), + GEN_INT (3)); - operands[3] = gen_rtx (ASHIFT, SImode, - force_reg (SImode, - gen_rtx (CONST_INT, VOIDmode, pos / 8)), - gen_rtx (CONST_INT, VOIDmode, 3)); }") ;; EXHW @@ -672,8 +650,9 @@ (const_int -65536)) (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r") (const_int 16) - (ashift:SI (match_operand:SI 3 "register_operand" "b") - (const_int 3)))))] + (ashift:PSI + (match_operand:PSI 3 "register_operand" "b") + (const_int 3)))))] "" "exhw %0,%2,%1") @@ -681,29 +660,38 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (zero_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r") (const_int 16) - (ashift:SI (match_operand:SI 2 "register_operand" "b") - (const_int 3))))] + (ashift:PSI + (match_operand:PSI 2 "register_operand" "b") + (const_int 3))))] "" "exhw %0,%1,0") (define_insn "" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") (const_int 16) - (match_operand:SI 1 "const_16_operand" "")) + (match_operand:PSI 1 "const_16_operand" "")) (zero_extract:SI (match_operand:SI 2 "gpc_reg_operand" "r") (const_int 16) - (ashift:SI (match_operand:SI 3 "register_operand" "b") - (const_int 3))))] + (ashift:PSI + (match_operand:PSI 3 "register_operand" "b") + (const_int 3))))] "" "exhw %0,%2,%0") ;; EXHWS +;; +;; This is probably unused. The high-order 16-bits are obtained with an SRA +;; insn. The low-order 16 bits are a sign-extend, which is a pair of +;; shifts. Setting BP followed by the insn is equivalent, so we don't +;; bother going to any trouble to generate this insn. + (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (sign_extract:SI (match_operand:SI 1 "gpc_reg_operand" "r") (const_int 16) - (ashift:SI (match_operand:SI 2 "register_operand" "b") - (const_int 3))))] + (ashift:PSI + (match_operand:PSI 2 "register_operand" "b") + (const_int 3))))] "" "exhws %0,%1") @@ -711,19 +699,26 @@ (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (reg:QI 178)))] + (match_operand:PSI 2 "register_operand" "f")))] "" "extract %0,%1,%1") (define_expand "rotlsi3" - [(set (reg:QI 178) - (match_operand: SI 2 "gpc_reg_or_immediate_operand" "")) + [(set (match_dup 3) + (match_operand:SI 2 "gpc_reg_or_immediate_operand" "")) (set (match_operand:SI 0 "gpc_reg_operand" "") (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "") - (reg:QI 178)))] + (match_dup 3)))] "" " -{ operands[2] = gen_lowpart (QImode, operands[2]); }") +{ operands[2] = gen_lowpart (PSImode, operands[2]); + operands[3] = gen_reg_rtx (PSImode); +}") + +;; It would be nice to be able to have a define_split corresponding to the +;; above, but there is no way to tell combine we need a PSImode temporary. +;; If we put a (clobber (scratch:PSI)) there, combine would merge the above +;; two insns. This is bad because it then thinks only one insn is needed. ;; FADD (define_expand "addsf3" @@ -898,32 +893,25 @@ (define_insn "" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") (const_int 8) - (ashift:SI (match_operand:SI 2 "register_operand" "b") - (const_int 3))) + (ashift:PSI + (match_operand:PSI 2 "register_operand" "b") + (const_int 3))) (match_operand:SI 1 "srcb_operand" "rI"))] "" "inbyte %0,%0,%1") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ior:SI (and:SI (not:SI (ashift:SI (const_int 255) - (ashift:SI (match_operand:SI 3 "register_operand" "b") - (const_int 3)))) - (match_operand:SI 1 "gpc_reg_operand" "r")) - (ashift:SI (and:SI (match_operand:SI 2 "srcb_operand" "rI") - (const_int 255)) - (match_operand:SI 4 "const_24_operand" ""))))] - "" - "inbyte %0,%1,%2") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ior:SI (and:SI (not:SI (ashift:SI (const_int 255) - (ashift:SI (match_operand:SI 3 "register_operand" "b") - (const_int 3)))) - (match_operand:SI 1 "gpc_reg_operand" "r")) - (ashift:SI (match_operand:SI 2 "srcb_operand" "rI") - (match_operand:SI 4 "const_24_operand" ""))))] + (ior:SI (and:SI + (not:SI + (ashift:SI (const_int 255) + (ashift:PSI + (match_operand:PSI 3 "register_operand" "b") + (const_int 3)))) + (match_operand:SI 1 "gpc_reg_operand" "r")) + (ashift:SI (zero_extend:SI + (match_operand:QI 2 "srcb_operand" "rI")) + (ashift:PSI (match_dup 3) (const_int 3)))))] "" "inbyte %0,%1,%2") @@ -931,32 +919,25 @@ (define_insn "" [(set (zero_extract:SI (match_operand:SI 0 "gpc_reg_operand" "+r") (const_int 16) - (ashift:SI (match_operand:SI 2 "register_operand" "b") - (const_int 3))) + (ashift:PSI + (match_operand:PSI 2 "register_operand" "b") + (const_int 3))) (match_operand:SI 1 "srcb_operand" "rI"))] "" "inhw %0,%0,%1") (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ior:SI (and:SI (not:SI (ashift:SI (const_int 65535) - (ashift:SI (match_operand:SI 3 "register_operand" "b") - (const_int 3)))) - (match_operand:SI 1 "gpc_reg_operand" "r")) - (ashift:SI (and:SI (match_operand:SI 2 "srcb_operand" "rI") - (const_int 65535)) - (match_operand:SI 4 "const_24_operand" ""))))] - "" - "inhw %0,%1,%2") - -(define_insn "" - [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (ior:SI (and:SI (not:SI (ashift:SI (const_int 65535) - (ashift:SI (match_operand:SI 3 "register_operand" "b") - (const_int 3)))) - (match_operand:SI 1 "gpc_reg_operand" "r")) - (ashift:SI (match_operand:SI 2 "srcb_operand" "rI") - (match_operand:SI 4 "const_24_operand" ""))))] + (ior:SI (and:SI + (not:SI + (ashift:SI (const_int 65535) + (ashift:PSI + (match_operand:PSI 3 "register_operand" "b") + (const_int 3)))) + (match_operand:SI 1 "gpc_reg_operand" "r")) + (ashift:SI (zero_extend:SI + (match_operand:HI 2 "srcb_operand" "rI")) + (ashift:PSI (match_dup 3) (const_int 3)))))] "" "inhw %0,%1,%2") @@ -979,10 +960,9 @@ if ((size != 8 && size != 16) || pos % size != 0) FAIL; - operands[2] = gen_rtx (ASHIFT, SImode, - force_reg (SImode, - gen_rtx (CONST_INT, VOIDmode, pos / 8)), - gen_rtx (CONST_INT, VOIDmode, 3)); + operands[2] = gen_rtx (ASHIFT, PSImode, + force_reg (PSImode, GEN_INT (pos / 8)), + GEN_INT (3)); }") ;; LOAD (also used by move insn). @@ -990,36 +970,61 @@ [(set (match_operand:SI 0 "gpc_reg_operand" "=r") (mem:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "r") (const_int -4)))) - (set (reg:SI 177) - (and:SI (match_dup 1) - (const_int 3)))] + (set (match_operand:PSI 2 "register_operand" "=b") + (truncate:PSI (match_dup 1)))] "! TARGET_DW_ENABLE" - "load 0,17,%0,%1" + "load 0,16,%0,%1" [(set_attr "type" "load")]) (define_insn "" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") - (mem:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "r") - (const_int -4)))) - (set (reg:SI 177) - (and:SI (match_dup 1) - (const_int 2)))] - "! TARGET_DW_ENABLE" - "load 0,18,%0,%1" + (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))] + "TARGET_DW_ENABLE" + "load 0,1,%0,%1" [(set_attr "type" "load")]) (define_insn "" - [(set (match_operand 0 "gpc_reg_operand" "=r") - (match_operator 2 "extend_operator" - [(match_operand 1 "memory_operand" "m")]))] - "TARGET_DW_ENABLE && GET_MODE (operands[0]) == GET_MODE (operands[2])" - "load 0,%X2,%0,%1" + [(set (match_operand:HI 0 "gpc_reg_operand" "=r") + (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))] + "TARGET_DW_ENABLE" + "load 0,1,%0,%1" + [(set_attr "type" "load")]) + +(define_insn "" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] + "TARGET_DW_ENABLE" + "load 0,2,%0,%1" + [(set_attr "type" "load")]) + +(define_insn "" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (sign_extend:SI (match_operand:QI 1 "memory_operand" "m"))) + (clobber (match_scratch:PSI 2 "=b"))] + "TARGET_DW_ENABLE" + "load 0,17,%0,%1" + [(set_attr "type" "load")]) + +(define_insn "" + [(set (match_operand:HI 0 "gpc_reg_operand" "=r") + (sign_extend:HI (match_operand:QI 1 "memory_operand" "m"))) + (clobber (match_scratch:PSI 2 "=b"))] + "TARGET_DW_ENABLE" + "load 0,17,%0,%1" + [(set_attr "type" "load")]) + +(define_insn "" + [(set (match_operand:SI 0 "gpc_reg_operand" "=r") + (sign_extend:SI (match_operand:HI 1 "memory_operand" "m"))) + (clobber (match_scratch:PSI 2 "=b"))] + "TARGET_DW_ENABLE" + "load 0,18,%0,%1" [(set_attr "type" "load")]) ;; LOADM (define_expand "load_multiple" - [(set (reg:SI 179) - (match_operand:SI 2 "const_int_operand" "")) + [(set (match_dup 4) + (match_operand:PSI 2 "const_int_operand" "")) (match_par_dup 3 [(set (match_operand:SI 0 "" "") (match_operand:SI 1 "" ""))])] "" @@ -1042,17 +1047,17 @@ regno = REGNO (operands[0]); /* CR gets set to the number of registers minus one. */ - operands[2] = gen_rtx (CONST_INT, VOIDmode, count - 1); + operands[2] = GEN_INT(count - 1); operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count + 2)); from = memory_address (SImode, XEXP (operands[1], 0)); XVECEXP (operands[3], 0, 0) = gen_rtx (SET, VOIDmode, gen_rtx (REG, SImode, regno), gen_rtx (MEM, SImode, from)); - XVECEXP (operands[3], 0, 1) - = gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, R_CR)); - XVECEXP (operands[3], 0, 2) - = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, R_CR)); + operands[4] = gen_reg_rtx (PSImode); + + XVECEXP (operands[3], 0, 1) = gen_rtx (USE, VOIDmode, operands[4]); + XVECEXP (operands[3], 0, 2) = gen_rtx (CLOBBER, VOIDmode, operands[4]); for (i = 1; i < count; i++) XVECEXP (operands[3], 0, i + 2) @@ -1064,8 +1069,8 @@ (define_insn "" [(set (match_operand 0 "gpc_reg_operand" "=r") (match_operand 1 "memory_operand" "m")) - (use (reg:SI 179)) - (clobber (reg:SI 179))] + (use (match_operand:PSI 2 "register_operand" "+c")) + (clobber (match_dup 2))] "GET_MODE (operands[0]) == GET_MODE (operands[1]) && GET_MODE_SIZE (GET_MODE (operands[0])) > UNITS_PER_WORD && ! TARGET_29050" @@ -1075,8 +1080,8 @@ (define_insn "" [(set (match_operand 0 "gpc_reg_operand" "=&r") (match_operand 1 "memory_operand" "m")) - (use (reg:SI 179)) - (clobber (reg:SI 179))] + (use (match_operand:PSI 2 "register_operand" "+c")) + (clobber (match_dup 2))] "GET_MODE (operands[0]) == GET_MODE (operands[1]) && GET_MODE_SIZE (GET_MODE (operands[0])) > UNITS_PER_WORD && TARGET_29050" @@ -1087,8 +1092,8 @@ [(match_parallel 0 "load_multiple_operation" [(set (match_operand:SI 1 "gpc_reg_operand" "=r") (match_operand:SI 2 "memory_operand" "m")) - (use (reg:SI 179)) - (clobber (reg:SI 179))])] + (use (match_operand:PSI 3 "register_operand" "+c")) + (clobber (match_dup 3))])] "! TARGET_29050" "loadm 0,0,%1,%2" [(set_attr "type" "load")]) @@ -1097,8 +1102,8 @@ [(match_parallel 0 "load_multiple_operation" [(set (match_operand:SI 1 "gpc_reg_operand" "=&r") (match_operand:SI 2 "memory_operand" "m")) - (use (reg:SI 179)) - (clobber (reg:SI 179))])] + (use (match_operand:PSI 3 "register_operand" "+c")) + (clobber (match_dup 3))])] "TARGET_29050" "loadm 0,0,%1,%2" [(set_attr "type" "load")]) @@ -1112,6 +1117,15 @@ "@ mtsr %0,%1 mtsrim %0,%1") + +(define_insn "" + [(set (match_operand:PSI 0 "register_operand" "=h,h") + (truncate:PSI + (match_operand:SI 1 "gpc_reg_or_immediate_operand" "r,i")))] + "" + "@ + mtsr %0,%1 + mtsrim %0,%1") ;; MULTIPLY, MULTM, MULTMU (define_insn "mulsi3" @@ -1258,6 +1272,21 @@ "" "sll %0,%1,%Q2") +;; SQRT +(define_insn "sqrtsf2" + [(set (match_operand:SF 0 "gpc_reg_operand" "=r") + (sqrt:SF (match_operand:SF 1 "gpc_reg_operand" "r")))] + "TARGET_29050" + "sqrt %0,%1,1" + [(set_attr "type" "fsqrt")]) + +(define_insn "sqrtdf2" + [(set (match_operand:DF 0 "gpc_reg_operand" "=r") + (sqrt:DF (match_operand:DF 1 "gpc_reg_operand" "r")))] + "TARGET_29050" + "sqrt %0,%1,2" + [(set_attr "type" "dsqrt")]) + ;; SRA (define_insn "ashrsi3" [(set (match_operand:SI 0 "gpc_reg_operand" "=r") @@ -1317,8 +1346,8 @@ }") (define_expand "store_multiple_no_bug" - [(set (reg:SI 179) - (match_operand:SI 2 "const_int_operand" "")) + [(set (match_dup 4) + (match_operand:PSI 2 "const_int_operand" "")) (match_par_dup 3 [(set (match_operand:SI 0 "" "") (match_operand:SI 1 "" ""))])] "" @@ -1341,17 +1370,16 @@ regno = REGNO (operands[1]); /* CR gets set to the number of registers minus one. */ - operands[2] = gen_rtx (CONST_INT, VOIDmode, count - 1); + operands[2] = GEN_INT(count - 1); operands[3] = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (count + 2)); from = memory_address (SImode, XEXP (operands[0], 0)); XVECEXP (operands[3], 0, 0) = gen_rtx (SET, VOIDmode, gen_rtx (MEM, SImode, from), gen_rtx (REG, SImode, regno)); - XVECEXP (operands[3], 0, 1) - = gen_rtx (USE, VOIDmode, gen_rtx (REG, SImode, R_CR)); - XVECEXP (operands[3], 0, 2) - = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, R_CR)); + operands[4] = gen_reg_rtx (PSImode); + XVECEXP (operands[3], 0, 1) = gen_rtx (USE, VOIDmode, operands[4]); + XVECEXP (operands[3], 0, 2) = gen_rtx (CLOBBER, VOIDmode, operands[4]); for (i = 1; i < count; i++) XVECEXP (operands[3], 0, i + 2) @@ -1389,7 +1417,7 @@ gen_rtx (MEM, SImode, from), gen_rtx (REG, SImode, regno)); XVECEXP (operands[3], 0, 1) - = gen_rtx (CLOBBER, VOIDmode, gen_rtx (REG, SImode, R_CR)); + = gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, PSImode)); for (i = 1; i < count; i++) XVECEXP (operands[3], 0, i + 1) @@ -1401,7 +1429,7 @@ (define_insn "" [(set (match_operand 0 "memory_operand" "=m") (match_operand 1 "gpc_reg_operand" "r")) - (clobber (reg:SI 179))] + (clobber (match_scratch:PSI 2 "=c"))] "!TARGET_NO_STOREM_BUG && GET_MODE (operands[0]) == GET_MODE (operands[1]) && GET_MODE_SIZE (GET_MODE (operands[0])) > UNITS_PER_WORD" @@ -1412,7 +1440,7 @@ [(match_parallel 0 "store_multiple_operation" [(set (match_operand:SI 1 "memory_operand" "=m") (match_operand:SI 2 "gpc_reg_operand" "r")) - (clobber (reg:SI 179))])] + (clobber (match_scratch:PSI 3 "=c"))])] "!TARGET_NO_STOREM_BUG" "mtsrim cr,%V0\;storem 0,0,%2,%1" [(set_attr "type" "multi")]) @@ -1420,8 +1448,8 @@ (define_insn "" [(set (match_operand 0 "memory_operand" "=m") (match_operand 1 "gpc_reg_operand" "r")) - (use (reg:SI 179)) - (clobber (reg:SI 179))] + (use (match_operand:PSI 2 "register_operand" "+c")) + (clobber (match_dup 2))] "TARGET_NO_STOREM_BUG && GET_MODE (operands[0]) == GET_MODE (operands[1]) && GET_MODE_SIZE (GET_MODE (operands[0])) > UNITS_PER_WORD" @@ -1432,8 +1460,8 @@ [(match_parallel 0 "store_multiple_operation" [(set (match_operand:SI 1 "memory_operand" "=m") (match_operand:SI 2 "gpc_reg_operand" "r")) - (use (reg:SI 179)) - (clobber (reg:SI 179))])] + (use (match_operand:PSI 3 "register_operand" "+c")) + (clobber (match_dup 3))])] "TARGET_NO_STOREM_BUG" "storem 0,0,%2,%1" [(set_attr "type" "store")]) @@ -1519,8 +1547,7 @@ target = operand_subword_force (operands[0], 0, SFmode); result = expand_binop (SImode, xor_optab, operand_subword_force (operands[1], 0, SFmode), - gen_rtx (CONST_INT, VOIDmode, 0x80000000), - target, 0, OPTAB_WIDEN); + GEN_INT(0x80000000), target, 0, OPTAB_WIDEN); if (result == 0) abort (); @@ -1550,8 +1577,7 @@ target = operand_subword (operands[0], 0, 1, DFmode); result = expand_binop (SImode, xor_optab, operand_subword_force (operands[1], 0, DFmode), - gen_rtx (CONST_INT, VOIDmode, 0x80000000), - target, 0, OPTAB_WIDEN); + GEN_INT(0x80000000), target, 0, OPTAB_WIDEN); if (result == 0) abort (); @@ -1644,6 +1670,21 @@ operands[1] = force_reg (SImode, operands[1]); }") +(define_expand "movpsi" + [(set (match_operand:PSI 0 "general_operand" "") + (match_operand:PSI 1 "general_operand" ""))] + "" + " +{ + if (GET_CODE (operands[0]) == MEM + && ! gpc_reg_operand (operands[1], PSImode)) + operands[1] = copy_to_mode_reg (PSImode, operands[1]); + else if (spec_reg_operand (operands[0], PSImode) + && ! (register_operand (operands[1], PSImode) + || cint_16_operand (operands[1], PSImode))) + operands[1] = force_reg (PSImode, operands[1]); +}") + (define_split [(set (match_operand:SI 0 "gpc_reg_operand" "") (match_operand:SI 1 "long_const_operand" ""))] @@ -1652,86 +1693,66 @@ (and:SI (match_dup 1) (const_int 65535))) (set (match_dup 0) - (ior:SI (and:SI (match_dup 0) - (const_int 65535)) + (ior:SI (zero_extend:SI (subreg:HI (match_dup 0) 0)) (and:SI (match_dup 1) (const_int -65536))))] "") -;; Subroutines to load/store halfwords. Use TAV (gr121) as scratch. We have -;; two versions of storehi, one when halfword writes are supported and one -;; where they aren't. +;; Subroutines to load/store halfwords. Operands 0 and 1 are the output and +;; input, respectively, except that the address is passed for a MEM instead +;; of the MEM itself and the short item is passed in QImode. +;; +;; Operand 2 is a scratch general register and operand 3 is a scratch register +;; used for BP. When called before reload, pseudos are passed for both +;; operands. During reload, R_TAV is used for the general register, and +;; a reload register of class BR_REGS (R_VP) for BP. +;; +;; We have two versions of the store operations, for when halfword writes are +;; supported and when they are not. (define_expand "loadhi" - [(parallel [(set (match_dup 2) - (mem:SI (and:SI (match_operand:SI 0 "gpc_reg_operand" "") + [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "") + (mem:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "") (const_int -4)))) - (set (reg:SI 177) - (and:SI (match_dup 0) - (const_int 2)))]) - (set (match_operand:HI 1 "gpc_reg_operand" "") + (set (match_operand:PSI 3 "register_operand" "") + (truncate:PSI (match_dup 1)))]) + (set (match_operand:SI 0 "gpc_reg_operand" "") (zero_extract:SI (match_dup 2) (const_int 16) - (ashift:SI (reg:SI 177) - (const_int 3))))] + (ashift:PSI (match_dup 3) (const_int 3))))] "" - " -{ operands[1] = gen_lowpart (SImode, operands[1]); - - if (reload_in_progress) - operands[2] = gen_rtx (REG, SImode, R_TAV); - else - operands[2] = gen_reg_rtx (SImode); -}") + "") (define_expand "storehinhww" - [(parallel [(set (match_dup 2) + [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "") (mem:SI (and:SI (match_operand:SI 0 "gpc_reg_operand" "") (const_int -4)))) - (set (reg:SI 177) - (and:SI (match_dup 0) - (const_int 2)))]) + (set (match_operand:PSI 3 "register_operand" "") + (truncate:PSI (match_dup 0)))]) (set (zero_extract:SI (match_dup 2) (const_int 16) - (ashift:SI (reg:SI 177) - (const_int 3))) - (match_operand:HI 1 "gpc_reg_operand" "")) + (ashift:PSI (match_dup 3) (const_int 3))) + (match_operand:SI 1 "gpc_reg_operand" "")) (set (mem:SI (match_dup 0)) (match_dup 2))] "" - " -{ operands[1] = gen_lowpart (SImode, operands[1]); - - if (reload_in_progress) - operands[2] = gen_rtx (REG, SImode, R_TAV); - else - operands[2] = gen_reg_rtx (SImode); -}") + "") (define_expand "storehihww" - [(set (reg:SI 177) - (and:SI (match_operand:SI 0 "gpc_reg_operand" "") - (const_int 3))) - (set (match_dup 2) + [(set (match_operand:PSI 3 "register_operand" "") + (truncate:PSI (match_operand:SI 0 "gpc_reg_operand" ""))) + (set (match_operand:SI 2 "gpc_reg_operand" "") (ior:SI (and:SI (not:SI (ashift:SI (const_int 65535) - (ashift:SI (reg:SI 177) - (const_int 3)))) - (match_operand:HI 1 "gpc_reg_operand" "")) - (ashift:SI (and:SI (match_dup 1) - (const_int 65535)) - (ashift:SI (reg:SI 177) - (const_int 3))))) + (ashift:PSI (match_dup 3) + (const_int 3)))) + (match_operand:SI 1 "gpc_reg_operand" "")) + (ashift:SI (zero_extend:SI (match_dup 4)) + (ashift:PSI (match_dup 3) (const_int 3))))) (set (mem:SI (and:SI (match_dup 0) (const_int -3))) (match_dup 2))] "" " -{ operands[1] = gen_lowpart (SImode, operands[1]); - - if (reload_in_progress) - operands[2] = gen_rtx (REG, SImode, R_TAV); - else - operands[2] = gen_reg_rtx (SImode); -}") +{ operands[4] = gen_lowpart (HImode, operands[1]); }") (define_expand "movhi" [(set (match_operand:HI 0 "general_operand" "") @@ -1744,10 +1765,17 @@ operands[1] = copy_to_mode_reg (HImode, operands[1]); if (! TARGET_DW_ENABLE) { + rtx general = gen_reg_rtx (SImode); + rtx bp = gen_reg_rtx (PSImode); + if (TARGET_BYTE_WRITES) - emit_insn (gen_storehihww (XEXP (operands[0], 0), operands[1])); + emit_insn (gen_storehihww (XEXP (operands[0], 0), + gen_lowpart (SImode, operands[1]), + general, bp)); else - emit_insn (gen_storehinhww (XEXP (operands[0], 0), operands[1])); + emit_insn (gen_storehinhww (XEXP (operands[0], 0), + gen_lowpart (SImode, operands[1]), + general, bp)); DONE; } } @@ -1755,84 +1783,105 @@ { if (! TARGET_DW_ENABLE) { - emit_insn (gen_loadhi (XEXP (operands[1], 0), operands[0])); + rtx general = gen_reg_rtx (SImode); + rtx bp = gen_reg_rtx (PSImode); + + emit_insn (gen_loadqi (gen_lowpart (SImode, operands[0]), + XEXP (operands[1], 0), general, bp)); DONE; } } }") + +(define_expand "reload_inhi" + [(parallel [(match_operand:SI 0 "register_operand" "=r") + (match_operand:SI 1 "reload_memory_operand" "m") + (match_operand:PSI 2 "register_operand" "=b")])] + "! TARGET_DW_ENABLE" + " +{ emit_insn (gen_loadhi (gen_lowpart (SImode, operands[0]), + a29k_get_reloaded_address (operands[1]), + gen_rtx (REG, SImode, R_TAV), + operands[2])); + DONE; +}") + +(define_expand "reload_outhi" + [(parallel [(match_operand:SI 0 "reload_memory_operand" "=m") + (match_operand:SI 1 "register_operand" "m") + (match_operand:PSI 2 "register_operand" "=b")])] + "! TARGET_DW_ENABLE" + " +{ if (TARGET_BYTE_WRITES) + emit_insn (gen_storehihww (a29k_get_reloaded_address (operands[0]), + gen_lowpart (SImode, operands[1]), + gen_rtx (REG, SImode, R_TAV), + operands[2])); + else + emit_insn (gen_storehinhww (a29k_get_reloaded_address (operands[0]), + gen_lowpart (SImode, operands[1]), + gen_rtx (REG, SImode, R_TAV), + operands[2])); + DONE; +}") -;; Subroutines to load/store bytes. Use TAV (gr121) as scratch. +;; Subroutines to load/store bytes. Operands 0 and 1 are the output and +;; input, respectively, except that the address is passed for a MEM instead +;; of the MEM itself and the short item is passed in QImode. +;; +;; Operand 2 is a scratch general register and operand 3 is a scratch register +;; used for BP. When called before reload, pseudos are passed for both +;; operands. During reload, R_TAV is used for the general register, and +;; a reload register of class BR_REGS (R_VP) for BP. +;; +;; We have two versions of the store operations, for when byte writes are +;; supported and when they are not. (define_expand "loadqi" - [(parallel [(set (match_dup 2) - (mem:SI (and:SI (match_operand:SI 0 "gpc_reg_operand" "") + [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "") + (mem:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "") (const_int -4)))) - (set (reg:SI 177) - (and:SI (match_dup 0) - (const_int 3)))]) - (set (match_operand:QI 1 "gpc_reg_operand" "") + (set (match_operand:PSI 3 "register_operand" "") + (truncate:PSI (match_dup 1)))]) + (set (match_operand:SI 0 "gpc_reg_operand" "") (zero_extract:SI (match_dup 2) (const_int 8) - (ashift:SI (reg:SI 177) - (const_int 3))))] + (ashift:PSI (match_dup 3) (const_int 3))))] "" - " -{ operands[1] = gen_lowpart (SImode, operands[1]); - - if (reload_in_progress) - operands[2] = gen_rtx (REG, SImode, R_TAV); - else - operands[2] = gen_reg_rtx (SImode); -}") + "") (define_expand "storeqinhww" - [(parallel [(set (match_dup 2) + [(parallel [(set (match_operand:SI 2 "gpc_reg_operand" "") (mem:SI (and:SI (match_operand:SI 0 "gpc_reg_operand" "") (const_int -4)))) - (set (reg:SI 177) - (and:SI (match_dup 0) - (const_int 3)))]) + (set (match_operand:PSI 3 "register_operand" "") + (truncate:PSI (match_dup 0)))]) (set (zero_extract:SI (match_dup 2) (const_int 8) - (ashift:SI (reg:SI 177) - (const_int 3))) - (match_operand:QI 1 "gpc_reg_operand" "")) + (ashift:PSI (match_dup 3) + (const_int 3))) + (match_operand:SI 1 "gpc_reg_operand" "")) (set (mem:SI (match_dup 0)) (match_dup 2))] "" - " -{ operands[1] = gen_lowpart (SImode, operands[1]); - - if (reload_in_progress) - operands[2] = gen_rtx (REG, SImode, R_TAV); - else - operands[2] = gen_reg_rtx (SImode); -}") + "") (define_expand "storeqihww" - [(set (reg:SI 177) - (and:SI (match_operand:SI 0 "gpc_reg_operand" "") - (const_int 3))) - (set (match_dup 2) + [(set (match_operand:PSI 3 "register_operand" "") + (truncate:PSI (match_operand:SI 0 "gpc_reg_operand" ""))) + (set (match_operand:SI 2 "gpc_reg_operand" "") (ior:SI (and:SI (not:SI (ashift:SI (const_int 255) - (ashift:SI (reg:SI 177) - (const_int 3)))) - (match_operand:HI 1 "gpc_reg_operand" "")) - (ashift:SI (and:SI (match_dup 1) - (const_int 255)) - (ashift:SI (reg:SI 177) - (const_int 3))))) + (ashift:PSI (match_dup 3) + (const_int 3)))) + (match_operand:SI 1 "gpc_reg_operand" "")) + (ashift:SI (zero_extend:SI (match_dup 4)) + (ashift:PSI (match_dup 3) + (const_int 3))))) (set (mem:SI (and:SI (match_dup 0) (const_int -4))) (match_dup 2))] "" " -{ operands[1] = gen_lowpart (SImode, operands[1]); - - if (reload_in_progress) - operands[2] = gen_rtx (REG, SImode, R_TAV); - else - operands[2] = gen_reg_rtx (SImode); -}") +{ operands[4] = gen_lowpart (QImode, operands[1]); }") (define_expand "movqi" [(set (match_operand:QI 0 "general_operand" "") @@ -1845,10 +1894,17 @@ operands[1] = copy_to_mode_reg (QImode, operands[1]); if (! TARGET_DW_ENABLE) { + rtx general = gen_reg_rtx (SImode); + rtx bp = gen_reg_rtx (PSImode); + if (TARGET_BYTE_WRITES) - emit_insn (gen_storeqihww (XEXP (operands[0], 0), operands[1])); + emit_insn (gen_storeqihww (XEXP (operands[0], 0), + gen_lowpart (SImode, operands[1]), + general, bp)); else - emit_insn (gen_storeqinhww (XEXP (operands[0], 0), operands[1])); + emit_insn (gen_storeqinhww (XEXP (operands[0], 0), + gen_lowpart (SImode, operands[1]), + general, bp)); DONE; } } @@ -1856,11 +1912,47 @@ { if (! TARGET_DW_ENABLE) { - emit_insn (gen_loadqi (XEXP (operands[1], 0), operands[0])); + rtx general = gen_reg_rtx (SImode); + rtx bp = gen_reg_rtx (PSImode); + + emit_insn (gen_loadqi (gen_lowpart (SImode, operands[0]), + XEXP (operands[1], 0), general, bp)); DONE; } } }") + +(define_expand "reload_inqi" + [(parallel [(match_operand:SI 0 "register_operand" "=r") + (match_operand:SI 1 "reload_memory_operand" "m") + (match_operand:PSI 2 "register_operand" "=b")])] + "! TARGET_DW_ENABLE" + " +{ emit_insn (gen_loadqi (gen_lowpart (SImode, operands[0]), + a29k_get_reloaded_address (operands[1]), + gen_rtx (REG, SImode, R_TAV), + operands[2])); + DONE; +}") + +(define_expand "reload_outqi" + [(parallel [(match_operand:SI 0 "reload_memory_operand" "=m") + (match_operand:SI 1 "register_operand" "m") + (match_operand:PSI 2 "register_operand" "=b")])] + "! TARGET_DW_ENABLE" + " +{ if (TARGET_BYTE_WRITES) + emit_insn (gen_storeqihww (a29k_get_reloaded_address (operands[0]), + gen_lowpart (SImode, operands[1]), + gen_rtx (REG, SImode, R_TAV), + operands[2])); + else + emit_insn (gen_storeqinhww (a29k_get_reloaded_address (operands[0]), + gen_lowpart (SImode, operands[1]), + gen_rtx (REG, SImode, R_TAV), + operands[2])); + DONE; +}") ;; Now the actual insns used to move data around. We include here the ;; DEFINE_SPLITs that may be needed. In some cases these will be @@ -1912,9 +2004,9 @@ }") (define_insn "" - [(set (match_operand:DF 0 "out_operand" "=r,r,r,m") + [(set (match_operand:DF 0 "out_operand" "=?r,?r,r,m") (match_operand:DF 1 "in_operand" "rE,F,m,r")) - (clobber (reg:SI 179))] + (clobber (match_scratch:PSI 2 "=X,X,&c,&c"))] "(gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode)) && ! TARGET_29050" @@ -1926,9 +2018,9 @@ [(set_attr "type" "multi")]) (define_insn "" - [(set (match_operand:DF 0 "out_operand" "=r,r,&r,m,*a,r") + [(set (match_operand:DF 0 "out_operand" "=?r,?r,&r,m,?*a,?r") (match_operand:DF 1 "in_operand" "rE,F,m,r,r,*a")) - (clobber (reg:SI 179))] + (clobber (match_scratch:PSI 2 "=X,X,&c,&c,X,X"))] "(gpc_reg_operand (operands[0], DFmode) || gpc_reg_operand (operands[1], DFmode)) && TARGET_29050" @@ -1951,29 +2043,29 @@ (define_split [(set (match_operand:DF 0 "gpc_reg_operand" "") (match_operand:DF 1 "gpc_reg_or_float_constant_operand" "")) - (clobber (reg:SI 179))] + (clobber (match_scratch:PSI 2 ""))] "reload_completed" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 4) (match_dup 5))] + [(set (match_dup 3) (match_dup 4)) + (set (match_dup 5) (match_dup 6))] " { if (GET_CODE (operands[1]) == REG && REGNO (operands[0]) == REGNO (operands[1]) + 1) { - operands[2] = operand_subword (operands[0], 1, 1, DFmode); - operands[3] = operand_subword (operands[1], 1, 1, DFmode); - operands[4] = operand_subword (operands[0], 0, 1, DFmode); - operands[5] = operand_subword (operands[1], 0, 1, DFmode); + operands[3] = operand_subword (operands[0], 1, 1, DFmode); + operands[4] = operand_subword (operands[1], 1, 1, DFmode); + operands[5] = operand_subword (operands[0], 0, 1, DFmode); + operands[6] = operand_subword (operands[1], 0, 1, DFmode); } else { - operands[2] = operand_subword (operands[0], 0, 1, DFmode); - operands[3] = operand_subword (operands[1], 0, 1, DFmode); - operands[4] = operand_subword (operands[0], 1, 1, DFmode); - operands[5] = operand_subword (operands[1], 1, 1, DFmode); + operands[3] = operand_subword (operands[0], 0, 1, DFmode); + operands[4] = operand_subword (operands[1], 0, 1, DFmode); + operands[5] = operand_subword (operands[0], 1, 1, DFmode); + operands[6] = operand_subword (operands[1], 1, 1, DFmode); } - if (operands[2] == 0 || operands[3] == 0 - || operands[4] == 0 || operands[5] == 0) + if (operands[3] == 0 || operands[4] == 0 + || operands[5] == 0 || operands[6] == 0) FAIL; }") @@ -1981,21 +2073,21 @@ (define_split [(set (match_operand:DF 0 "out_operand" "") (match_operand:DF 1 "in_operand" "")) - (clobber (reg:SI 179))] + (clobber (reg:PSI 179))] "TARGET_NO_STOREM_BUG && (memory_operand (operands[0], DFmode) || memory_operand (operands[1], DFmode))" - [(set (reg:SI 179) (const_int 1)) + [(set (reg:PSI 179) (const_int 1)) (parallel [(set (match_dup 0) (match_dup 1)) - (use (reg:SI 179)) - (clobber (reg:SI 179))])] + (use (reg:PSI 179)) + (clobber (reg:PSI 179))])] "") ;; DI move is similar to DF move. (define_insn "" - [(set (match_operand:DI 0 "out_operand" "=r,r,m") + [(set (match_operand:DI 0 "out_operand" "=?r,r,m") (match_operand:DI 1 "in_operand" "rn,m,r")) - (clobber (reg:SI 179))] + (clobber (match_scratch:PSI 2 "=X,&c,&c"))] "(gpc_reg_operand (operands[0], DImode) || gpc_reg_operand (operands[1], DImode)) && ! TARGET_29050" @@ -2006,9 +2098,9 @@ [(set_attr "type" "multi")]) (define_insn "" - [(set (match_operand:DI 0 "out_operand" "=r,&r,m") + [(set (match_operand:DI 0 "out_operand" "=?r,&r,m") (match_operand:DI 1 "in_operand" "rn,m,r")) - (clobber (reg:SI 179))] + (clobber (match_scratch:PSI 2 "=X,&c,&c"))] "(gpc_reg_operand (operands[0], DImode) || gpc_reg_operand (operands[1], DImode)) && TARGET_29050" @@ -2021,47 +2113,47 @@ (define_split [(set (match_operand:DI 0 "gpc_reg_operand" "") (match_operand:DI 1 "gpc_reg_or_integer_constant_operand" "")) - (clobber (reg:SI 179))] + (clobber (match_scratch:PSI 2 ""))] "reload_completed" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 4) (match_dup 5))] + [(set (match_dup 3) (match_dup 4)) + (set (match_dup 5) (match_dup 6))] " { if (GET_CODE (operands[1]) == REG && REGNO (operands[0]) == REGNO (operands[1]) + 1) { - operands[2] = operand_subword (operands[0], 1, 1, DImode); - operands[3] = operand_subword (operands[1], 1, 1, DImode); - operands[4] = operand_subword (operands[0], 0, 1, DImode); - operands[5] = operand_subword (operands[1], 0, 1, DImode); + operands[3] = operand_subword (operands[0], 1, 1, DImode); + operands[4] = operand_subword (operands[1], 1, 1, DImode); + operands[5] = operand_subword (operands[0], 0, 1, DImode); + operands[6] = operand_subword (operands[1], 0, 1, DImode); } else { - operands[2] = operand_subword (operands[0], 0, 1, DImode); - operands[3] = operand_subword (operands[1], 0, 1, DImode); - operands[4] = operand_subword (operands[0], 1, 1, DImode); - operands[5] = operand_subword (operands[1], 1, 1, DImode); + operands[3] = operand_subword (operands[0], 0, 1, DImode); + operands[4] = operand_subword (operands[1], 0, 1, DImode); + operands[5] = operand_subword (operands[0], 1, 1, DImode); + operands[6] = operand_subword (operands[1], 1, 1, DImode); } }") (define_split [(set (match_operand:DI 0 "out_operand" "") (match_operand:DI 1 "in_operand" "")) - (clobber (reg:SI 179))] + (clobber (reg:PSI 179))] "TARGET_NO_STOREM_BUG && (memory_operand (operands[0], DImode) || memory_operand (operands[1], DImode))" - [(set (reg:SI 179) (const_int 1)) + [(set (reg:PSI 179) (const_int 1)) (parallel [(set (match_dup 0) (match_dup 1)) - (use (reg:SI 179)) - (clobber (reg:SI 179))])] + (use (reg:PSI 179)) + (clobber (reg:PSI 179))])] "") ;; TImode moves are very similar to DImode moves, except that we can't ;; have constants. (define_insn "" - [(set (match_operand:TI 0 "out_operand" "=r,r,m") + [(set (match_operand:TI 0 "out_operand" "=?r,r,m") (match_operand:TI 1 "in_operand" "r,m,r")) - (clobber (reg:SI 179))] + (clobber (match_scratch:PSI 2 "=X,&c,&c"))] "(gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode)) && ! TARGET_29050" @@ -2072,9 +2164,9 @@ [(set_attr "type" "multi,multi,multi")]) (define_insn "" - [(set (match_operand:TI 0 "out_operand" "=r,&r,m") + [(set (match_operand:TI 0 "out_operand" "=?r,&r,m") (match_operand:TI 1 "in_operand" "r,m,r")) - (clobber (reg:SI 179))] + (clobber (match_scratch:PSI 2 "=X,&c,&c"))] "(gpc_reg_operand (operands[0], TImode) || gpc_reg_operand (operands[1], TImode)) && TARGET_29050" @@ -2087,50 +2179,50 @@ (define_split [(set (match_operand:TI 0 "gpc_reg_operand" "") (match_operand:TI 1 "gpc_reg_operand" "")) - (clobber (reg:SI 179))] + (clobber (match_scratch:PSI 2 ""))] "reload_completed" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 4) (match_dup 5)) - (set (match_dup 6) (match_dup 7)) - (set (match_dup 8) (match_dup 9))] + [(set (match_dup 3) (match_dup 4)) + (set (match_dup 5) (match_dup 6)) + (set (match_dup 7) (match_dup 8)) + (set (match_dup 9) (match_dup 10))] " { if (REGNO (operands[0]) >= REGNO (operands[1]) + 1 && REGNO (operands[0]) <= REGNO (operands[1]) + 3) { - operands[2] = gen_rtx (REG, SImode, REGNO (operands[0]) + 3); - operands[3] = gen_rtx (REG, SImode, REGNO (operands[1]) + 3); - operands[4] = gen_rtx (REG, SImode, REGNO (operands[0]) + 2); - operands[5] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2); - operands[6] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - operands[7] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - operands[8] = gen_rtx (REG, SImode, REGNO (operands[0])); - operands[9] = gen_rtx (REG, SImode, REGNO (operands[1])); + operands[3] = gen_rtx (REG, SImode, REGNO (operands[0]) + 3); + operands[4] = gen_rtx (REG, SImode, REGNO (operands[1]) + 3); + operands[5] = gen_rtx (REG, SImode, REGNO (operands[0]) + 2); + operands[6] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2); + operands[7] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); + operands[8] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); + operands[9] = gen_rtx (REG, SImode, REGNO (operands[0])); + operands[10] = gen_rtx (REG, SImode, REGNO (operands[1])); } else { - operands[2] = gen_rtx (REG, SImode, REGNO (operands[0])); - operands[3] = gen_rtx (REG, SImode, REGNO (operands[1])); - operands[4] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - operands[5] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); - operands[6] = gen_rtx (REG, SImode, REGNO (operands[0]) + 2); - operands[7] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2); - operands[8] = gen_rtx (REG, SImode, REGNO (operands[0]) + 3); - operands[9] = gen_rtx (REG, SImode, REGNO (operands[1]) + 3); + operands[3] = gen_rtx (REG, SImode, REGNO (operands[0])); + operands[4] = gen_rtx (REG, SImode, REGNO (operands[1])); + operands[5] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); + operands[6] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1); + operands[7] = gen_rtx (REG, SImode, REGNO (operands[0]) + 2); + operands[8] = gen_rtx (REG, SImode, REGNO (operands[1]) + 2); + operands[9] = gen_rtx (REG, SImode, REGNO (operands[0]) + 3); + operands[10] = gen_rtx (REG, SImode, REGNO (operands[1]) + 3); } }") (define_split [(set (match_operand:TI 0 "out_operand" "") (match_operand:TI 1 "in_operand" "")) - (clobber (reg:SI 179))] + (clobber (reg:PSI 179))] "TARGET_NO_STOREM_BUG && (memory_operand (operands[0], TImode) || memory_operand (operands[1], TImode))" - [(set (reg:SI 179) (const_int 1)) + [(set (reg:PSI 179) (const_int 1)) (parallel [(set (match_dup 0) (match_dup 1)) - (use (reg:SI 179)) - (clobber (reg:SI 179))])] + (use (reg:PSI 179)) + (clobber (reg:PSI 179))])] "") (define_insn "" @@ -2175,11 +2267,30 @@ mtsrim %0,%1" [(set_attr "type" "misc,misc,misc,misc,multi,load,misc,store,misc,misc")]) +(define_insn "" + [(set (match_operand:PSI 0 "out_operand" "=*r,*r,*r,*r,m,h,h") + (match_operand:PSI 1 "in_operand" "r,i,m,h,r,r,J"))] + "(gpc_reg_operand (operands[0], PSImode) + || gpc_reg_operand (operands[1], PSImode) + || (spec_reg_operand (operands[0], PSImode) + && cint_16_operand (operands[1], PSImode)))" + "@ + sll %0,%1,0 + const %0,%1 + load 0,0,%0,%1 + mfsr %0,%1 + store 0,0,%1,%0 + mtsr %0,%1 + mtsrim %0,%1" + [(set_attr "type" "misc,multi,load,misc,store,misc,misc")]) + (define_insn "" [(set (match_operand:HI 0 "out_operand" "=r,r,r,m,r,*h,*h") (match_operand:HI 1 "in_operand" "r,i,m,r,*h,r,i"))] "gpc_reg_operand (operands[0], HImode) - || gpc_reg_operand (operands[1], HImode)" + || gpc_reg_operand (operands[1], HImode) + || (spec_reg_operand (operands[0], HImode) + && cint_16_operand (operands[1], HImode))" "@ sll %0,%1,0 const %0,%1 @@ -2194,7 +2305,9 @@ [(set (match_operand:QI 0 "out_operand" "=r,r,r,m,r,*h,*h") (match_operand:QI 1 "in_operand" "r,i,m,r,*h,r,i"))] "gpc_reg_operand (operands[0], QImode) - || gpc_reg_operand (operands[1], QImode)" + || gpc_reg_operand (operands[1], QImode) + || (spec_reg_operand (operands[0], HImode) + && cint_16_operand (operands[1], HImode))" "@ sll %0,%1,0 const %0,%1 @@ -2214,11 +2327,11 @@ ;; ;; In other cases, handle similarly to SImode moves. ;; -;; However, indicate that DI, TI, and DF moves (can) clobber CR (reg 179). +;; However, indicate that DI, TI, and DF moves may clobber CR (reg 179). (define_expand "movdi" [(parallel [(set (match_operand:DI 0 "general_operand" "") (match_operand:DI 1 "general_operand" "")) - (clobber (reg:SI 179))])] + (clobber (scratch:PSI))])] "" " { @@ -2238,7 +2351,7 @@ (define_expand "movdf" [(parallel [(set (match_operand:DF 0 "general_operand" "") (match_operand:DF 1 "general_operand" "")) - (clobber (reg:SI 179))])] + (clobber (scratch:PSI))])] "" " { if (GET_CODE (operands[0]) == MEM) @@ -2248,7 +2361,7 @@ (define_expand "movti" [(parallel [(set (match_operand:TI 0 "general_operand" "") (match_operand:TI 1 "general_operand" "")) - (clobber (reg:SI 179))])] + (clobber (scratch:PSI))])] "" " { @@ -2285,6 +2398,50 @@ } }") +;; Here are the variants of the above for use during reload. + +(define_expand "reload_indf" + [(parallel [(set (match_operand:DF 0 "register_operand" "=r") + (match_operand:DF 1 "reload_memory_operand" "m")) + (clobber (match_operand:PSI 2 "register_operand" "=&b"))])] + "" + "") + +(define_expand "reload_outdf" + [(parallel [(set (match_operand:DF 0 "reload_memory_operand" "=m") + (match_operand:DF 1 "register_operand" "r")) + (clobber (match_operand:PSI 2 "register_operand" "=&b"))])] + "" + "") + +(define_expand "reload_indi" + [(parallel [(set (match_operand:DI 0 "register_operand" "=r") + (match_operand:DI 1 "reload_memory_operand" "m")) + (clobber (match_operand:PSI 2 "register_operand" "=&b"))])] + "" + "") + +(define_expand "reload_outdi" + [(parallel [(set (match_operand:DI 0 "reload_memory_operand" "=m") + (match_operand:DI 1 "register_operand" "r")) + (clobber (match_operand:PSI 2 "register_operand" "=&b"))])] + "" + "") + +(define_expand "reload_inti" + [(parallel [(set (match_operand:TI 0 "register_operand" "=r") + (match_operand:TI 1 "reload_memory_operand" "m")) + (clobber (match_operand:PSI 2 "register_operand" "=&b"))])] + "" + "") + +(define_expand "reload_outti" + [(parallel [(set (match_operand:TI 0 "reload_memory_operand" "=m") + (match_operand:TI 1 "register_operand" "r")) + (clobber (match_operand:PSI 2 "register_operand" "=&b"))])] + "" + "") + ;; For compare operations, we simply store the comparison operands and ;; do nothing else. The following branch or scc insn will output whatever ;; is needed. -- 2.30.2