--- gcc/config/alpha/alpha.md 2018/04/24 18:22:30 1.1.1.3 +++ gcc/config/alpha/alpha.md 2018/04/24 18:30:13 1.1.1.4 @@ -1,5 +1,5 @@ ;; Machine description for DEC Alpha for GNU C compiler -;; Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +;; Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ;; This file is part of GNU CC. @@ -16,7 +16,8 @@ ;; You should have received a copy of the GNU General Public License ;; along with GNU CC; see the file COPYING. If not, write to -;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;; the Free Software Foundation, 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. @@ -275,10 +276,10 @@ ;; seem to be a way around it. Only recognize them while reloading. (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=&r") - (plus:DI (plus:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "register_operand" "r")) - (match_operand:DI 3 "add_operand" "rIOKL")))] + [(set (match_operand:DI 0 "some_operand" "=&r") + (plus:DI (plus:DI (match_operand:DI 1 "some_operand" "r") + (match_operand:DI 2 "some_operand" "r")) + (match_operand:DI 3 "some_operand" "rIOKL")))] "reload_in_progress" "#" [(set_attr "type" "iaddlog")]) @@ -294,11 +295,11 @@ "") (define_insn "" - [(set (match_operand:SI 0 "register_operand" "=&r") + [(set (match_operand:SI 0 "some_operand" "=&r") (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "some_operand" "rJ") (match_operand:SI 2 "const48_operand" "I")) - (match_operand:SI 3 "register_operand" "r")) - (match_operand:SI 4 "add_operand" "rIOKL")))] + (match_operand:SI 3 "some_operand" "r")) + (match_operand:SI 4 "some_operand" "rIOKL")))] "reload_in_progress" "#" [(set_attr "type" "iaddlog")]) @@ -316,13 +317,13 @@ "") (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=&r") + [(set (match_operand:DI 0 "some_operand" "=&r") (sign_extend:DI (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "some_operand" "rJ") (match_operand:SI 2 "const48_operand" "I")) - (match_operand:SI 3 "register_operand" "r")) - (match_operand:SI 4 "add_operand" "rIOKL"))))] + (match_operand:SI 3 "some_operand" "r")) + (match_operand:SI 4 "some_operand" "rIOKL"))))] "reload_in_progress" "#" [(set_attr "type" "iaddlog")]) @@ -344,13 +345,13 @@ }") (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=&r") + [(set (match_operand:DI 0 "some_operand" "=&r") (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "some_operand" "rJ") (match_operand:DI 2 "const48_operand" "I")) - (match_operand:DI 3 "register_operand" "r")) - (match_operand:DI 4 "add_operand" "rIOKL")))] + (match_operand:DI 3 "some_operand" "r")) + (match_operand:DI 4 "some_operand" "rIOKL")))] "reload_in_progress" - "s%2addq %r1,%3,%0\;addq %0,%4,%0" + "#" [(set_attr "type" "iaddlog")]) (define_split @@ -785,21 +786,24 @@ }" [(set_attr "type" "iaddlog,shiftcm")]) -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (sign_extend:DI - (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") - (match_operand:DI 2 "const_int_operand" "P")) - 0)))] - "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3" - "* -{ - if (operands[2] == const1_rtx) - return \"addl %r1,%r1,%0\"; - else - return \"s%P2addl %r1,0,%0\"; -}" - [(set_attr "type" "iaddlog")]) +;; ??? The following pattern is made by combine, but earlier phases +;; (specifically flow) can't handle it. This occurs in jump.c. Deal +;; with this in a better way at some point. +;;(define_insn "" +;; [(set (match_operand:DI 0 "register_operand" "=r") +;; (sign_extend:DI +;; (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") +;; (match_operand:DI 2 "const_int_operand" "P")) +;; 0)))] +;; "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3" +;; "* +;;{ +;; if (operands[2] == const1_rtx) +;; return \"addl %r1,%r1,%0\"; +;; else +;; return \"s%P2addl %r1,0,%0\"; +;; }" +;; [(set_attr "type" "iaddlog")]) (define_insn "lshrdi3" [(set (match_operand:DI 0 "register_operand" "=r") @@ -1301,18 +1305,38 @@ "cmple $31,%1,%0" [(set_attr "type" "icmp")]) +;; This pattern exists so conditional moves of SImode values are handled. +;; Comparisons are still done in DImode though. + (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r,r") + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") (if_then_else:DI (match_operator 2 "signed_comparison_operator" - [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ") - (const_int 0)]) - (match_operand:DI 1 "reg_or_8bit_operand" "rI,0") - (match_operand:DI 4 "reg_or_8bit_operand" "0,rI")))] - "" + [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J") + (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")]) + (match_operand:SI 1 "reg_or_8bit_operand" "rI,0,rI,0") + (match_operand:SI 5 "reg_or_8bit_operand" "0,rI,0,rI")))] + "operands[3] == const0_rtx || operands[4] == const0_rtx" "@ cmov%C2 %r3,%1,%0 - cmov%D2 %r3,%4,%0") + cmov%D2 %r3,%5,%0 + cmov%c2 %r4,%1,%0 + cmov%d2 %r4,%5,%0") + +(define_insn "" + [(set (match_operand:DI 0 "register_operand" "=r,r,r,r") + (if_then_else:DI + (match_operator 2 "signed_comparison_operator" + [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J") + (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")]) + (match_operand:DI 1 "reg_or_8bit_operand" "rI,0,rI,0") + (match_operand:DI 5 "reg_or_8bit_operand" "0,rI,0,rI")))] + "operands[3] == const0_rtx || operands[4] == const0_rtx" + "@ + cmov%C2 %r3,%1,%0 + cmov%D2 %r3,%5,%0 + cmov%c2 %r4,%1,%0 + cmov%d2 %r4,%5,%0") (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r,r") @@ -1859,7 +1883,7 @@ (define_expand "cmpdf" [(set (cc0) (compare (match_operand:DF 0 "reg_or_fp0_operand" "") (match_operand:DF 1 "reg_or_fp0_operand" "")))] - "" + "TARGET_FP" " { alpha_compare_op0 = operands[0]; @@ -2199,6 +2223,182 @@ alpha_compare_op0); }") +;; These are the main define_expand's used to make conditional moves. + +(define_expand "movsicc" + [(set (match_dup 4) (match_operand 1 "comparison_operator" "")) + (set (match_operand:SI 0 "register_operand" "") + (if_then_else:DI (match_dup 5) + (match_operand:SI 2 "reg_or_8bit_operand" "") + (match_operand:SI 3 "reg_or_8bit_operand" "")))] + "" + " +{ + rtx op0,op1; + enum rtx_code code = GET_CODE (operands[1]), code2 = NE; + + if (alpha_compare_fp_p) + FAIL; + switch (code) + { + case EQ: case LE: case LT: + op0 = alpha_compare_op0; + op1 = alpha_compare_op1; + break; + case NE: + code = code2 = EQ; + op0 = alpha_compare_op0; + op1 = alpha_compare_op1; + break; + case GE: + code = LE; + op0 = force_reg (DImode, alpha_compare_op1); + op1 = alpha_compare_op0; + break; + case GT: + code = LT; + op0 = force_reg (DImode, alpha_compare_op1); + op1 = alpha_compare_op0; + break; + default: + FAIL; + } + operands[1] = gen_rtx (code, DImode, op0, op1); + operands[4] = gen_reg_rtx (DImode); + operands[5] = gen_rtx (code2, VOIDmode, operands[4], CONST0_RTX (DImode)); +}") + +(define_expand "movdicc" + [(set (match_dup 4) (match_operand 1 "comparison_operator" "")) + (set (match_operand:DI 0 "register_operand" "") + (if_then_else:DI (match_dup 5) + (match_operand:DI 2 "reg_or_8bit_operand" "") + (match_operand:DI 3 "reg_or_8bit_operand" "")))] + "" + " +{ + rtx op0,op1; + enum rtx_code code = GET_CODE (operands[1]), code2 = NE; + + if (alpha_compare_fp_p) + FAIL; + switch (code) + { + case EQ: case LE: case LT: + op0 = alpha_compare_op0; + op1 = alpha_compare_op1; + break; + case NE: + code = code2 = EQ; + op0 = alpha_compare_op0; + op1 = alpha_compare_op1; + break; + case GE: + code = LE; + op0 = force_reg (DImode, alpha_compare_op1); + op1 = alpha_compare_op0; + break; + case GT: + code = LT; + op0 = force_reg (DImode, alpha_compare_op1); + op1 = alpha_compare_op0; + break; + default: + FAIL; + } + operands[1] = gen_rtx (code, DImode, op0, op1); + operands[4] = gen_reg_rtx (DImode); + operands[5] = gen_rtx (code2, VOIDmode, operands[4], CONST0_RTX (DImode)); +}") + +(define_expand "movsfcc" + [(set (match_dup 4) (match_operand 1 "comparison_operator" "")) + (set (match_operand:SF 0 "register_operand" "") + (if_then_else:SF (match_dup 5) + (match_operand:SF 2 "reg_or_fp0_operand" "") + (match_operand:SF 3 "reg_or_fp0_operand" "")))] + "" + " +{ + rtx op0,op1; + enum rtx_code code = GET_CODE (operands[1]), code2 = NE; + + if (!alpha_compare_fp_p) + FAIL; + switch (code) + { + case EQ: case LE: case LT: + op0 = alpha_compare_op0; + op1 = alpha_compare_op1; + break; + case NE: + /* There isn't a cmptne insn. */ + code = code2 = EQ; + op0 = alpha_compare_op0; + op1 = alpha_compare_op1; + break; + case GE: + code = LE; + op0 = force_reg (DFmode, alpha_compare_op1); + op1 = alpha_compare_op0; + break; + case GT: + code = LT; + op0 = force_reg (DFmode, alpha_compare_op1); + op1 = alpha_compare_op0; + break; + default: + FAIL; + } + operands[1] = gen_rtx (code, DFmode, op0, op1); + operands[4] = gen_reg_rtx (DFmode); + operands[5] = gen_rtx (code2, VOIDmode, operands[4], CONST0_RTX (DFmode)); +}") + +(define_expand "movdfcc" + [(set (match_dup 4) (match_operand 1 "comparison_operator" "")) + (set (match_operand:DF 0 "register_operand" "") + (if_then_else:DF (match_dup 5) + (match_operand:DF 2 "reg_or_fp0_operand" "") + (match_operand:DF 3 "reg_or_fp0_operand" "")))] + "" + " +{ + rtx op0,op1; + enum rtx_code code = GET_CODE (operands[1]), code2 = NE; + + if (!alpha_compare_fp_p) + FAIL; + switch (code) + { + case EQ: case LE: case LT: + op0 = alpha_compare_op0; + op1 = alpha_compare_op1; + break; + case NE: + /* There isn't a cmptne insn. */ + code = code2 = EQ; + op0 = alpha_compare_op0; + op1 = alpha_compare_op1; + break; + case GE: + code = LE; + op0 = force_reg (DFmode, alpha_compare_op1); + op1 = alpha_compare_op0; + break; + case GT: + code = LT; + op0 = force_reg (DFmode, alpha_compare_op1); + op1 = alpha_compare_op0; + break; + default: + FAIL; + } + operands[1] = gen_rtx (code, DFmode, op0, op1); + operands[4] = gen_reg_rtx (DFmode); + operands[5] = gen_rtx (code2, VOIDmode, operands[4], CONST0_RTX (DFmode)); +}") + ;; These define_split definitions are used in cases when comparisons have ;; not be stated in the correct way and we need to reverse the second ;; comparison. For example, x >= 7 has to be done as x < 6 with the @@ -2403,9 +2603,23 @@ DImode, operands[4], const0_rtx); }") -;; Here are the CALL and unconditional branch insns. +;; Here are the CALL and unconditional branch insns. Calls on NT and OSF +;; work differently, so we have different patterns for each. (define_expand "call" + [(use (match_operand:DI 0 "" "")) + (use (match_operand 1 "" ""))] + "" + " +{ if (WINDOWS_NT) + emit_call_insn (gen_call_nt (operands[0], operands[1])); + else + emit_call_insn (gen_call_osf (operands[0], operands[1])); + + DONE; +}") + +(define_expand "call_osf" [(parallel [(call (mem:DI (match_operand 0 "" "")) (match_operand 1 "" "")) (clobber (reg:DI 27)) @@ -2426,7 +2640,40 @@ } }") +(define_expand "call_nt" + [(parallel [(call (mem:DI (match_operand:DI 0 "" "")) + (match_operand 1 "" "")) + (clobber (reg:DI 26))])] + "" + " +{ if (GET_CODE (operands[0]) != MEM) + abort (); + operands[0] = XEXP (operands[0], 0); + + if (GET_CODE (operands[1]) != SYMBOL_REF + && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27)) + { + rtx tem = gen_rtx (REG, DImode, 27); + emit_move_insn (tem, operands[1]); + operands[1] = tem; + } +}") + (define_expand "call_value" + [(use (match_operand 0 "" "")) + (use (match_operand:DI 1 "" "")) + (use (match_operand 2 "" ""))] + "" + " +{ if (WINDOWS_NT) + emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2])); + else + emit_call_insn (gen_call_value_osf (operands[0], operands[1], + operands[2])); + DONE; +}") + +(define_expand "call_value_osf" [(parallel [(set (match_operand 0 "" "") (call (mem:DI (match_operand 1 "" "")) (match_operand 2 "" ""))) @@ -2448,12 +2695,32 @@ } }") +(define_expand "call_value_nt" + [(parallel [(set (match_operand 0 "" "") + (call (mem:DI (match_operand:DI 1 "" "")) + (match_operand 2 "" ""))) + (clobber (reg:DI 26))])] + "" + " +{ if (GET_CODE (operands[1]) != MEM) + abort (); + + operands[1] = XEXP (operands[1], 0); + if (GET_CODE (operands[1]) != SYMBOL_REF + && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27)) + { + rtx tem = gen_rtx (REG, DImode, 27); + emit_move_insn (tem, operands[1]); + operands[1] = tem; + } +}") + (define_insn "" [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i")) (match_operand 1 "" "")) (clobber (reg:DI 27)) (clobber (reg:DI 26))] - "" + "! WINDOWS_NT" "@ jsr $26,($27),0\;ldgp $29,0($26) bsr $26,%0..ng @@ -2461,18 +2728,39 @@ [(set_attr "type" "jsr,jsr,ibr")]) (define_insn "" + [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i")) + (match_operand 1 "" "")) + (clobber (reg:DI 26))] + "WINDOWS_NT" + "@ + jsr $26,(%0) + bsr $26,%0" + [(set_attr "type" "jsr")]) + +(define_insn "" [(set (match_operand 0 "register_operand" "=rf,rf,rf") (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i")) (match_operand 2 "" ""))) (clobber (reg:DI 27)) (clobber (reg:DI 26))] - "" + "! WINDOWS_NT" "@ jsr $26,($27),0\;ldgp $29,0($26) bsr $26,%1..ng jsr $26,%1\;ldgp $29,0($26)" [(set_attr "type" "jsr,jsr,ibr")]) +(define_insn "" + [(set (match_operand 0 "register_operand" "=rf,rf") + (call (mem:DI (match_operand:DI 1 "call_operand" "r,i")) + (match_operand 2 "" ""))) + (clobber (reg:DI 26))] + "WINDOWS_NT" + "@ + jsr $26,(%1) + bsr $26,%1" + [(set_attr "type" "jsr")]) + ;; Call subroutine returning any type. (define_expand "untyped_call" @@ -2536,6 +2824,20 @@ [(set_attr "type" "iaddlog")]) (define_expand "tablejump" + [(use (match_operand:SI 0 "register_operand" "")) + (use (match_operand:SI 1 "" ""))] + "" + " +{ + if (WINDOWS_NT) + emit_jump_insn (gen_tablejump_nt (operands[0], operands[1])); + else + emit_jump_insn (gen_tablejump_osf (operands[0], operands[1])); + + DONE; +}") + +(define_expand "tablejump_osf" [(set (match_dup 3) (sign_extend:DI (match_operand:SI 0 "register_operand" ""))) (parallel [(set (pc) @@ -2546,12 +2848,22 @@ " { operands[3] = gen_reg_rtx (DImode); }") +(define_expand "tablejump_nt" + [(set (match_dup 3) + (sign_extend:DI (match_operand:SI 0 "register_operand" ""))) + (parallel [(set (pc) + (match_dup 3)) + (use (label_ref (match_operand 1 "" "")))])] + "" + " +{ operands[3] = gen_reg_rtx (DImode); }") + (define_insn "" [(set (pc) (plus:DI (match_operand:DI 0 "register_operand" "r") (label_ref:DI (match_operand 1 "" "")))) (clobber (match_scratch:DI 2 "=r"))] - "next_active_insn (insn) != 0 + "! WINDOWS_NT && next_active_insn (insn) != 0 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC && PREV_INSN (next_active_insn (insn)) == operands[1]" "* @@ -2590,6 +2902,49 @@ }" [(set_attr "type" "ibr")]) +(define_insn "" + [(set (pc) + (match_operand:DI 0 "register_operand" "r")) + (use (label_ref (match_operand 1 "" "")))] + "WINDOWS_NT && next_active_insn (insn) != 0 + && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC + && PREV_INSN (next_active_insn (insn)) == operands[1]" + "* +{ rtx best_label = 0; + rtx jump_table_insn = next_active_insn (operands[1]); + + if (GET_CODE (jump_table_insn) == JUMP_INSN + && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC) + { + rtx jump_table = PATTERN (jump_table_insn); + int n_labels = XVECLEN (jump_table, 1); + int best_count = -1; + int i, j; + + for (i = 0; i < n_labels; i++) + { + int count = 1; + + for (j = i + 1; j < n_labels; j++) + if (XEXP (XVECEXP (jump_table, 1, i), 0) + == XEXP (XVECEXP (jump_table, 1, j), 0)) + count++; + + if (count > best_count) + best_count = count, best_label = XVECEXP (jump_table, 1, i); + } + } + + if (best_label) + { + operands[2] = best_label; + return \"jmp $31,(%0),%2\"; + } + else + return \"jmp $31,(%0),0\"; +}" + [(set_attr "type" "ibr")]) + ;; Cache flush. Used by INITIALIZE_TRAMPOLINE. 0x86 is PAL_imb, but we don't ;; want to have to include pal.h in our .s file. (define_insn "" @@ -2653,30 +3008,44 @@ operands[1] = force_reg (DFmode, operands[1]); }") -;; There is a problem with 32-bit values in FP registers. We keep such -;; values in the register as a quadword. This is done on loads by using -;; the cvtlq instruction. On stores, we can't do anything directly from -;; floating-point registers. Disallow such an operation and let reload -;; use an integer register instead. Don't encourage 32-bit values to -;; be placed in FP registers at all. +(define_insn "" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,f,f,f,m") + (match_operand:SI 1 "input_operand" "r,J,I,K,L,m,rJ,f,J,m,fG"))] + "! WINDOWS_NT && (register_operand (operands[0], SImode) + || reg_or_0_operand (operands[1], SImode))" + "@ + bis %1,%1,%0 + bis $31,$31,%0 + bis $31,%1,%0 + lda %0,%1 + ldah %0,%h1 + ldl %0,%1 + stl %r1,%0 + cpys %1,%1,%0 + cpys $f31,$f31,%0 + lds %0,%1 + sts %R1,%0" + [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,iaddlog,ld,st,fpop,fpop,ld,st")]) (define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,*f") - (match_operand:SI 1 "input_operand" "r,J,I,K,L,m,rJ,*f,J,m"))] - "register_operand (operands[0], SImode) - || reg_or_0_operand (operands[1], SImode)" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,f,f,f,m") + (match_operand:SI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,m,fG"))] + "WINDOWS_NT && (register_operand (operands[0], SImode) + || reg_or_0_operand (operands[1], SImode))" "@ bis %1,%1,%0 bis $31,$31,%0 bis $31,%1,%0 lda %0,%1 ldah %0,%h1 + lda %0,%1 ldl %0,%1 stl %r1,%0 cpys %1,%1,%0 cpys $f31,$f31,%0 - lds %0,%1\;cvtlq %0,%0" - [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,iaddlog,ld,st,fpop,fpop,ld")]) + lds %0,%1 + sts %R1,%0" + [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,iaddlog,ldsym,ld,st,fpop,fpop,ld,st")]) (define_insn "" [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,f,f") @@ -2723,10 +3092,10 @@ ; else if (GET_CODE (operands[1]) == CONST_INT) { - if (alpha_emit_set_const (operands[0], INTVAL (operands[1]), 3)) + operands[1] + = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 3); + if (rtx_equal_p (operands[0], operands[1])) DONE; - else - abort (); } }") @@ -2740,7 +3109,10 @@ [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))] " -{ if (alpha_emit_set_const (operands[0], INTVAL (operands[1]), 2)) +{ rtx tem + = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2); + + if (tem == operands[0]) DONE; else FAIL; @@ -2775,6 +3147,8 @@ "" " { + rtx tem; + if (GET_CODE (operands[0]) == MEM && ! reg_or_0_operand (operands[1], DImode)) operands[1] = force_reg (DImode, operands[1]); @@ -2782,14 +3156,21 @@ if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode)) ; else if (GET_CODE (operands[1]) == CONST_INT - && alpha_emit_set_const (operands[0], INTVAL (operands[1]), 3)) - DONE; + && (tem = alpha_emit_set_const (operands[0], DImode, + INTVAL (operands[1]), 3)) != 0) + { + if (rtx_equal_p (tem, operands[0])) + DONE; + else + operands[1] = tem; + } else if (CONSTANT_P (operands[1])) { operands[1] = force_const_mem (DImode, operands[1]); if (reload_in_progress) { emit_move_insn (operands[0], XEXP (operands[1], 0)); + operands[1] = copy_rtx (operands[1]); XEXP (operands[1], 0) = operands[0]; } else @@ -2809,7 +3190,10 @@ [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] " -{ if (alpha_emit_set_const (operands[0], INTVAL (operands[1]), 2)) +{ rtx tem + = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2); + + if (tem == operands[0]) DONE; else FAIL; @@ -3186,7 +3570,7 @@ { extern rtx get_unaligned_address (); rtx addr = get_unaligned_address (operands[1]); /* It is possible that one of the registers we got for operands[2] - might co-incide with that of operands[0] (which is why we made + might coincide with that of operands[0] (which is why we made it TImode). Pick the other one to use as our scratch. */ rtx scratch = gen_rtx (REG, DImode, REGNO (operands[0]) == REGNO (operands[2]) @@ -3306,11 +3690,11 @@ "" " { - operands[0] = gen_rtx (MEM, DImode, plus_constant (stack_pointer_rtx, + operands[1] = gen_rtx (MEM, DImode, plus_constant (stack_pointer_rtx, INTVAL (operands[0]))); - MEM_VOLATILE_P (operands[0]) = 1; + MEM_VOLATILE_P (operands[1]) = 1; - operands[1] = gen_reg_rtx (DImode); + operands[0] = const0_rtx; }") ;; This is how we allocate stack space. If we are allocating a @@ -3341,7 +3725,7 @@ emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192)))); if (probed + 4096 < INTVAL (operands[0])) - emit_insn (gen_probe_stack (GEN_INT (- (probed += 4096)))); + emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[0])))); } operands[0] = GEN_INT (- INTVAL (operands[0])); @@ -3350,56 +3734,36 @@ { rtx out_label = 0; rtx loop_label = gen_label_rtx (); - rtx count = gen_reg_rtx (DImode); - rtx access = gen_reg_rtx (Pmode); - rtx memref = gen_rtx (MEM, DImode, access); + rtx want = gen_reg_rtx (Pmode); + rtx tmp = gen_reg_rtx (Pmode); + rtx memref; - MEM_VOLATILE_P (memref) = 1; - - /* If the amount to be allocated is not a constant, we only need to - do something special if it is >= 4096. */ + emit_insn (gen_subdi3 (want, stack_pointer_rtx, + force_reg (Pmode, operands[0]))); + emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096))); if (GET_CODE (operands[0]) != CONST_INT) { - operands[0] = force_reg (DImode, operands[0]); out_label = gen_label_rtx (); - emit_insn (gen_cmpdi (operands[0], - force_reg (DImode, GEN_INT (4096)))); - emit_jump_insn (gen_ble (out_label)); - - /* Compute COUNT = (N + 4096) / 8192. N is known positive. */ - emit_insn (gen_adddi3 (count, operands[0], GEN_INT (4096))); - emit_insn (gen_lshrdi3 (count, count, GEN_INT (13))); + emit_insn (gen_cmpdi (want, tmp)); + emit_jump_insn (gen_bgeu (out_label)); } - else - emit_move_insn (count, GEN_INT ((INTVAL (operands[0]) + 4096) >> 13)); - /* ACCESS = SP + 4096. */ - emit_insn (gen_adddi3 (access, stack_pointer_rtx, GEN_INT (4096))); emit_label (loop_label); - - /* Each iteration subtracts 8192 from ACCESS and references it. */ - emit_insn (gen_adddi3 (count, count, constm1_rtx)); - emit_insn (gen_adddi3 (access, access, GEN_INT (-8192))); - emit_move_insn (gen_reg_rtx (DImode), memref); - emit_insn (gen_cmpdi (count, const0_rtx)); - emit_jump_insn (gen_bgt (loop_label)); + memref = gen_rtx (MEM, DImode, tmp); + MEM_VOLATILE_P (memref) = 1; + emit_move_insn (memref, const0_rtx); + emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192))); + emit_insn (gen_cmpdi (tmp, want)); + emit_jump_insn (gen_bgtu (loop_label)); + memref = gen_rtx (MEM, DImode, want); + MEM_VOLATILE_P (memref) = 1; + emit_move_insn (memref, const0_rtx); if (out_label) emit_label (out_label); - /* We need to subtract operands[0] from SP. We know it isn't a - constant less than 32768, so we know we have to load it into - a register. */ - - emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx, - force_reg (Pmode, operands[0]))); - - /* Now, unless we have a constant and we know that we are within - 4096 from the end, we need to access sp + 4096. */ - if (! (GET_CODE (operands[0]) == CONST_INT - && (INTVAL (operands[0]) % 8192) < 4096)) - emit_insn (gen_probe_stack (GEN_INT (4096))); + emit_move_insn (stack_pointer_rtx, want); DONE; }