--- gcc/config/alpha/alpha.md 2018/04/24 18:10:26 1.1.1.1 +++ gcc/config/alpha/alpha.md 2018/04/24 18:22:30 1.1.1.3 @@ -1,6 +1,6 @@ -;;- Machine description for DEC Alpha for GNU C compiler -;; Copyright (C) 1992 Free Software Foundation, Inc. -;; Contributed by Richard Kenner (kenner@nyu.edu) +;; Machine description for DEC Alpha for GNU C compiler +;; Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. +;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ;; This file is part of GNU CC. @@ -26,7 +26,7 @@ ;; separately. (define_attr "type" - "ld,st,ibr,fbr,jsr,iaddlog,shiftcm,icmp,imull,imulq,fpop,fdivs,fdivt,ldsym" + "ld,st,ibr,fbr,jsr,iaddlog,shiftcm,icmp,imull,imulq,fpop,fdivs,fdivt,ldsym,isubr" (const_string "shiftcm")) ;; We include four function units: ABOX, which computes the address, @@ -85,9 +85,25 @@ cvtql %1,%0\;cvtlq %0,%0" [(set_attr "type" "iaddlog,ld,fpop")]) -(define_insn "addsi3" +;; Do addsi3 the way expand_binop would do if we didn't have one. This +;; generates better code. We have the anonymous addsi3 pattern below in +;; case combine wants to make it. +(define_expand "addsi3" + [(set (match_operand:SI 0 "register_operand" "") + (plus:SI (match_operand:SI 1 "reg_or_0_operand" "") + (match_operand:SI 2 "add_operand" "")))] + "" + " +{ emit_insn (gen_rtx (SET, VOIDmode, gen_lowpart (DImode, operands[0]), + gen_rtx (PLUS, DImode, + gen_lowpart (DImode, operands[1]), + gen_lowpart (DImode, operands[2])))); + DONE; +} ") + +(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") - (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,%rJ,%rJ,%rJ") + (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ") (match_operand:SI 2 "add_operand" "rI,O,K,L")))] "" "@ @@ -149,9 +165,27 @@ operands[5] = GEN_INT (mult); }") +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (sign_extend:DI + (plus:SI (match_operator:SI 1 "comparison_operator" + [(match_operand 2 "" "") + (match_operand 3 "" "")]) + (match_operand:SI 4 "add_operand" "")))) + (clobber (match_operand:DI 5 "register_operand" ""))] + "" + [(set (match_dup 5) (match_dup 6)) + (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))] + " +{ + operands[6] = gen_rtx (GET_CODE (operands[1]), DImode, + operands[2], operands[3]); + operands[7] = gen_lowpart (SImode, operands[5]); +}") + (define_insn "adddi3" [(set (match_operand:DI 0 "register_operand" "=r,r,r,r") - (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,%rJ,%rJ,%rJ") + (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ") (match_operand:DI 2 "add_operand" "rI,O,K,L")))] "" "@ @@ -204,6 +238,27 @@ s%2subl %r1,%n3,%0" [(set_attr "type" "iaddlog")]) +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (sign_extend:DI + (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator" + [(match_operand 2 "" "") + (match_operand 3 "" "")]) + (match_operand:SI 4 "const48_operand" "")) + (match_operand:SI 5 "add_operand" "")))) + (clobber (match_operand:DI 6 "register_operand" ""))] + "" + [(set (match_dup 6) (match_dup 7)) + (set (match_dup 0) + (sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4)) + (match_dup 5))))] + " +{ + operands[7] = gen_rtx (GET_CODE (operands[1]), DImode, + operands[2], operands[3]); + operands[8] = gen_lowpart (SImode, operands[6]); +}") + (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r,r") (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ") @@ -220,37 +275,96 @@ ;; 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")))] + "reload_in_progress" + "#" + [(set_attr "type" "iaddlog")]) + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (plus:DI (plus:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "register_operand" "")) + (match_operand:DI 3 "add_operand" "")))] + "reload_completed" + [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2))) + (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] + "") + +(define_insn "" [(set (match_operand:SI 0 "register_operand" "=&r") - (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") + (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 "const_int_operand" "rI")))] + (match_operand:SI 4 "add_operand" "rIOKL")))] "reload_in_progress" - "s%2addl %r1,%3,%0\;addl %0,%4,%0" + "#" [(set_attr "type" "iaddlog")]) +(define_split + [(set (match_operand:SI 0 "register_operand" "r") + (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "") + (match_operand:SI 2 "const48_operand" "")) + (match_operand:SI 3 "register_operand" "")) + (match_operand:SI 4 "add_operand" "rIOKL")))] + "reload_completed" + [(set (match_dup 0) + (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))] + "") + (define_insn "" [(set (match_operand:DI 0 "register_operand" "=&r") (sign_extend:DI (plus:SI (plus:SI - (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") + (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 "const_int_operand" "rI"))))] + (match_operand:SI 4 "add_operand" "rIOKL"))))] "reload_in_progress" - "s%2addl %r1,%3,%0\;addl %0,%4,%0" + "#" [(set_attr "type" "iaddlog")]) +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (sign_extend:DI + (plus:SI (plus:SI + (mult:SI (match_operand:SI 1 "reg_or_0_operand" "") + (match_operand:SI 2 "const48_operand" "")) + (match_operand:SI 3 "register_operand" "")) + (match_operand:SI 4 "add_operand" ""))))] + "reload_completed" + [(set (match_dup 5) + (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 5) (match_dup 4))))] + " +{ operands[5] = gen_lowpart (SImode, operands[0]); +}") + (define_insn "" [(set (match_operand:DI 0 "register_operand" "=&r") - (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") + (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 "const_int_operand" "rI")))] + (match_operand:DI 4 "add_operand" "rIOKL")))] "reload_in_progress" "s%2addq %r1,%3,%0\;addq %0,%4,%0" [(set_attr "type" "iaddlog")]) +(define_split + [(set (match_operand:DI 0 "register_operand" "=") + (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "") + (match_operand:DI 2 "const48_operand" "")) + (match_operand:DI 3 "register_operand" "")) + (match_operand:DI 4 "add_operand" "")))] + "reload_completed" + [(set (match_dup 0) + (plus:DI (mult:DI (match_dup 1) (match_dup 2)) (match_dup 3))) + (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] + "") + (define_insn "negsi2" [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))] @@ -273,7 +387,21 @@ "subq $31,%1,%0" [(set_attr "type" "iaddlog")]) -(define_insn "subsi3" +(define_expand "subsi3" + [(set (match_operand:SI 0 "register_operand" "") + (minus:SI (match_operand:SI 1 "reg_or_0_operand" "") + (match_operand:SI 2 "reg_or_8bit_operand" "")))] + "" + " +{ emit_insn (gen_rtx (SET, VOIDmode, gen_lowpart (DImode, operands[0]), + gen_rtx (MINUS, DImode, + gen_lowpart (DImode, operands[1]), + gen_lowpart (DImode, operands[2])))); + DONE; + +} ") + +(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") (match_operand:SI 2 "reg_or_8bit_operand" "rI")))] @@ -328,173 +456,155 @@ (define_insn "mulsi3" [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") - (match_operand:SI 2 "reg_or_8bit_operand" "rI")))] + (match_operand:SI 2 "reg_or_0_operand" "rJ")))] "" - "mull %r1,%2,%0" + "mull %r1,%r2,%0" [(set_attr "type" "imull")]) (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") - (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))] + (match_operand:SI 2 "reg_or_0_operand" "rJ"))))] "" - "mull %r1,%2,%0" + "mull %r1,%r2,%0" [(set_attr "type" "imull")]) (define_insn "muldi3" [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ") - (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] + (match_operand:DI 2 "reg_or_0_operand" "rJ")))] + "" + "mulq %r1,%r2,%0" + [(set_attr "type" "imulq")]) + +(define_insn "umuldi3_highpart" + [(set (match_operand:DI 0 "register_operand" "=r") + (truncate:DI + (lshiftrt:TI + (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r")) + (zero_extend:TI (match_operand:DI 2 "register_operand" "r"))) + (const_int 64))))] + "" + "umulh %1,%2,%0" + [(set_attr "type" "imulq")]) + +(define_insn "" + [(set (match_operand:DI 0 "register_operand" "=r") + (truncate:DI + (lshiftrt:TI + (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r")) + (match_operand:TI 2 "cint8_operand" "I")) + (const_int 64))))] "" - "mulq %r1,%2,%0" + "umulh %1,%2,%0" [(set_attr "type" "imulq")]) ;; The divide and remainder operations always take their inputs from ;; r24 and r25, put their output in r27, and clobber r23 and r28. (define_expand "divsi3" - [(parallel [(set (reg:SI 27) - (div:SI (match_operand:SI 1 "general_operand" "") - (match_operand:SI 2 "general_operand" ""))) + [(set (reg:SI 24) (match_operand:SI 1 "input_operand" "")) + (set (reg:SI 25) (match_operand:SI 2 "input_operand" "")) + (parallel [(set (reg:SI 27) + (div:SI (reg:SI 24) + (reg:SI 25))) (clobber (reg:DI 23)) (clobber (reg:DI 28))]) (set (match_operand:SI 0 "general_operand" "") (reg:SI 27))] "" - " -{ rtx in0 = gen_rtx (REG, SImode, 24); - rtx in1 = gen_rtx (REG, SImode, 25); - - emit_move_insn (in0, operands[1]); - emit_move_insn (in1, operands[2]); - operands[1] = in0, operands[2] = in1; -}") + "") (define_expand "udivsi3" - [(parallel [(set (reg:SI 27) - (udiv:SI (match_operand:SI 1 "general_operand" "") - (match_operand:SI 2 "general_operand" ""))) + [(set (reg:SI 24) (match_operand:SI 1 "input_operand" "")) + (set (reg:SI 25) (match_operand:SI 2 "input_operand" "")) + (parallel [(set (reg:SI 27) + (udiv:SI (reg:SI 24) + (reg:SI 25))) (clobber (reg:DI 23)) (clobber (reg:DI 28))]) (set (match_operand:SI 0 "general_operand" "") (reg:SI 27))] "" - " -{ rtx in0 = gen_rtx (REG, SImode, 24); - rtx in1 = gen_rtx (REG, SImode, 25); - - emit_move_insn (in0, operands[1]); - emit_move_insn (in1, operands[2]); - operands[1] = in0, operands[2] = in1; -}") + "") (define_expand "modsi3" - [(parallel [(set (reg:SI 27) - (mod:SI (match_operand:SI 1 "general_operand" "") - (match_operand:SI 2 "general_operand" ""))) + [(set (reg:SI 24) (match_operand:SI 1 "input_operand" "")) + (set (reg:SI 25) (match_operand:SI 2 "input_operand" "")) + (parallel [(set (reg:SI 27) + (mod:SI (reg:SI 24) + (reg:SI 25))) (clobber (reg:DI 23)) (clobber (reg:DI 28))]) (set (match_operand:SI 0 "general_operand" "") (reg:SI 27))] "" - " -{ rtx in0 = gen_rtx (REG, SImode, 24); - rtx in1 = gen_rtx (REG, SImode, 25); - - emit_move_insn (in0, operands[1]); - emit_move_insn (in1, operands[2]); - operands[1] = in0, operands[2] = in1; -}") + "") (define_expand "umodsi3" - [(parallel [(set (reg:SI 27) - (umod:SI (match_operand:SI 1 "general_operand" "") - (match_operand:SI 2 "general_operand" ""))) + [(set (reg:SI 24) (match_operand:SI 1 "input_operand" "")) + (set (reg:SI 25) (match_operand:SI 2 "input_operand" "")) + (parallel [(set (reg:SI 27) + (umod:SI (reg:SI 24) + (reg:SI 25))) (clobber (reg:DI 23)) (clobber (reg:DI 28))]) (set (match_operand:SI 0 "general_operand" "") (reg:SI 27))] "" - " -{ rtx in0 = gen_rtx (REG, SImode, 24); - rtx in1 = gen_rtx (REG, SImode, 25); - - emit_move_insn (in0, operands[1]); - emit_move_insn (in1, operands[2]); - operands[1] = in0, operands[2] = in1; -}") + "") (define_expand "divdi3" - [(parallel [(set (reg:DI 27) - (div:DI (match_operand:DI 1 "general_operand" "") - (match_operand:DI 2 "general_operand" ""))) + [(set (reg:DI 24) (match_operand:DI 1 "input_operand" "")) + (set (reg:DI 25) (match_operand:DI 2 "input_operand" "")) + (parallel [(set (reg:DI 27) + (div:DI (reg:DI 24) + (reg:DI 25))) (clobber (reg:DI 23)) (clobber (reg:DI 28))]) (set (match_operand:DI 0 "general_operand" "") (reg:DI 27))] "" - " -{ rtx in0 = gen_rtx (REG, DImode, 24); - rtx in1 = gen_rtx (REG, DImode, 25); - - emit_move_insn (in0, operands[1]); - emit_move_insn (in1, operands[2]); - operands[1] = in0, operands[2] = in1; -}") + "") (define_expand "udivdi3" - [(parallel [(set (reg:DI 27) - (udiv:DI (match_operand:DI 1 "general_operand" "") - (match_operand:DI 2 "general_operand" ""))) + [(set (reg:DI 24) (match_operand:DI 1 "input_operand" "")) + (set (reg:DI 25) (match_operand:DI 2 "input_operand" "")) + (parallel [(set (reg:DI 27) + (udiv:DI (reg:DI 24) + (reg:DI 25))) (clobber (reg:DI 23)) (clobber (reg:DI 28))]) (set (match_operand:DI 0 "general_operand" "") (reg:DI 27))] "" - " -{ rtx in0 = gen_rtx (REG, DImode, 24); - rtx in1 = gen_rtx (REG, DImode, 25); - - emit_move_insn (in0, operands[1]); - emit_move_insn (in1, operands[2]); - operands[1] = in0, operands[2] = in1; -}") + "") (define_expand "moddi3" - [(parallel [(set (reg:DI 27) - (mod:DI (match_operand:DI 1 "general_operand" "") - (match_operand:DI 2 "general_operand" ""))) + [(set (reg:DI 24) (match_operand:DI 1 "input_operand" "")) + (set (reg:DI 25) (match_operand:DI 2 "input_operand" "")) + (parallel [(set (reg:DI 27) + (mod:DI (reg:DI 24) + (reg:DI 25))) (clobber (reg:DI 23)) (clobber (reg:DI 28))]) (set (match_operand:DI 0 "general_operand" "") (reg:DI 27))] "" - " -{ rtx in0 = gen_rtx (REG, DImode, 24); - rtx in1 = gen_rtx (REG, DImode, 25); - - emit_move_insn (in0, operands[1]); - emit_move_insn (in1, operands[2]); - operands[1] = in0, operands[2] = in1; -}") + "") (define_expand "umoddi3" - [(parallel [(set (reg:DI 27) - (umod:DI (match_operand:DI 1 "general_operand" "") - (match_operand:DI 2 "general_operand" ""))) + [(set (reg:DI 24) (match_operand:DI 1 "input_operand" "")) + (set (reg:DI 25) (match_operand:DI 2 "input_operand" "")) + (parallel [(set (reg:DI 27) + (umod:DI (reg:DI 24) + (reg:DI 25))) (clobber (reg:DI 23)) (clobber (reg:DI 28))]) (set (match_operand:DI 0 "general_operand" "") (reg:DI 27))] "" - " -{ rtx in0 = gen_rtx (REG, DImode, 24); - rtx in1 = gen_rtx (REG, DImode, 25); - - emit_move_insn (in0, operands[1]); - emit_move_insn (in1, operands[2]); - operands[1] = in0, operands[2] = in1; -}") + "") (define_insn "" [(set (reg:SI 27) @@ -503,7 +613,8 @@ (clobber (reg:DI 23)) (clobber (reg:DI 28))] "" - "%E1 $24,$25,$27") + "%E1 $24,$25,$27" + [(set_attr "type" "isubr")]) (define_insn "" [(set (reg:DI 27) @@ -512,7 +623,8 @@ (clobber (reg:DI 23)) (clobber (reg:DI 28))] "" - "%E1 $24,$25,$27") + "%E1 $24,$25,$27" + [(set_attr "type" "isubr")]) ;; Next are the basic logical operations. These only exist in DImode. @@ -609,11 +721,13 @@ [(set_attr "type" "iaddlog")]) (define_insn "iordi3" - [(set (match_operand:DI 0 "register_operand" "=r") - (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ") - (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] + [(set (match_operand:DI 0 "register_operand" "=r,r") + (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ") + (match_operand:DI 2 "or_operand" "rI,N")))] "" - "bis %r1,%2,%0" + "@ + bis %r1,%2,%0 + ornot %r1,%N2,%0" [(set_attr "type" "iaddlog")]) (define_insn "one_cmpldi2" @@ -632,17 +746,19 @@ [(set_attr "type" "iaddlog")]) (define_insn "xordi3" - [(set (match_operand:DI 0 "register_operand" "=r") - (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") - (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] + [(set (match_operand:DI 0 "register_operand" "=r,r") + (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ") + (match_operand:DI 2 "or_operand" "rI,N")))] "" - "xor %r1,%2,%0" + "@ + xor %r1,%2,%0 + eqv %r1,%N2,%0" [(set_attr "type" "iaddlog")]) (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") - (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") - (match_operand:DI 2 "reg_or_8bit_operand" "rI"))))] + (not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ") + (match_operand:DI 2 "register_operand" "rI"))))] "" "eqv %r1,%2,%0" [(set_attr "type" "iaddlog")]) @@ -652,7 +768,7 @@ (define_insn "ashldi3" [(set (match_operand:DI 0 "register_operand" "=r,r") (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ") - (match_operand:DI 2 "reg_or_8bit_operand" "P,rI")))] + (match_operand:DI 2 "reg_or_6bit_operand" "P,rI")))] "" "* { @@ -669,40 +785,33 @@ }" [(set_attr "type" "iaddlog,shiftcm")]) -;; This is the same as (sign_extend (shift X [123])). (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") - (ashiftrt:DI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") - (match_operand:DI 2 "const_int_operand" "i")) - (const_int 32)))] - "INTVAL (operands[2]) >= 33 && INTVAL (operands[2]) <= 35" + (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" "* { - switch (INTVAL (operands[2])) - { - case 33: - return \"addl %r1,%r1,%0\"; - case 34: - return \"s4addl %r1,0,%0\"; - case 35: - return \"s8addl %r1,0,%0\"; - default: - abort (); - } + 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") (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") - (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] + (match_operand:DI 2 "reg_or_6bit_operand" "rI")))] "" "srl %r1,%2,%0") (define_insn "ashrdi3" [(set (match_operand:DI 0 "register_operand" "=r") (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") - (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] + (match_operand:DI 2 "reg_or_6bit_operand" "rI")))] "" "sra %r1,%2,%0") @@ -909,10 +1018,11 @@ (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") - (and:DI (ashift:DI - (match_operand:DI 2 "mode_mask_operand" "n") - (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI") - (const_int 3))) + (and:DI (not:DI (ashift:DI + (match_operand:DI 2 "mode_mask_operand" "n") + (ashift:DI + (match_operand:DI 3 "reg_or_8bit_operand" "rI") + (const_int 3)))) (match_operand:DI 1 "reg_or_0_operand" "rJ")))] "" "msk%U2l %r1,%3,%0") @@ -942,14 +1052,14 @@ [(set (match_operand:SF 0 "register_operand" "=f") (neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))] "TARGET_FP" - "cpysn %1,%R1,%0" + "cpysn %R1,%R1,%0" [(set_attr "type" "fpop")]) (define_insn "negdf2" [(set (match_operand:DF 0 "register_operand" "=f") (neg:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] "TARGET_FP" - "cpysn %1,%R1,%0" + "cpysn %R1,%R1,%0" [(set_attr "type" "fpop")]) (define_insn "addsf3" @@ -971,7 +1081,7 @@ (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") (plus:DF (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "%fG")) + (match_operand:SF 1 "reg_or_fp0_operand" "fG")) (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" "addt %R1,%R2,%0" @@ -1075,7 +1185,7 @@ (define_insn "mulsf3" [(set (match_operand:SF 0 "register_operand" "=f") - (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG") + (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG") (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" "muls %R1,%R2,%0" @@ -1083,7 +1193,7 @@ (define_insn "muldf3" [(set (match_operand:DF 0 "register_operand" "=f") - (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG") + (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG") (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" "mult %R1,%R2,%0" @@ -1101,7 +1211,7 @@ (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") (mult:DF (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "fG")) + (match_operand:SF 1 "reg_or_fp0_operand" "%fG")) (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] "TARGET_FP" @@ -1110,7 +1220,7 @@ (define_insn "subsf3" [(set (match_operand:SF 0 "register_operand" "=f") - (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG") + (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG") (match_operand:SF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" "subs %R1,%R2,%0" @@ -1118,7 +1228,7 @@ (define_insn "subdf3" [(set (match_operand:DF 0 "register_operand" "=f") - (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG") + (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG") (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" "subt %R1,%R2,%0" @@ -1127,7 +1237,7 @@ (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") (minus:DF (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "%fG")) + (match_operand:SF 1 "reg_or_fp0_operand" "fG")) (match_operand:DF 2 "reg_or_fp0_operand" "fG")))] "TARGET_FP" "subt %R1,%R2,%0" @@ -1135,7 +1245,7 @@ (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") - (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG") + (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG") (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] "TARGET_FP" @@ -1145,7 +1255,7 @@ (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") (minus:DF (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "%fG")) + (match_operand:SF 1 "reg_or_fp0_operand" "fG")) (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))] "TARGET_FP" @@ -1366,7 +1476,7 @@ (match_dup 0) (match_dup 1)))] "") -(define_expand "maxdi3" +(define_expand "smaxdi3" [(set (match_dup 3) (le:DI (match_operand:DI 1 "reg_or_0_operand" "") (match_operand:DI 2 "reg_or_8bit_operand" ""))) @@ -1671,11 +1781,12 @@ (le:DF (match_operand:DF 1 "reg_or_fp0_operand" "") (match_operand:DF 2 "reg_or_fp0_operand" ""))) (set (match_operand:DF 0 "register_operand" "") - (if_then_else:DF (eq (match_dup 3) (const_int 0)) + (if_then_else:DF (eq (match_dup 3) (match_dup 4)) (match_dup 1) (match_dup 2)))] "TARGET_FP" " { operands[3] = gen_reg_rtx (DFmode); + operands[4] = CONST0_RTX (DFmode); }") (define_expand "mindf3" @@ -1683,35 +1794,38 @@ (lt:DF (match_operand:DF 1 "reg_or_fp0_operand" "") (match_operand:DF 2 "reg_or_fp0_operand" ""))) (set (match_operand:DF 0 "register_operand" "") - (if_then_else:DF (ne (match_dup 3) (const_int 0)) + (if_then_else:DF (ne (match_dup 3) (match_dup 4)) (match_dup 1) (match_dup 2)))] "TARGET_FP" " { operands[3] = gen_reg_rtx (DFmode); + operands[4] = CONST0_RTX (DFmode); }") (define_expand "maxsf3" [(set (match_dup 3) - (le:DF (match_operand:SF 1 "reg_or_fp0_operand" "") + (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "")) (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "")))) (set (match_operand:SF 0 "register_operand" "") - (if_then_else:SF (eq (match_dup 3) (const_int 0)) + (if_then_else:SF (eq (match_dup 3) (match_dup 4)) (match_dup 1) (match_dup 2)))] "TARGET_FP" " -{ operands[3] = gen_reg_rtx (SFmode); +{ operands[3] = gen_reg_rtx (DFmode); + operands[4] = CONST0_RTX (DFmode); }") (define_expand "minsf3" [(set (match_dup 3) - (lt:DF (match_operand:SF 1 "reg_or_fp0_operand" "") + (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "")) (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "")))) (set (match_operand:SF 0 "register_operand" "") - (if_then_else:SF (ne (match_dup 3) (const_int 0)) + (if_then_else:SF (ne (match_dup 3) (match_dup 4)) (match_dup 1) (match_dup 2)))] "TARGET_FP" " -{ operands[3] = gen_reg_rtx (SFmode); +{ operands[3] = gen_reg_rtx (DFmode); + operands[4] = CONST0_RTX (DFmode); }") (define_insn "" @@ -2263,32 +2377,60 @@ operands[6] = gen_rtx (GET_CODE (operands[1]), VOIDmode, operands[4], const0_rtx); }") + +;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0". +;; This eliminates one, and sometimes two, insns when the AND can be done +;; with a ZAP. +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (match_operator 1 "comparison_operator" + [(match_operand:DI 2 "register_operand" "") + (match_operand:DI 3 "const_int_operand" "")])) + (clobber (match_operand:DI 4 "register_operand" ""))] + "exact_log2 (INTVAL (operands[3]) + 1) >= 0 + && (GET_CODE (operands[1]) == GTU + || GET_CODE (operands[1]) == LEU + || ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE) + && extended_count (operands[2], DImode, 1) > 0))" + [(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5))) + (set (match_dup 0) (match_dup 6))] + " +{ + operands[5] = GEN_INT (~ INTVAL (operands[3])); + operands[6] = gen_rtx (((GET_CODE (operands[1]) == GTU + || GET_CODE (operands[1]) == GT) + ? NE : EQ), + DImode, operands[4], const0_rtx); +}") ;; Here are the CALL and unconditional branch insns. (define_expand "call" - [(parallel [(call (mem:DI (match_dup 2)) + [(parallel [(call (mem:DI (match_operand 0 "" "")) (match_operand 1 "" "")) - (use (match_operand:DI 0 "" "")) + (clobber (reg:DI 27)) (clobber (reg:DI 26))])] "" " { if (GET_CODE (operands[0]) != MEM) abort (); - operands[0] = XEXP (operands[0], 0); - operands[2] = gen_rtx (REG, DImode, 27); - emit_move_insn (operands[2], operands[0]); + operands[0] = XEXP (operands[0], 0); - if (GET_CODE (operands[0]) != SYMBOL_REF) - operands[0] = const0_rtx; + if (GET_CODE (operands[0]) != SYMBOL_REF + && ! (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 27)) + { + rtx tem = gen_rtx (REG, DImode, 27); + emit_move_insn (tem, operands[0]); + operands[0] = tem; + } }") (define_expand "call_value" [(parallel [(set (match_operand 0 "" "") - (call (mem:DI (match_dup 3)) + (call (mem:DI (match_operand 1 "" "")) (match_operand 2 "" ""))) - (use (match_operand:DI 1 "" "")) + (clobber (reg:DI 27)) (clobber (reg:DI 26))])] "" " @@ -2297,50 +2439,39 @@ operands[1] = XEXP (operands[1], 0); - operands[3] = gen_rtx (REG, DImode, 27); - emit_move_insn (operands[3], operands[1]); - - if (GET_CODE (operands[1]) != SYMBOL_REF) - operands[1] = const0_rtx; + 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 (reg:DI 27)) - (match_operand 0 "" "")) - (use (match_operand:DI 1 "" "")) + [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i")) + (match_operand 1 "" "")) + (clobber (reg:DI 27)) (clobber (reg:DI 26))] "" - "jsr $26,($27),%1\;ldgp $29,0($26)" - [(set_attr "type" "jsr")]) - -(define_insn "" - [(set (match_operand 0 "register_operand" "=rf") - (call (mem:DI (reg:DI 27)) - (match_operand 1 "" ""))) - (use (match_operand:DI 2 "" "")) - (clobber (reg:DI 26))] - "" - "jsr $26,($27),%2\;ldgp $29,0($26)" - [(set_attr "type" "jsr")]) - -(define_insn "" - [(call (mem:DI (match_operand 1 "current_file_function_operand" "i")) - (match_operand 0 "" "")) - (use (match_dup 1)) - (clobber (reg:DI 26))] - "" - "bsr $26,%1..ng" - [(set_attr "type" "ibr")]) + "@ + jsr $26,($27),0\;ldgp $29,0($26) + bsr $26,%0..ng + jsr $26,%0\;ldgp $29,0($26)" + [(set_attr "type" "jsr,jsr,ibr")]) (define_insn "" - [(set (match_operand 0 "register_operand" "=rf") - (call (mem:DI (match_operand 1 "current_file_function_operand" "i")) + [(set (match_operand 0 "register_operand" "=rf,rf,rf") + (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i")) (match_operand 2 "" ""))) - (use (match_dup 1)) + (clobber (reg:DI 27)) (clobber (reg:DI 26))] "" - "bsr $26,%1..ng" - [(set_attr "type" "ibr")]) + "@ + 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")]) ;; Call subroutine returning any type. @@ -2407,8 +2538,9 @@ (define_expand "tablejump" [(set (match_dup 3) (sign_extend:DI (match_operand:SI 0 "register_operand" ""))) - (parallel [(set (pc) (plus:DI (match_dup 3) (reg:DI 29))) - (use (label_ref (match_operand 1 "" ""))) + (parallel [(set (pc) + (plus:DI (match_dup 3) + (label_ref:DI (match_operand 1 "" "")))) (clobber (match_scratch:DI 2 "=r"))])] "" " @@ -2417,19 +2549,20 @@ (define_insn "" [(set (pc) (plus:DI (match_operand:DI 0 "register_operand" "r") - (reg:DI 29))) - (use (label_ref (match_operand 1 "" ""))) + (label_ref:DI (match_operand 1 "" "")))) (clobber (match_scratch:DI 2 "=r"))] - "" + "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_VEC) + && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC) { rtx jump_table = PATTERN (jump_table_insn); - int n_labels = XVECLEN (jump_table, 0); + int n_labels = XVECLEN (jump_table, 1); int best_count = -1; int i, j; @@ -2438,12 +2571,12 @@ int count = 1; for (j = i + 1; j < n_labels; j++) - if (XEXP (XVECEXP (jump_table, 0, i), 0) - == XEXP (XVECEXP (jump_table, 0, j), 0)) + 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, 0, i); + best_count = count, best_label = XVECEXP (jump_table, 1, i); } } @@ -2470,11 +2603,11 @@ (define_insn "" [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m") - (match_operand:SF 1 "input_operand" "r,m,rG,f,G,m,fG"))] + (match_operand:SF 1 "input_operand" "rG,m,rG,f,G,m,fG"))] "register_operand (operands[0], SFmode) || reg_or_fp0_operand (operands[1], SFmode)" "@ - bis %1,%1,%0 + bis %r1,%r1,%0 ldl %0,%1 stl %r1,%0 cpys %1,%1,%0 @@ -2485,11 +2618,11 @@ (define_insn "" [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m") - (match_operand:DF 1 "input_operand" "r,m,rG,f,G,m,fG"))] + (match_operand:DF 1 "input_operand" "rG,m,rG,f,G,m,fG"))] "register_operand (operands[0], DFmode) || reg_or_fp0_operand (operands[1], DFmode)" "@ - bis %1,%1,%0 + bis %r1,%r1,%0 ldq %0,%1 stq %r1,%0 cpys %1,%1,%0 @@ -2614,8 +2747,8 @@ }") (define_insn "" - [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,r,r,m,f,f,f,m") - (match_operand:DI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,m,fG"))] + [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,r,r,m,f,f,f,Q") + (match_operand:DI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,Q,fG"))] "register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode)" "@ @@ -2749,10 +2882,12 @@ (const_int -7))) (set (match_operand:DI 3 "register_operand" "") (mem:DI (match_dup 2))) + (set (match_operand:DI 4 "register_operand" "") + (and:DI (match_dup 1) (const_int -2))) (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0) (zero_extract:DI (match_dup 3) (const_int 16) - (ashift:DI (match_dup 1) (const_int 3))))] + (ashift:DI (match_dup 4) (const_int 3))))] "" "") @@ -2781,7 +2916,7 @@ ;; For the unaligned byte case, we use code similar to that in the ;; Architecture book, but reordered to lower the number of registers ;; required. Operand 0 is the address. Operand 1 is the data to store. -;; Operands 2, 3, and 4 are DImode temporaries, where the last two may +;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may ;; be the same temporary, if desired. If the address is in a register, ;; operand 2 can be that register. @@ -2792,8 +2927,8 @@ (set (match_operand:DI 2 "register_operand" "") (match_dup 0)) (set (match_dup 3) - (and:DI (ashift:DI (const_int 255) - (ashift:DI (match_dup 2) (const_int 3))) + (and:DI (not:DI (ashift:DI (const_int 255) + (ashift:DI (match_dup 2) (const_int 3)))) (match_dup 3))) (set (match_operand:DI 4 "register_operand" "") (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "")) @@ -2825,13 +2960,15 @@ (and:DI (match_dup 2) (const_int -7))) (set (match_operand:DI 4 "register_operand" "") (mem:DI (match_dup 3))) + (set (match_operand:DI 10 "register_operand" "") + (and:DI (match_dup 2) (const_int -2))) (set (match_operand:DI 5 "register_operand" "") - (and:DI (ashift:DI (const_int 65535) - (ashift:DI (match_dup 2) (const_int 3))) + (and:DI (not:DI (ashift:DI (const_int 65535) + (ashift:DI (match_dup 10) (const_int 3)))) (match_dup 4))) (set (match_operand:DI 6 "register_operand" "") (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "")) - (ashift:DI (match_dup 2) (const_int 3)))) + (ashift:DI (match_dup 10) (const_int 3)))) (set (match_operand:DI 7 "register_operand" "") (ior:DI (match_dup 5) (match_dup 6))) (set (match_operand:DI 8 "register_operand" "") (match_dup 0)) @@ -2979,8 +3116,10 @@ NULL_RTX)); rtx scratch1 = gen_reg_rtx (DImode); rtx scratch2 = gen_reg_rtx (DImode); + rtx scratch3 = gen_reg_rtx (DImode); + rtx seq = gen_unaligned_loadhi (operands[0], addr, scratch1, - scratch2); + scratch2, scratch3); alpha_set_memflags (seq, operands[1]); emit_insn (seq); @@ -3019,9 +3158,12 @@ rtx temp6 = gen_reg_rtx (DImode); rtx temp7 = gen_reg_rtx (DImode); rtx temp8 = gen_reg_rtx (DImode); + rtx temp9 = gen_reg_rtx (DImode); + rtx seq = gen_unaligned_storehi (get_unaligned_address (operands[0]), operands[1], temp1, temp2,temp3, - temp4, temp5, temp6,temp7, temp8); + temp4, temp5, temp6,temp7, + temp8, temp9); alpha_set_memflags (seq, operands[0]); emit_insn (seq); @@ -3038,12 +3180,18 @@ (define_expand "reload_inqi" [(parallel [(match_operand:QI 0 "register_operand" "=r") (match_operand:QI 1 "unaligned_memory_operand" "m") - (match_operand:DI 2 "register_operand" "=&r")])] + (match_operand:TI 2 "register_operand" "=&r")])] "" " { extern rtx get_unaligned_address (); rtx addr = get_unaligned_address (operands[1]); - rtx seq = gen_unaligned_loadqi (operands[0], addr, operands[2], + /* 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 + it TImode). Pick the other one to use as our scratch. */ + rtx scratch = gen_rtx (REG, DImode, + REGNO (operands[0]) == REGNO (operands[2]) + ? REGNO (operands[2]) + 1 : REGNO (operands[2])); + rtx seq = gen_unaligned_loadqi (operands[0], addr, scratch, gen_rtx (REG, DImode, REGNO (operands[0]))); alpha_set_memflags (seq, operands[1]); @@ -3069,7 +3217,7 @@ addr = scratch2; } - seq = gen_unaligned_loadhi (operands[0], addr, scratch1, scratch1); + seq = gen_unaligned_loadhi (operands[0], addr, scratch1, scratch1, scratch2); alpha_set_memflags (seq, operands[1]); emit_insn (seq); DONE; @@ -3099,13 +3247,14 @@ rtx addr = get_unaligned_address (operands[0]); rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2])); rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1); + rtx scratch3 = scratch1; rtx seq; if (GET_CODE (addr) == REG) scratch1 = addr; seq = gen_unaligned_storeqi (addr, operands[1], scratch1, - scratch2, scratch2); + scratch2, scratch3); alpha_set_memflags (seq, operands[0]); emit_insn (seq); } @@ -3143,7 +3292,7 @@ seq = gen_unaligned_storehi (addr, operands[1], scratch_a, scratch2, scratch2, scratch2, scratch1, scratch2, scratch_a, - scratch1); + scratch1, scratch_a); alpha_set_memflags (seq, operands[0]); emit_insn (seq); }