--- gcc/config/a29k.md 2018/04/24 17:58:28 1.1.1.3 +++ gcc/config/a29k.md 2018/04/24 18:03:49 1.1.1.4 @@ -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". @@ -47,8 +47,11 @@ [(eq_attr "in_delay_slot" "yes") (nil) (nil)]) ;; Define the function unit usages. We first define memory as a unit. -(define_function_unit "memory" 1 2 (eq_attr "type" "load") 6 11) -(define_function_unit "memory" 1 2 (eq_attr "type" "store") 1 0) +(define_function_unit "memory" 1 0 (eq_attr "type" "load") 6 5 + [(eq_attr "type" "load")]) +(define_function_unit "memory" 1 0 (eq_attr "type" "load") 6 6 + [(eq_attr "type" "store")]) +(define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0) ;; Now define the function units for the floating-point support. Most ;; units are pipelined and can accept an input every cycle. @@ -59,14 +62,16 @@ ;; floating-point rounder. It isn't clear how to represent this. (define_function_unit "multiplier" 1 0 (eq_attr "type" "fmul") 3 0) -(define_function_unit "multiplier" 1 0 (eq_attr "type" "dmul") 6 8) -(define_function_unit "multiplier" 1 0 (eq_attr "type" "fam") 6 8) -(define_function_unit "multiplier" 1 0 (eq_attr "type" "dam") 9 8) +(define_function_unit "multiplier" 1 0 (eq_attr "type" "dmul") 6 4) +(define_function_unit "multiplier" 1 0 (eq_attr "type" "fam") 6 0) +(define_function_unit "multiplier" 1 0 (eq_attr "type" "dam") 9 4) (define_function_unit "adder" 1 0 (eq_attr "type" "fadd,fam,dam") 3 0) -(define_function_unit "divider" 1 1 (eq_attr "type" "fdiv") 11 20) -(define_function_unit "divider" 1 1 (eq_attr "type" "ddiv") 18 34) +(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" @@ -131,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 "" "")] "" " @@ -142,27 +150,21 @@ if (GET_CODE (operands[0]) != MEM) abort (); + /* We tell here whether this is a recursive call, since this insn may + later be inlined into another function. */ if (! TARGET_SMALL_MEMORY && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) - operands[0] = gen_rtx (MEM, GET_MODE (operands[0]), + 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 "" "")] "" " @@ -170,41 +172,47 @@ if (GET_CODE (operands[1]) != MEM) abort (); + /* We tell here whether this is a recursive call, since this insn may + later be inlined into another function. */ if (! TARGET_SMALL_MEMORY && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) - operands[1] = gen_rtx (MEM, GET_MODE (operands[1]), + 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,28 +256,22 @@ (match_operand:SI 1 "const_0_operand" "")) (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" @@ -382,7 +384,7 @@ "TARGET_29050" "@ dadd %0,%1,%2 - dmac 8,%0,%1,0" + dmac 8,%0,%1,%1" [(set_attr "type" "fadd,dam")]) ;; DDIV @@ -506,7 +508,7 @@ (minus:DF (neg:DF (match_operand:DF 1 "register_operand" "r")) (match_operand:DF 2 "register_operand" "0")))] "TARGET_29050" - "dmac 11,%0,%1,0" + "dmac 11,%0,%1,%1" [(set_attr "type" "dam")]) (define_insn "" @@ -514,7 +516,7 @@ (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "%r") (match_operand:DF 2 "register_operand" "0"))))] "TARGET_29050" - "dmac 11,%0,%1,0" + "dmac 11,%0,%1,%1" [(set_attr "type" "dam")]) (define_insn "" @@ -525,7 +527,7 @@ "@ cpeq %2,gr1,gr1\;xor %0,%1,%2 cpeq %2,gr1,gr1\;xor %0,%1,%2\;sll %L0,%L1,0 - dmac 13,%0,%1,0" + dmac 13,%0,%1,%1" [(set_attr "type" "multi,multi,dam")]) ;; DMUL @@ -577,8 +579,8 @@ "TARGET_29050" "@ dsub %0,%1,%2 - dmac 9,%0,%2,0 - dmac 10,%0,%1,0" + dmac 9,%0,%2,%2 + dmac 10,%0,%1,%1" [(set_attr "type" "fadd,dam,dam")]) ;; EXBYTE @@ -588,8 +590,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") @@ -597,19 +600,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") @@ -629,37 +634,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 @@ -669,8 +656,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") @@ -678,29 +666,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") @@ -708,19 +705,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" @@ -745,13 +749,13 @@ "TARGET_29050" "@ fadd %0,%1,%2 - fmac 8,%0,%1,0" + fmac 8,%0,%1,%1" [(set_attr "type" "fadd,fam")]) ;; FDIV (define_insn "divsf3" [(set (match_operand:SF 0 "register_operand" "=r") - (div:DF (match_operand:SF 1 "register_operand" "=r") + (div:SF (match_operand:SF 1 "register_operand" "=r") (match_operand:SF 2 "register_operand" "r")))] "" "fdiv %0,%1,%2" @@ -817,7 +821,7 @@ (minus:SF (neg:SF (match_operand:SF 1 "register_operand" "%r")) (match_operand:SF 2 "register_operand" "0")))] "TARGET_29050" - "fmac 11,%0,%1,0" + "fmac 11,%0,%1,%1" [(set_attr "type" "fam")]) (define_insn "" @@ -825,7 +829,7 @@ (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "%r") (match_operand:SF 2 "register_operand" "0"))))] "TARGET_29050" - "fmac 11,%0,%1,0" + "fmac 11,%0,%1,%1" [(set_attr "type" "fam")]) (define_insn "" @@ -835,7 +839,7 @@ "TARGET_29050" "@ cpeq %2,gr1,gr1\;xor %0,%1,%2 - fmac 13,%0,%1,0" + fmac 13,%0,%1,%1" [(set_attr "type" "multi,fam")]) ;; FMUL @@ -887,40 +891,33 @@ "TARGET_29050" "@ fsub %0,%1,%2 - fmac 9,%0,%2,0 - fmac 10,%0,%1,0" + fmac 9,%0,%2,%2 + fmac 10,%0,%1,%1" [(set_attr "type" "fadd,fam,fam")]) ;; INBYTE (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") @@ -928,32 +925,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") @@ -976,10 +966,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). @@ -987,38 +976,63 @@ [(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_dup 2)) - (match_parallel 3 "" [(set (match_operand:SI 0 "" "") - (match_operand:SI 1 "" ""))])] + [(set (match_dup 4) + (match_operand:PSI 2 "const_int_operand" "")) + (match_par_dup 3 [(set (match_operand:SI 0 "" "") + (match_operand:SI 1 "" ""))])] "" " { @@ -1039,17 +1053,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) @@ -1061,8 +1075,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" @@ -1072,8 +1086,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" @@ -1084,8 +1098,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")]) @@ -1094,8 +1108,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")]) @@ -1109,6 +1123,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" @@ -1255,6 +1278,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") @@ -1314,10 +1352,10 @@ }") (define_expand "store_multiple_no_bug" - [(set (reg:SI 179) - (match_dup 2)) - (match_parallel 3 "" [(set (match_operand:SI 0 "" "") - (match_operand:SI 1 "" ""))])] + [(set (match_dup 4) + (match_operand:PSI 2 "const_int_operand" "")) + (match_par_dup 3 [(set (match_operand:SI 0 "" "") + (match_operand:SI 1 "" ""))])] "" " { @@ -1338,17 +1376,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) @@ -1358,8 +1395,9 @@ }") (define_expand "store_multiple_bug" - [(match_parallel 3 "" [(set (match_operand:SI 0 "" "") - (match_operand:SI 1 "" ""))])] + [(match_par_dup 3 [(set (match_operand:SI 0 "" "") + (match_operand:SI 1 "" "")) + (use (match_operand:SI 2 "" ""))])] "" " { @@ -1385,7 +1423,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) @@ -1397,7 +1435,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" @@ -1408,7 +1446,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")]) @@ -1416,8 +1454,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" @@ -1428,8 +1466,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")]) @@ -1515,8 +1553,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 (); @@ -1546,8 +1583,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 (); @@ -1640,6 +1676,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" ""))] @@ -1648,86 +1699,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 (match_dup 2)) (and:SI (match_dup 1) (const_int -65536))))] - "") + " operands[2] = gen_lowpart (HImode, operands[0]); ") -;; 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 8) - (ashift:SI (reg:SI 177) - (const_int 3))) - (match_operand:HI 1 "gpc_reg_operand" "")) + (const_int 16) + (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" "") @@ -1740,10 +1771,16 @@ operands[1] = copy_to_mode_reg (HImode, operands[1]); if (! TARGET_DW_ENABLE) { - if (TARGET_BYTE_WRITES) - emit_insn (gen_storehihww (XEXP (operands[0], 0), operands[1])); - else - emit_insn (gen_storehinhww (XEXP (operands[0], 0), operands[1])); + rtx general = gen_reg_rtx (SImode); + rtx bp = gen_reg_rtx (PSImode); + rtx (*fcn) () + = TARGET_BYTE_WRITES ? gen_storehihww : gen_storehinhww; + rtx seq = (*fcn) (XEXP (operands[0], 0), + gen_lowpart (SImode, operands[1]), + general, bp); + + a29k_set_memflags (seq, operands[0]); + emit_insn (seq); DONE; } } @@ -1751,84 +1788,107 @@ { 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); + rtx seq = gen_loadqi (gen_lowpart (SImode, operands[0]), + XEXP (operands[1], 0), general, bp); + + a29k_set_memflags (seq, operands[1]); + emit_insn (seq); 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" + " +{ rtx seq = gen_loadhi (gen_lowpart (SImode, operands[0]), + a29k_get_reloaded_address (operands[1]), + gen_rtx (REG, SImode, R_TAV), + operands[2]); + + a29k_set_memflags (seq, operands[1]); + emit_insn (seq); + 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" + " +{ rtx (*fcn) () = TARGET_BYTE_WRITES ? gen_storehihww : gen_storehinhww; + rtx seq = (*fcn) (a29k_get_reloaded_address (operands[0]), + gen_lowpart (SImode, operands[1]), + gen_rtx (REG, SImode, R_TAV), operands[2]); + + a29k_set_memflags (seq, operands[0]); + emit_insn (seq); + 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" "") @@ -1841,22 +1901,65 @@ operands[1] = copy_to_mode_reg (QImode, operands[1]); if (! TARGET_DW_ENABLE) { - if (TARGET_BYTE_WRITES) - emit_insn (gen_storeqihww (XEXP (operands[0], 0), operands[1])); - else - emit_insn (gen_storeqinhww (XEXP (operands[0], 0), operands[1])); - DONE; + rtx general = gen_reg_rtx (SImode); + rtx bp = gen_reg_rtx (PSImode); + rtx (*fcn) () + = TARGET_BYTE_WRITES ? gen_storeqihww : gen_storeqinhww; + rtx seq = (*fcn) (XEXP (operands[0], 0), + gen_lowpart (SImode, operands[1]), + general, bp); + + a29k_set_memflags (seq, operands[0]); + emit_insn (seq); } } else if (GET_CODE (operands[1]) == MEM) { 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); + rtx seq = gen_loadqi (gen_lowpart (SImode, operands[0]), + XEXP (operands[1], 0), general, bp); + + a29k_set_memflags (seq, operands[1]); + emit_insn (seq); 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" + " +{ rtx seq = gen_loadqi (gen_lowpart (SImode, operands[0]), + a29k_get_reloaded_address (operands[1]), + gen_rtx (REG, SImode, R_TAV), + operands[2]); + + a29k_set_memflags (seq, operands[1]); + emit_insn (seq); + 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" + " +{ rtx (*fcn) () = TARGET_BYTE_WRITES ? gen_storeqihww : gen_storeqinhww; + rtx seq = (*fcn) (a29k_get_reloaded_address (operands[0]), + gen_lowpart (SImode, operands[1]), + gen_rtx (REG, SImode, R_TAV), operands[2]); + + a29k_set_memflags (seq, operands[0]); + emit_insn (seq); + 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 @@ -1908,9 +2011,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" @@ -1922,9 +2025,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" @@ -1947,29 +2050,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; }") @@ -1977,21 +2080,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" @@ -2002,9 +2105,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" @@ -2017,47 +2120,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" @@ -2068,9 +2171,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" @@ -2083,50 +2186,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 "" @@ -2172,10 +2275,29 @@ [(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 @@ -2190,7 +2312,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 @@ -2210,11 +2334,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))])] "" " { @@ -2234,7 +2358,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) @@ -2244,14 +2368,87 @@ (define_expand "movti" [(parallel [(set (match_operand:TI 0 "general_operand" "") (match_operand:TI 1 "general_operand" "")) - (clobber (reg:SI 179))])] + (clobber (scratch:PSI))])] "" " { if (GET_CODE (operands[0]) == MEM) operands[1] = force_reg (TImode, operands[1]); + + /* We can't handle constants in general because there is no rtl to represent + 128 bit constants. Splitting happens to work for CONST_INTs so we split + them for good code. Other constants will get forced to memory. */ + + if (GET_CODE (operands[1]) == CONST_INT) + { + rtx part0, part1, part2, part3; + + part0 = operand_subword (operands[0], 0, 1, TImode); + part1 = operand_subword (operands[0], 1, 1, TImode); + part2 = operand_subword (operands[0], 2, 1, TImode); + part3 = operand_subword (operands[0], 3, 1, TImode); + + emit_move_insn (part0, const0_rtx); + emit_move_insn (part1, const0_rtx); + emit_move_insn (part2, const0_rtx); + emit_move_insn (part3, const0_rtx); + + DONE; + } + else if (CONSTANT_P (operands[1])) + { + operands[1] = force_const_mem (TImode, operands[1]); + if (! memory_address_p (TImode, XEXP (operands[1], 0)) + && ! reload_in_progress) + operands[1] = change_address (operands[1], TImode, + XEXP (operands[1], 0)); + } }") +;; 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" "=&c"))])] + "" + "") + +(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" "=&c"))])] + "" + "") + +(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" "=&c"))])] + "" + "") + +(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" "=&c"))])] + "" + "") + +(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" "=&c"))])] + "" + "") + +(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" "=&c"))])] + "" + "") + ;; For compare operations, we simply store the comparison operands and ;; do nothing else. The following branch or scc insn will output whatever ;; is needed.